有没有办法检测用户何时更改了设备上的时钟时间?

时间:2013-03-21 10:31:00

标签: android time

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

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

5 个答案:

答案 0 :(得分:49)

是的,有。更改设备时间时会广播ACTION_TIME_CHANGED Intent,并且您可以使用一种方法,该方法将在检测到此Intent时触发。

此意图自API级别1开始在Android中使用,因此它应该可以在您可能需要兼容的任何平台上运行。

您需要使用BroadcastReceiver处理广播:

public class TimeChangedReceiver extends BroadcastReceiver {

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

}

你还需要在你的Manifest中添加这样的东西:

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

这将让Android知道在检测到此类意图时触发您的接收器。

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

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

您可以使用ConnectivityManager来跟踪手机是否有连接,您可以根据此更改行为(即只要有网络连接,时间是自动/网络时间,忽略时间变化或其他东西)但我找不到任何关于丢失/重新获得网络连接的意图,所以你可能不得不使用轮询方法。

答案 1 :(得分:20)

对于matt5784的回答有点注意:我发现在Android 4.1.2上没有意图动作,不知道这是针对所有Android版本还是仅仅是我的版本。而不是

     "android.intent.action.ACTION_TIME_CHANGED"

使用

     "android.intent.action.TIME_SET"

答案 2 :(得分:14)

如果用户调整了时钟,系统时间(System.currentTimeMillis())会发生变化,但自启动以来经过的时间(SystemClock.elapsedRealtime())有望不会。通过跟踪这两者之间的差异,可以检测用户对系统时钟的主要变化。

重要的是不要跟踪网络更新系统时钟可能导致的微小变化。我会假设,就我的目的而言,任何大约半小时的变化都无关紧要;系统时间不应在Locale国家/地区发生变化,但也可能值得消除。

经过实时显然会在启动时重置,因此我应该在接收BroadcastReceiver时添加android.intent.action.BOOT_COMPLETED来重置差异。

答案 3 :(得分:3)

我们可以同时使用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();
    }
}

答案 4 :(得分:1)

如果你不介意你的应用程序扔掉作弊以防用户的时钟会因* DT / * ST转换而得到更新,偶尔会有时间同步NTP源可以倒回你的时钟,你自己的进程停止,你可以对系统时间进行“后续”检查,这样如果时间“回”,你就会认为这是“作弊”。否则,您必须依赖服务器,这将是您“有效”时间的来源。即使这样,你的服务器的时间也可能偶尔倒退。