45

有没有办法检测 Android 系统时钟何时被用户在 Android 中重置?

我正在设计一个应用程序,它使用系统时间来确定用户何时在某个时间到达某个地点,并且我不想在那时依赖网络可用性。显然,因此最好知道用户何时更改了系统时钟,这样他们就不能“作弊”。

4

5 回答 5

63

就在这里。ACTION_TIME_CHANGEDIntent在设备时间改变时被广播,你可以有一个方法在检测到这个 Intent 时触发。

这个意图从 API 级别 1 开始就存在于 Android 中,因此它应该适用于您可能需要兼容的任何平台。

您需要使用以下命令处理广播BroadcastReceiver

public class TimeChangedReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //Do whatever you need to
    }

}

您还需要在清单中添加类似的内容:

<receiver android:name=".TimeChangedReceiver">
  <intent-filter>
    <action android:name="android.intent.action.TIME_SET" />
  </intent-filter>
</receiver>

当检测到这种类型的意图时,这将使 Android 知道触发您的接收器。

似乎这并不关心谁编辑时间,但也不会在您与网络同步时触发自动调整。但是,如果您丢失网络并重新获得它,这可能会触发,因为您的时间会略有不同(假设您使用的是自动网络时间)。

然而,虽然手机上的时钟不是特别准确(因为它们通常依赖于与接收到的时间信号同步),但根据我的经验,它们绝对不应该超过大约 30 秒或每小时一分钟,在绝对最大值,所以如果时间变化很小,您也许可以假设它是自动的。添加闰秒时,也可能会产生时间更改消息,尽管这些显然很小且不常见。

您可以使用ConnectivityManager来跟踪手机是否有连接,并且您可以基于此更改行为(即只要存在网络连接,并且时间是自动/网络时间,忽略时间变化或其他东西)但是我找不到任何有关丢失/恢复网络连接的意图,因此您可能必须使用轮询方法。

于 2013-06-18T17:40:31.467 回答
22

System.currentTimeMillis()如果用户调整时钟,SystemClock.elapsedRealtime()系统时间(通过跟踪这两者之间的差异,可以检测到用户对系统时钟的重大更改。

重要的是不要跟踪可能由网络更新系统时钟引起的小变化。我将假设出于我的目的,大约半小时内的任何更改都无关紧要。系统时间不应该随着Locale国家/地区的变化而变化,但这也可能值得消除。

经过的实时显然会在启动时重置,所以我应该包括一个BroadcastReceiver在接收时重置差异android.intent.action.BOOT_COMPLETED

于 2013-03-21T11:06:00.423 回答
20

对 matt5784 的回答稍加注意:我发现在 Android 4.1.2 上,意图操作不可用,不知道这是否适用于所有 android 版本或仅适用于我的版本。代替

     "android.intent.action.ACTION_TIME_CHANGED"

利用

     "android.intent.action.TIME_SET"
于 2013-07-15T09:31:42.777 回答
7

我们可以同时使用TIME_SETTIMEZONE_CHANGED

<application
    ...>

    <receiver android:name=".TimeChangedReceiver">
        <intent-filter>
            <action android:name="android.intent.action.TIME_SET"/>
            <action android:name="android.intent.action.TIMEZONE_CHANGED"/>
        </intent-filter>
    </receiver>
</application>

TimeChangedReceiver.java

public class TimeChangedReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "time change " + intent.getAction(), Toast.LENGTH_SHORT).show();
    }
}
于 2017-10-24T04:17:47.070 回答
1

如果您不介意您的应用程序在用户的时钟由于 *DT/*ST 偏移而更新的情况下进行作弊,偶尔与可以倒带时钟的 NTP 源同步时间,您自己的进程停止,您可以实现“对系统时间进行相应的“检查”,这样如果时间“倒退”,您就会认为这是“作弊”。否则,您必须依赖服务器,这将是您“有效”时间的来源。即便如此,您的服务器时间也偶尔会倒退。

于 2013-03-21T10:35:44.043 回答