يستخدم إطار عمل Android مصادر زمنية مختلفة لمزامنة الوقت. تركّز هذه الصفحة على بروتوكول Network Time Protocol (NTP) ومصدرَي الوقت التلقائيَين Network Identity and Time Zone (NITZ). وحسب الإعدادات التلقائية في Android 12 أو الإصدارات الأحدث، يعطي إطار العمل الأولوية لبروتوكول NTP باعتباره مصدرًا للوقت على NITZ لأن NTP أكثر دقة وموثوقية من NITZ. في الحالات التي لا يتوفّر فيها بروتوكول NTP، يعود إطار العمل إلى استخدام بروتوكول NITZ. ويُعدّ ذلك عكسًا للأولوية التلقائية عن الإصدارات السابقة من المنصة. في الإصدار 11 من Android والإصدارات الأقدم، يمنح إطار العمل الأولوية لبروتوكول 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 صالحة في جهاز DUT
- إيقاف بيانات الجوّال وشبكة 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}