Фреймворк Android использует различные источники времени для синхронизации времени. На этой странице основное внимание уделяется автоматическим источникам времени Network Time Protocol (NTP) и Network Identity and Time Zone (NITZ). По умолчанию в Android 12 и выше фреймворк отдает приоритет NTP как источнику времени над NITZ, поскольку NTP более точен и надежен, чем NITZ. В ситуациях, когда NTP недоступен, фреймворк возвращается к NITZ. Это обратный приоритет по умолчанию из более ранних версий платформы. По умолчанию в Android 11 и ниже фреймворк отдает приоритет NITZ над NTP.
Более подробную информацию об этом изменении можно найти в следующих исправлениях AOSP: 1563678 , 1513323 .
Настроить приоритет источника времени
Чтобы настроить, какой источник времени будет иметь приоритет по умолчанию для определенной версии Android, настройте ключ config_autoTimeSourcesPriority
в frameworks/base/core/res/res/values/config.xml
во время сборки. Предложения по времени из источника времени, который находится выше в списке, имеют приоритет над источниками, которые находятся ниже в списке.
Источники времени Android, которые можно настроить, находятся в TimeDetectorStrategy.java
. Следующие источники настроены для использования по умолчанию:
- Телефония (NITZ)
- Сеть (НТП)
Тестирование
Чтобы убедиться, что устройство использует NITZ, когда NTP недоступен (когда отключены мобильные данные и Wi-Fi), выполните следующие действия:
- Убедитесь, что в проверяемом устройстве установлена рабочая SIM-карта.
- Отключите мобильные данные и Wi-Fi
- Переведите устройство в режим полета, чтобы убедиться, что сотовая связь выключена.
- Отключить автоматическое определение времени
- Установите часы вручную на неправильное значение времени в будущем
- Перезагрузите устройство.
- Включить автоматическое определение времени
- Выведите устройство из режима полета.
Эти шаги запускают изменение системных часов, как только получен сигнал NITZ. Чтобы проверить, как установлено время устройства, выполните следующую команду:
adb shell dumpsys time_detector
Чтобы убедиться, что системные часы используют NITZ, проверьте следующее в выводе команды:
-
mEnvironment.isAutoTimeDetectionEnabled()
имеетtrue
. -
mEnvironment.autoOriginPriorities()
содержит список источников времени, при этом источники, расположенные выше в списке, имеют приоритет над источниками, расположенными ниже в списке. - Раздел
Time change log
показывает, что системные часы установлены с использованием подсказки телефонии. - Раздел
Telephony suggestion history
содержит предложения по времени. - Раздел
Network suggestion history
пуст.
Предложения времени в разделах Telephony suggestion history
и Network suggestion history
считаются источником истины для времени. Если устройство подключено к Интернету и имеет SIM-карту, предложения генерируются с использованием как NTP (сеть), так и NITZ (телефония). В этом тестовом случае только раздел Telephony suggestion history
содержит предложения, поскольку NTP отключен.
Раздел Time change log
записывает изменения, внесенные в системные часы устройства, и использованное предложение. Системные часы устанавливаются на основе порядка источников времени в списке приоритетов в ключе config_autoTimeSourcesPriority
. Однако предложения из источника с более высоким приоритетом могут быть проигнорированы, если предложение слишком старое или недействительное. Кроме того, если действительное предложение с самым высоким приоритетом совпадает с текущим временем системных часов устройства с точностью до нескольких секунд, время не будет изменено. В этом тестовом случае, пока предложения не устарели, системные часы устанавливаются с использованием одного из предложений из Telephony suggestion history
.
Ниже приведен пример выходных данных, в которых устройство переходит на использование NITZ, когда NTP недоступен.
TimeDetectorStrategy:
mLastAutoSystemClockTimeSet=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}
mEnvironment.isAutoTimeDetectionEnabled()=true
mEnvironment.elapsedRealtimeMillis()=73059
mEnvironment.systemClockMillis()=1614186767818
mEnvironment.systemClockUpdateThresholdMillis()=2000
mEnvironment.autoTimeLowerBound()=2021-02-24T15:44:15Z(1614181455000)
mEnvironment.autoOriginPriorities()=[network,telephony]
Time change log:
66261 / 2021-02-24T17:12:41.020Z - Set system clock using time=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000} cause=Found good telephony suggestion., bestTelephonySuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}, detectionReason=New telephony time suggested. timeSuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]} elapsedRealtimeMillis=66259 newSystemClockMillis=1614186761019
Telephony suggestion history:
key idx: 0=0
val idx: 0=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
Historic values=[
0@PT1M6.258S: TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
]
Network suggestion history:
{Empty}
Gnss suggestion history:
{Empty}
External suggestion history:
{Empty}
Для сравнения с результатами в тестовом сценарии ниже приведен пример типичного результата, когда устройство получает предложения по времени от источников времени NTP и NITZ.
TimeDetectorStrategy:
mLastAutoSystemClockTimeSet=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}
mEnvironment.isAutoTimeDetectionEnabled()=true
mEnvironment.elapsedRealtimeMillis()=302926
mEnvironment.systemClockMillis()=1614186997685
mEnvironment.systemClockUpdateThresholdMillis()=2000
mEnvironment.autoTimeLowerBound()=2021-02-24T15:44:15Z(1614181455000)
mEnvironment.autoOriginPriorities()=[network,telephony]
Time change log:
66261 / 2021-02-24T17:12:41.020Z - Set system clock using time=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000} cause=Found good telephony suggestion., bestTelephonySuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}, detectionReason=New telephony time suggested. timeSuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]} elapsedRealtimeMillis=66259 newSystemClockMillis=1614186761019
Telephony suggestion history:
key idx: 0=0
val idx: 0=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
Historic values=[
0@PT1M6.258S: TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
]
Network suggestion history:
0@PT4M4.04S: NetworkTimeSuggestion{mUtcTime=TimestampedValue{mReferenceTimeMillis=244038, mValue=1614186939242}, mDebugInfo=[Origin: NetworkTimeUpdateService. event=3]}
Gnss suggestion history:
{Empty}
External suggestion history:
{Empty}