เฟรมเวิร์ก 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) ให้ทำดังนี้
- ตรวจสอบว่ามีซิมที่ใช้งานได้ใน 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}