本頁介紹時間和時區檢測在 Android 上的工作原理。這包括 Android 如何自動檢測時間和時區、設備製造商的配置選項以及測試信息。
時間和時區概覽
為了確定在狀態欄等位置顯示的用戶本地時間,Android 會跟踪兩個相關但獨立的狀態:
- 當前的 Unix 紀元時間
- 當前時區
當前 Unix 紀元時間和當前時區是設備範圍的狀態,這意味著它們由設備的所有用戶共享。
當前的 Unix 紀元時間不是固定值。它會自動更新以反映時間的流逝。除了正常的時間流逝外,如果發現設備當前的 Unix 紀元時間不正確,例如在設備斷電後,也會調整設備當前的 Unix 紀元時間。
當前時區決定了將當前 Unix 紀元時間轉換為本地時間所要進行的調整。例如,在洛杉磯的夏季,設備從當前 Unix 紀元時間減去 7 小時,而在冬天則減去 8 小時。
為了支持這些本地時間計算,所有 Android 設備都有一個包含所有全球時區規則的數據庫。有關時區規則的更多信息,請參閱時區規則。
當用戶前往使用不同時區的新位置時,不需要調整當前的 Unix 紀元時間,但用戶通常希望看到本地時間而不是他們之前位置的時間。更改當前時區可確保將正確的偏移量應用於當前 Unix 紀元時間,以顯示新位置的正確本地時間。
AOSP允許用戶通過以下機制自主控制是否自動為他們設置時間和時區。
- 自動時間檢測:確保設備具有正確的當前 Unix 紀元時間。
- 自動時區檢測:確保設備具有正確的當前時區。
自動時間檢測
本節概述了管理自動時間檢測、用戶控件、配置選項和測試詳細信息的time_detector
服務。
time_detector 服務
運行 Android 10 或更高版本的設備上存在的time_detector
服務管理自動時間檢測。當啟用自動時間檢測時,它會根據需要調整設備的當前 Unix 紀元時間。
time_detector
服務始終處於兩種狀態之一: uncertain或certain 。服務的確定或不確定狀態由它從各種來源接收的時間建議決定。
當time_detector
服務確定時,意味著它已經收到帶有 Unix 紀元時間信息的建議,如果時間建議與當前的 Unix 紀元時間不同,它會覆蓋當前的 Unix 紀元時間。
當time_detector
不確定時,它不會覆蓋當前時間。不確定狀態通常意味著time_detector
服務沒有收到時間建議。如果time_detector
服務收到的建議被認為太舊而無法使用,它也會變得不確定。考慮建議的年齡是因為使用舊的 Unix 紀元時間建議的調整依賴於設備上經過的實時時鐘,這被認為在很長一段時間內是不准確的。
要自動建立當前的 Unix 紀元時間,設備可以使用各種來源。這些在本文檔中稱為起源。 time_detector
服務根據其來源將建議序列視為不同的。
time_detector
服務是有狀態的,這意味著它會記錄每個來源提出的最新建議。如果源有可用的最新 Unix 紀元時間信息,則會向time_detector
提出新建議。 time_detector
服務重新評估新的和現有的建議,並在收到建議時更新設備狀態。
儘管 UTC 時間在國際上得到認可,但出於多種原因,對於 Android 設備來說,建立當前的 Unix 紀元時間並不總是那麼簡單:
- Unix 紀元時間是一種與 UTC 時間略有不同的計時系統。兩者之間的轉換需要了解閏秒何時發生以及來源如何處理它們。
- 起源可能僅在特定時間或特定情況下可用。例如,如果源需要網絡連接,則它可能僅在設備連接到 Internet 時可用。
- 來源可能不准確或不精確,或者有錯誤。例如,如果電話信號塔沒有正確跟踪“通用時間”,電話來源可能會提供不准確的時間建議。
- 獲取 Unix 紀元時間時可能會引入錯誤。例如,網絡延遲、緩衝或進程調度可能導致 Unix 紀元時間不准確。
- 用於調整建議的參考時鐘自收到建議以來經過的時間可能不准確。
AOSP 中默認配置了兩個主要的時間檢測來源:
- 電話:使用網絡身份和時區 (NITZ) 電話信號。
- 網絡:使用網絡時間協議 (NTP) 時間服務器。
電話和網絡起源都需要連接到外部網絡,而外部網絡並不總是可用。
從 Android 12 開始,Android 還支持以下來源,默認情況下未配置使用:
時間設置
用戶可以在 AOSP 設置應用程序的系統 > 日期和時間中啟用自動時間檢測。
圖 1.設置中的自動時間檢測。
下表描述了 AOSP 設置應用中用於時間檢測的用戶控件。
*在 Android 11 及更低版本上,此設置標記為使用網絡提供的時間 | |||
AOSP 設置位置 | AOSP 設置名稱 | 範圍 | 行為 |
---|---|---|---|
系統 > 日期和時間 | 自動設置時間* | 全部用戶 | 一個開關。 打開時,設備負責檢測當前的 Unix 紀元時間。關閉時,用戶可以通過控件手動設置設備的時間。 |
當用戶手動輸入時間時,他們輸入的是本地時間,而不是 Unix 紀元時間。當前Unix紀元時間是通過使用當前時區推導出一個Unix紀元時間來計算的。
配置
設備製造商可以通過多種方式配置time_detector
服務,例如使用哪個來源以及如何對來自它們的信號進行優先級排序。
原產地優先
從 Android 12 開始,設備製造商可以更改core/res/res/values/config.xml
配置文件以指定要包含在自動時間檢測中的時間來源,以及time_detector
考慮這些來源的優先級。
對於運行 Android 11 或更低版本的設備,來源優先級被硬編碼為["telephony", "network"]
,這意味著電話建議優先於網絡建議。
默認的 AOSP 配置如下:
<!-- Specifies priority of automatic time sources. Suggestions from higher entries in the list
take precedence over lower ones.
See com.android.server.timedetector.TimeDetectorStrategy for available sources. -->
<string-array name="config_autoTimeSourcesPriority">
<item>network</item>
<item>telephony</item>
</string-array>
在 Android 12 中,網絡和電話建議被配置為默認使用的來源。網絡時間建議優先於電話時間建議。設備製造商可以更改源的順序以恢復到 Android 11 或更低版本中的行為,其中電話具有更高的優先級。
默認情況下,如果最高優先級的有效建議在幾秒內與設備的當前系統時鐘時間匹配,則設備時間不會更改。這是為了避免為偵聽ACTION_TIME_CHANGED
意圖的已安裝應用程序創建工作。
允許的原始值是:
下限時間
Android 12 引入了一個較低的時間限制,用於驗證time_detector
服務收到的時間建議。下限時間值是根據構建時間戳設置的。這是基於有效時間不能在構建設備的系統映像之前的原則。如果時間建議早於下限時間, time_detector
服務會丟棄該建議,因為如果構建時間戳正確則該建議無效。
對於運行 Android 11 或更低版本的設備, time_detector
服務不會驗證傳入的 Unix 紀元時間建議。
Android 不強制執行時間上限。
時間調試和測試
本節提供有關如何調試和測試time_detector
服務和所有來源共享的其他組件的行為的信息。
與 time_detector 服務交互
要查看time_detector
服務的配置和time_detector
服務的狀態,請使用:
adb shell cmd time_detector dump
要查看用於調試和測試時區檢測的其他命令,請使用:
adb shell cmd time_detector help
幫助輸出還描述了 device_config 服務屬性,可用於影響time_detector
的行為以進行測試或生產。有關詳細信息,請參閱使用 device_config 服務配置設備。
要驗證自動時間檢測,測試人員必須知道time_detector
服務使用的是哪個來源。以下是adb shell cmd time_zone_detector dump
命令的輸出示例,其中有關當前來源和服務狀態的信息以粗體顯示:
$ adb shell cmd time_detector dump
TimeDetectorStrategy:
mLastAutoSystemClockTimeSet=null
mEnvironment.isAutoTimeDetectionEnabled()=true
mEnvironment.elapsedRealtimeMillis()=23717241
mEnvironment.systemClockMillis()=1626707861336
mEnvironment.systemClockUpdateThresholdMillis()=2000
mEnvironment.autoTimeLowerBound()=2021-07-19T07:48:05Z(1626680885000)
mEnvironment.autoOriginPriorities()=[network,telephony]
Time change log:
...
Telephony suggestion history:
...
Network suggestion history:
...
Gnss suggestion history:
...
External suggestion history:
...
該信息可以解釋如下:
鑰匙 | 價值 |
---|---|
mEnvironment.isAutoTimeDetectionEnabled() | 是否啟用自動時間檢測。 |
mEnvironment.autoTimeLowerBound() | 當前下限用於驗證時間建議。 |
mEnvironment.autoOriginPriorities() | 使用的起源和優先順序。 |
時間更改日誌指示time_detector
服務更改設備當前 Unix 紀元時間的情況。
建議歷史信息表示每個來源已經提出了什麼建議。
自動時區檢測
本節概述了time_zone_detector
服務,該服務管理自動時區檢測、設置中的用戶控件、電話和位置時區檢測以及測試詳細信息。
time_zone_detector 服務
運行 Android 11 或更高版本的設備上存在的time_zone_detector
服務管理自動時區檢測。當啟用自動時區檢測時,它會根據需要調整設備的當前時區。
啟用自動時區檢測時, time_zone_detector
可以處於兩種狀態之一: uncertain和certain 。
當time_zone_detector
服務處於某種狀態時,這意味著time_zone_detector
服務收到了強時區信息,這會導致它覆蓋當前時區。當不確定時,這意味著它沒有收到任何信息或只收到低置信度的信息,這意味著它不會覆蓋當前時區。
time_zone_detector
服務的某些狀態可以包括time_zone_detector
沒有可供使用的時區信息,或者它有多個時區可供選擇的狀態。這些狀態如下:
- 當設備在沒有時區的地方,例如在國際水域或有爭議的區域時,進入零時區的特定狀態。此狀態類似於不確定狀態,但表示
time_zone_detector
不需要採取進一步操作來嘗試確定時區。 - 在存在歧義或邊界條件的情況下進入具有多個時區的特定狀態。在這種狀態下,如果當前時區是
time_zone_detector
確定的時區之一,則保持當前時區不變。否則,將使用可用時區之一。如果用戶之前手動選擇了他們的時區,或者當設備接近邊界時,這會給time_zone_detector
一個粘性元素。
time_zone_detector
服務的確定或不確定狀態由origin發送的時區建議決定。
通常,建議有兩種類型,它們與time_zone_detector
的可能狀態非常匹配:確定的和不確定的。以下是建議類型的示例:
type = "不確定", zoneIds = []
- 原點不知道時區是什麼。
type = "certain", zoneIds = ["歐洲/倫敦"]
- 來源確定該區域是“歐洲/倫敦”。
type = "確定", zoneIds = []
- 來源是確定的,但沒有與當前位置關聯的區域 ID。
type = "certain", zoneIds = ["America/Denver", "America/Phoenix"]
- 來源確定答案是兩個區域之一,但不能在“美國/丹佛”和“美國/鳳凰城”之間進行選擇。
time_zone_detector
服務根據其來源將建議序列視為不同的。根據來源,建議還可能包含指示來源確定性的元數據。
time_zone_detector
服務是有狀態的,這意味著它會記錄每個來源提出的最新建議。如果先前的建議不再正確,則會將新建議發送到time_zone_detector
服務;也就是說,如果一個來源現在有不同的建議,或者它是否失去了檢測時區的能力。 time_zone_detector
服務重新評估新的和現有的建議,並在收到建議時更新設備狀態。
Android 支持兩種時區檢測來源:
- 電話
- 地點
time_zone_detector
服務僅使用單一來源來確定時區。當設備支持位置原點時,當前使用的原點取決於用戶配置的時區設置。噹噹前來源變得不確定時區時, time_zone_detector
不會使用來自不同來源的建議。 time_zone_detector
可以將除當前原點之外的與原點相關的建議保存在內存中,但除非當前原點發生變化,否則不會使用它們。當用戶更改自動時區檢測的設置並且當前原點發生更改時,將使用可用於新原點的最新建議。
在運行 Android 13 及更高版本的設備上, time_zone_detector
服務支持電話回退模式。此模式允許 Android 在位置檢測無法檢測時區或位置檢測比電話檢測需要更長的時間來檢測時區的情況下臨時使用電話檢測建議。
電話回退模式適用於同時支持電話和位置檢測的設備,以及用戶在時區設置中啟用使用位置來設置時區的設備。當設備重新啟動時以及禁用飛行模式時,該模式會自動啟用。當處於電話回退模式時, time_zone_detector
服務使用電話建議,就像位置檢測被禁用一樣,直到位置來源提出特定建議。收到某個建議後,電話回退模式將被禁用,並專門使用位置建議。
有關電話回退模式的配置詳細信息,請參閱時區檢測配置。
時區設置
用戶可以在 AOSP 設置應用中啟用和配置自動時區檢測設置。
圖 2.設置中的自動時區檢測。
下表描述了 AOSP 設置應用中用於時區檢測的用戶控件。
*在 Android 11 及更低版本上,此設置標記為使用網絡提供的時區 | |||
AOSP 設置位置 | AOSP 設置名稱 | 範圍 | 行為 |
---|---|---|---|
系統 > 日期和時間 | 自動設置時區* | 全部用戶 | 一個開關。 打開時,設備負責檢測當前時區。關閉時,為用戶提供手動設置設備時區的控件。 |
系統 > 日期和時間 | 使用位置設置時區 | 當前用戶 | 一個開關。 從 Android 12 開始可用。此切換僅在設備支持位置時區檢測時顯示。 |
地點 | 使用地點 | 當前用戶 | 一個開關。 通常允許或阻止使用設備的位置。如果設備支持位置時區檢測,則該值是相關的。 |
下面概述了根據用戶選擇的設置進行時區檢測的設備行為:
[日期和時間] 自動設置時區:關閉
- 用戶必須手動選擇時區。
[日期和時間] 自動設置時區: ON
【位置】使用位置: OFF
- 電話信號用於檢測時區。 (見下面的註釋。)
【位置】使用位置: ON
[日期和時間] 使用位置設置時區: ON
- 位置用於檢測時區。
[日期和時間] 使用位置設置時區:關閉
- 電話信號用於檢測時區。 (見下面的註釋。)
多用戶設備
由於涉及的一些設置僅限於當前用戶,因此噹噹前用戶在多用戶 Android 設備上發生變化時,設備的時區檢測行為可能會發生變化。
使用位置設置時區切換僅限於當前用戶,不受設備策略限制,這意味著用戶可以隨時更改其值,即使設置時區自動切換關閉或其他時間或時區控件也是如此受設備策略控制器限制。
更改為自動檢測或更改為自動檢測時的行為
當用戶將時區檢測從手動切換到自動時, time_zone_detector
可能已經確定了當前時區。如果是這樣,當用戶啟用自動檢測時,設備的時區可能會同時更改以匹配time_zone_detector
服務的意見。
同樣,當用戶更改設置導致time_zone_detector
服務的當前來源發生更改時, time_zone_detector
可能已經收到新來源的建議,因此設備的時間可能會立即更改以匹配time_zone_detector
服務的意見。
電話時區檢測
電話時區檢測使用電話信號來確定當前時區。有關詳細信息,請參閱電話時區檢測。
位置時區檢測
位置時區檢測可在 Android 12 或更高版本上使用。這是一個可選的自動時區檢測功能,使設備能夠使用它們的位置來確定當前時區。
Android 12 引入的location_time_zone_manager
服務運行在系統服務器中,包含負責向time_zone_detector
服務提交位置來源建議的代碼。有關詳細信息,請參閱位置時區檢測。
功能採用注意事項
本節介紹位置時區檢測功能的各個方面,以幫助設備製造商確定是否在設備上採用該功能。
比較電話和位置檢測
下表比較了使用位置而不是電話信號進行時區檢測的優缺點。
電話檢測 | 位置檢測 | |
---|---|---|
正確性 | 因國家/地區而異。 取決於 MCC、NITZ 的正確性和可用性。 | 取決於功能配置或插件組件。 正確性通常因以下因素而異:
|
可更新性 | 電話檢測依賴於可更新時區數據模塊(com.android.tzdata APEX) 中包含的文件。 | 取決於功能配置或插件組件。 可更新性通常取決於設備是使用服務器還是客戶端時區地圖數據。 注意:時區地圖數據不包含在用於更新 Android 的 TZDB 副本和其他時區信息的時區數據模塊中。 設備製造商還必須考慮時區規則和時區地圖數據之間的版本一致性。 |
用電量 | 無或低功耗 | 取決於用戶位置設置、正在使用的插件,通常還有其他應用程序請求的位置。 |
可用性 | 僅限電話設備。通常需要可用的 SIM 卡。 | 位置檢測取決於可用的位置提供商。 |
用戶隱私
用戶的首選時區通常由他們的地理位置決定。位置是敏感數據。用戶可能會擔心他們的位置信息會作為時區檢測的一部分被共享。與時區檢測無關,設備上運行的所有應用程序都可以讀取設備的當前時區而無需 Android 許可,並且應用程序可以根據此信息推斷出設備位置的不精確概念。
更具體地說,時區檢測可以通過被動或主動方式工作:
- 被動:設備環境中的某些東西告訴設備在該環境中使用的時區。
- 主動:設備必須自己計算出時區,並根據用戶的隱私設置和他們的同意,獲取設備的位置來這樣做。然後它可以與外部服務共享其位置。有關用戶隱私和同意的詳細信息,請參閱下面的討論。
被動檢測,例如電話來源,對用戶沒有額外的隱私影響。
主動檢測,例如位置來源,涉及確定設備的位置,用戶可能不想同意,並且可以通過網絡發送該位置以確定時區 ID。
Android 的時區檢測用戶隱私方法使用戶能夠單獨禁用預期處於活動狀態的來源。此外,AOSP 平台代碼本身並不直接處理位置:位置檢測和將位置映射到時區 ID 留給設備製造商配置的插件組件。
有關用戶隱私功能的更多詳細信息,請參閱位置時區檢測。
配置
設備製造商可以配置time_zone_detector
服務來改變它的行為。本節介紹time_zone_detector
服務的一般行為的配置選項。有關電話和時區檢測源的配置詳細信息,請參閱電話時區檢測和位置時區檢測。
基本 AOSP 配置位於frameworks/base/core/res/res/values/config.xml
。
配置鍵 | AOSP值 | 描述 |
---|---|---|
config_supportTelephonyTimeZoneFallback | true | 當為true 時,`time_zone_detector` 將使用電話回退模式。這存在於 Android 13 及更高版本中。 |
改變設備默認行為
在 AOSP 中,默認情況下啟用自動時區檢測,並將auto_time_zone
設置設置為true
。要默認禁用自動時間檢測,請將frameworks/base/packages/SettingsProvider/res/values/defaults.xml
中定義的def_auto_time_zone
的值設置為false
。
從另一台設備恢復備份時,框架默認更新auto_time_zone
設置的值。如果要確保此設置不會從備份中恢復,請將auto_time_zone
包含在frameworks/base/packages/SettingsProvider/res/values/blocked_settings.xml
中定義的restore_blocked_global_settings
數組中。
時區調試和測試
本節提供有關如何調試和測試time_zone_detector
服務和所有來源共享的其他組件的行為的信息。
使用 device_config 服務配置設備
device_config
服務是 Android 上使用的一種機制,使用通常由專有(非 AOSP)代碼從遠程服務器提取的值來配置可修改的行為。當使用device_config
值進行測試時,尤其是在長時間運行的手動測試期間,設備可能會同步標誌,這將重置標誌並清除為測試設置的值。
在 Android 12 或更高版本中,要暫時阻止標誌同步,請使用:
adb shell cmd device_config set_sync_disabled_for_tests persistent
要在測試後恢復標誌同步,請使用:
adb shell cmd device_config set_sync_disabled_for_tests none
恢復標誌同步後,重啟設備。
有關詳細信息,請使用$ adb shell cmd device_config help
。
與 time_zone_detector 服務交互
要查看time_zone_detector
服務的time_zone_detector
配置和狀態,請使用:
adb shell cmd time_zone_detector dump
要查看用於調試和測試時區檢測的其他命令,請使用:
adb shell cmd time_zone_detector help
幫助輸出還描述了device_config
服務屬性,這些屬性可用於影響time_zone_detector
服務的行為以進行測試或生產。有關詳細信息,請參閱使用 device_config 服務配置設備。
要驗證時區檢測,測試人員必須知道time_zone_detector
使用的是哪個來源。要了解和影響time_zone_detector
的當前原點,請使用以下選項之一:
- 通過設置 UI 進行目視檢查。有關詳細信息,請參閱時區設置。
通過 adb 使用命令行:
- 要轉儲
time_zone_detector
狀態,請使用adb shell cmd time_zone_detector dump
- 要更改設備設置,請使用其他
time_zone_detector
命令。有關詳細信息,請使用adb shell cmd time_zone_detector help
。
- 要轉儲
以下是adb shell cmd time_zone_detector dump
命令的輸出示例,其中有關當前來源和服務狀態的信息以粗體顯示:
$ adb shell cmd time_zone_detector dump
TimeZoneDetectorStrategy:
mEnvironment.getCurrentUserId()=0
mEnvironment.getConfiguration(currentUserId)=ConfigurationInternal{mUserId=0, mUserConfigAllowed=true, mTelephonyDetectionSupported=true, mGeoDetectionSupported=true, mAutoDetectionEnabled=true, mLocationEnabled=true, mGeoDetectionEnabled=true}
[Capabilities=TimeZoneCapabilitiesAndConfig{mCapabilities=TimeZoneDetectorCapabilities{mUserHandle=UserHandle{0}, mConfigureAutoDetectionEnabledCapability=40, mConfigureGeoDetectionEnabledCapability=40, mSuggestManualTimeZoneCapability=30}, mConfiguration=TimeZoneConfiguration{mBundle=Bundle[{geoDetectionEnabled=true, autoDetectionEnabled=true}]}}]
mEnvironment.isDeviceTimeZoneInitialized()=true
mEnvironment.getDeviceTimeZone()=Europe/London
Time zone change log:
Manual suggestion history:
...
Geolocation suggestion history:
...
Telephony suggestion history:
...
該信息可以解釋如下:
鑰匙 | 價值 |
---|---|
mUserConfigAllowed | Device Policy Controller是否阻止用戶控制日期和時間設置。 |
mTelephonyDetectionSupported | 設備是否有電話時區檢測。 |
mGeoDetectionSupported | 設備是否有位置時區檢測。這是基於配置和至少一個 LTZP 存在的有效狀態。 |
mAutoDetectionEnabled | 是否啟用自動時區檢測。 |
mLocationEnabled | 主位置切換。 |
mGeoDetectionEnabled | 原點開關:`false` 表示電話原點,`true` 表示位置原點。 |
建議歷史信息指示通過設置(手動)以及電話和位置來源做出了哪些建議。