9

我有一个接收 TIME_SET 动作 android 的接收器。

但有时我会在不改变时间的情况下采取行动(随机问题)

请帮我解决这个问题

提前致谢。代码

    <receiver
        android:name=".tamperprooftime.TimeChangedReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="android.intent.action.TIME_SET" />
            <action android:name="android.intent.action.TIMEZONE_CHANGED" />
        </intent-filter>
    </receiver>
4

2 回答 2

17

我也有同样的问题。看来,如果您的设备选中了“使用网络提供的时间”,则设备将定期更新时间。似乎即使对于最小的时间更正也更新时间,TIME_SET 广播也会发生......我希望有一些阈值参数可以检查/使用,以便广播这些微小的时间更正,或者有当用户明确更改时间而不是设备进行自我校正时,会出现不同的广播。

于 2014-01-17T14:59:35.697 回答
0

我发现它不可靠,使用ACTION_TIME_CHANGEDand ACTION_TIMEZONE_CHANGED. 有时它会被触发,有时即使我手动更改设备时间也不会触发。当手动更改设备时间时ACTION_TIME_CHANGED,我的设备上会调用两次。

根据您的用例和需求,您可以System.currentTimeMillis()通过每 X 秒检查一次来计算设备时间(仅限)是否已手动更改。但它不会检测时区是否已更改。由于System.currentTimeMillis()可能会更改,但SystemClock.elapsedRealtime()除非设备启动,否则不会更改,因此您可以检测是否System.currentTimeMillis()更改。

在 Kotlin 中,示例实现如下所示:

private val TIME_CHANGE_CONTROL_INTERVAL = 10_000L
private val TIME_CHANGE_THRESHOLD = 1_000L
private var lastUptimeTime = SystemClock.elapsedRealtime()
private var lastEpochTime = System.currentTimeMillis()
private lateinit var timeChangeJob: Job

private fun detectTimeChange() {
    val uptimeDifference = SystemClock.elapsedRealtime() - lastUptimeTime
    val epochDifference = System.currentTimeMillis() - lastEpochTime
    val timeChange = Math.abs(uptimeDifference - epochDifference)

    if (timeChange > TIME_CHANGE_THRESHOLD) {
        // Time has changed more than 1sec
    }

    lastUptimeTime = SystemClock.elapsedRealtime()
    lastEpochTime = System.currentTimeMillis()
}

fun listenToDeviceTimeChanges() {
    if (::timeChangeJob.isInitialized) timeChangeJob.cancel()
    timeChangeJob = Job()

    GlobalScope.launch(timeChangeJob) {
        while (isActive) {
            detectTimeChange()
            delay(TIME_CHANGE_CONTROL_INTERVAL)
        }
    }
}

fun unlistenToDeviceTimeChanges() {
    if (::timeChangeJob.isInitialized) timeChangeJob.cancel()

    lastUptimeTime = SystemClock.elapsedRealtime()
    lastEpochTime = System.currentTimeMillis()
}
于 2019-03-11T12:57:15.247 回答