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