เฟรมเวิร์ก Android ใช้แหล่งที่มาของเวลาต่างๆ ในการซิงค์เวลา หน้านี้มุ่งเน้นที่แหล่งที่มาของเวลาอัตโนมัติจากโปรโตคอลเวลาของเครือข่าย (NTP) และข้อมูลประจำตัวและเขตเวลาของเครือข่าย (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) ให้ทำดังนี้
- ตรวจสอบว่ามีซิมที่ใช้งานได้ใน 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
จะถือว่าเป็นแหล่งข้อมูลที่เป็นความจริงสำหรับเวลา หากอุปกรณ์เชื่อมต่ออินเทอร์เน็ตและมีซิมการ์ด ระบบจะสร้างคำแนะนำโดยใช้ทั้ง NTP (เครือข่าย) และ NITZ (โทรศัพท์) ในตัวอย่างนี้ มีเฉพาะส่วน Telephony suggestion history
เท่านั้นที่มีคําแนะนําเนื่องจาก NTP ถูกปิดอยู่
ส่วน Time change log
จะบันทึกการเปลี่ยนแปลงที่ทำกับนาฬิกาของระบบอุปกรณ์และคำแนะนำที่ใช้ ระบบจะตั้งค่านาฬิกาตามลําดับของแหล่งข้อมูลเวลาในรายการลําดับความสําคัญในคีย์ config_autoTimeSourcesPriority
อย่างไรก็ตาม ระบบอาจละเว้นคําแนะนําจากแหล่งที่มาที่มีลําดับความสําคัญสูงกว่าหากคําแนะนํานั้นเก่าเกินไปหรือไม่ถูกต้อง
นอกจากนี้ หากคำแนะนำที่ถูกต้องซึ่งมีลำดับความสำคัญสูงสุดตรงกับเวลาปัจจุบันของนาฬิการะบบของอุปกรณ์ภายใน 2-3 วินาที ระบบจะไม่เปลี่ยนเวลา
ในตัวอย่างนี้ ตราบใดที่คำแนะนำยังไม่ล้าสมัย ระบบจะตั้งค่านาฬิกาโดยใช้คำแนะนำข้อใดข้อหนึ่งจาก 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}