Фреймворк 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)
- Сеть (NTP)
Тестирование
Чтобы проверить, использует ли устройство 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}