Подтвердить что ты не робот

Есть ли способ определить, когда пользователь изменил время на своем устройстве?

Есть ли способ обнаружить, когда системные часы Android были reset пользователем в Android?

Я разрабатываю приложение, которое использует системное время, чтобы определить, когда пользователь находится в определенном месте в определенное время, и я не хочу полагаться на доступность сети в этот момент. Очевидно, поэтому было бы полезно знать, когда пользователь изменил системные часы, поэтому они не могут "обманывать".

4b9b3361

Ответ 1

Да, есть. ACTION_TIME_CHANGED Intent транслируется при изменении времени устройства, и вы можете иметь метод, который будет срабатывать при обнаружении этого намерения.

Это намерение было в Android с уровня API 1, поэтому оно должно работать на любой платформе, с которой вам может потребоваться совместимость.

Вам нужно будет обработать трансляцию с помощью 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, чтобы отслеживать, имеет ли телефон соединение или нет, и вы можете изменить поведение на основе этого ( т.е. пока существует сетевое подключение, а время - автоматическое/сетевое время, игнорирует изменения времени или что-то в этом роде), но я не могу найти никаких намерений относительно потери/восстановления сетевого подключения, поэтому вам, вероятно, придется использовать метод опроса.

Ответ 2

Небольшое уведомление о ответе matt5784: я узнал, что на Android 4.1.2 действие намерения недоступно, не знаю, действительно ли это для всех версий Android или просто у меня. Вместо

     "android.intent.action.ACTION_TIME_CHANGED"

использовать

     "android.intent.action.TIME_SET"

Ответ 3

Системное время (System.currentTimeMillis()) изменится, если пользователь настроит часы, но прошедшее время с момента загрузки (SystemClock.elapsedRealtime()), надеюсь, не будет. Отслеживая разницу между этими двумя, можно было бы обнаружить значительные изменения в системных часах пользователем.

Было бы важно не отслеживать небольшие изменения, которые могут быть вызваны сетевым обновлением системных часов. Я собираюсь предположить, что для моих целей любое изменение менее чем через полчаса не имеет значения; системное время не должно меняться в стране Locale, но это также может быть оправдано.

Истекшее в реальном времени, очевидно, будет reset при загрузке, поэтому я должен включить BroadcastReceiver в reset дифференциал при приеме android.intent.action.BOOT_COMPLETED.

Ответ 4

Если вы не против, чтобы ваше приложение бросало читы, если пользовательские часы будут обновляться из-за сдвигов * DT/* ST, время от времени синхронизируется с источниками NTP, которые могут перематывать ваши часы, ваш собственный процесс останавливается, вы можете выполнить "последовательную" проверку системного времени, чтобы, если время прошло "назад", вы считаете это "чит". В противном случае вы должны полагаться на сервер, который будет вашим источником "действительного" времени. И даже тогда ваше серверное время тоже может вернуться назад.

Ответ 5

Должны использовать как TIME_SET, так и TIMEZONE_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();
    }
}