使用 NTP 协议获取网络时间
在 build.gradle
文件中添加以下依赖:
implementation 'commons-net:commons-net:3.6'
创建 NTP 时间获取工具类:
import org.apache.commons.net.ntp.NTPUDPClient
import org.apache.commons.net.ntp.TimeInfo
import java.net.InetAddress
import java.util.*
object NTPTimeHelper {
private const val NTP_SERVER = "pool.ntp.org"
private const val TIMEOUT = 30000
fun getNetworkTime(): Date? {
val client = NTPUDPClient()
client.defaultTimeout = TIMEOUT
return try {
client.open()
val info: TimeInfo = client.getTime(InetAddress.getByName(NTP_SERVER))
info.computeDetails()
Date(info.returnTime + info.offset)
} catch (e: Exception) {
null
} finally {
client.close()
}
}
}
通过 HTTP 请求获取时间
添加网络权限到 AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET"/>
使用 Retrofit 获取时间 API 响应:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
创建时间 API 服务接口:
interface TimeApiService {
@GET("/")
suspend fun getTime(): Response<Map<String, String>>
}
获取 HTTP 头部日期信息:
val retrofit = Retrofit.Builder()
.baseUrl("http://worldtimeapi.org/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(TimeApiService::class.java)
val response = service.getTime()
val dateString = response.headers()["Date"]
val date = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US).parse(dateString)
使用 Android 系统 API 获取网络时间
通过系统设置获取自动时间:
fun isAutoTimeEnabled(context: Context): Boolean {
return Settings.Global.getInt(
context.contentResolver,
Settings.Global.AUTO_TIME,
0
) == 1
}
fun getCurrentNetworkTime(): Long {
return System.currentTimeMillis()
}
处理运行时权限
检查并请求网络权限:
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.INTERNET
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.INTERNET),
PERMISSION_REQUEST_CODE
)
}
显示获取到的时间
在 UI 线程更新显示:
CoroutineScope(Dispatchers.IO).launch {
val networkTime = NTPTimeHelper.getNetworkTime()
withContext(Dispatchers.Main) {
textView.text = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
.format(networkTime ?: Date())
}
}
错误处理和重试机制
实现基本的错误处理:
fun getTimeWithRetry(maxRetries: Int = 3): Date? {
var retryCount = 0
while (retryCount < maxRetries) {
try {
return NTPTimeHelper.getNetworkTime()
} catch (e: Exception) {
retryCount++
if (retryCount == maxRetries) {
return null
}
Thread.sleep(1000)
}
}
return null
}