本頁介紹時間和時區偵測在 Android 上的工作原理。這包括 Android 如何自動偵測時間和時區、裝置製造商的配置選項以及測試資訊。
時間和時區概述
為了確定使用者在狀態列等位置顯示的本地時間,Android 會追蹤兩個相關但獨立的狀態:
- 目前 Unix 紀元時間
- 目前時區
目前 Unix 紀元時間和當前時區是設定範圍的狀態,這意味著它們由設備的所有使用者共用。
目前 Unix 紀元時間不是固定值。它會自動更新以反映時間的流逝。除了正常的時間流逝之外,如果發現設備目前的 Unix 紀元時間不正確,例如設備斷電後,設備的當前 Unix 紀元時間也會被調整。
目前時區決定將目前 Unix 紀元時間轉換為本地時間所需進行的調整。例如,在洛杉磯的夏季,設備會從目前 Unix 紀元時間減去 7 小時,在冬季則減去 8 小時。
為了支援這些本地時間計算,所有 Android 裝置都有一個包含所有全球時區規則的資料庫。有關時區規則的更多信息,請參閱時區規則。
當使用者旅行到使用不同時區的新位置時,不需要調整當前的 Unix 紀元時間,但使用者通常希望查看本地時間而不是先前位置的時間。變更目前時區可確保將正確的偏移量套用於目前 Unix 紀元時間,以顯示新位置的正確本地時間。
AOSP 允許使用者透過以下機制獨立控制是否自動為其設定時間和時區。
- 自動時間偵測:確保設備具有正確的目前 Unix 紀元時間。
- 自動時區偵測:確保設備具有正確的目前時區。
自動時間偵測
本節概述了time_detector
服務,該服務管理自動時間檢測、使用者控制項、設定選項和測試詳細資訊。
time_Detector 服務
time_detector
服務存在於執行 Android 10 或更高版本的裝置上,用於管理自動時間偵測。當啟用自動時間偵測時,它會根據需要調整裝置目前的 Unix 紀元時間。
time_detector
服務始終處於兩種狀態之一:不確定或確定。服務的確定或不確定狀態由它從各種來源接收的時間建議來決定。
當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 時間略有不同的計時系統。兩者之間的轉換需要了解閏秒何時發生以及來源如何處理它們。
- 起源可能僅在特定時間或特定情況下可用。例如,如果來源需要網路連接,則它可能僅在裝置連接到網路時才可用。
- 來源可能不準確或不精確,或有錯誤。例如,如果電話訊號塔未正確追蹤“通用時間”,則電話來源可能會提供不準確的時間建議。
- 取得 Unix 紀元時間時可能會引入不準確的情況。例如,網路延遲、緩衝或進程調度可能會導致 Unix 紀元時間不準確。
- 用於調整建議自收到建議以來經過的時間的參考時鐘可能不準確。
AOSP 中預設配置使用兩個主要時間偵測來源:
- 網路:使用網路時間協定 (NTP) 時間伺服器。
- 電話:使用網路身分和時區 (NITZ) 電話訊號。
電話和網路起源都需要連接到外部網絡,而外部網路並不總是可用。
從 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 14 引入了time_detector
服務接收的時間建議的上限。如果裝置支援 32 位元進程,框架會設定時間上限,以防止裝置使用可能觸發 Y2038 問題的時間建議。
Android 12 引入了一個較低的時間限制,用於驗證time_detector
服務收到的時間建議。用於自動建議的下限時間值是根據建置時間戳記設定的。其工作原理是有效時間不能早於設備的系統映像建置。如果時間建議早於時間下限,則time_detector
服務會丟棄該建議,因為如果建置時間戳正確,該建議就無效。
對於運行 Android 11 或更低版本的設備, time_detector
服務不會驗證傳入的 Unix 紀元時間建議。
及時調試和測試
本節提供有關如何調試和測試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 服務
time_zone_detector
服務存在於執行 Android 11 或更高版本的裝置上,用於管理自動時區偵測。當啟用自動時區偵測時,它會根據需要調整裝置的當前時區。
啟用自動時區偵測後, time_zone_detector
可以處於以下兩種狀態之一:不確定且確定。
當time_zone_detector
服務處於某種狀態時,這表示time_zone_detector
服務已接收到強時區訊息,這可能導致它覆蓋當前時區。當不確定時,這意味著它沒有收到任何訊息或僅收到低可信度訊息,這意味著它不會覆蓋當前時區。
time_zone_detector
服務的某些狀態可以包括time_zone_detector
沒有可使用的時區資訊或有多個時區可供選擇的狀態。這些狀態如下:
- 當設備位於沒有時區的某個地方(例如在國際水域或有爭議的區域)時,就會進入零時區的某個狀態。此狀態類似於不確定狀態,但表示
time_zone_detector
不需要採取進一步操作來嘗試確定時區。 - 在存在歧義或邊界條件的情況下,進入具有多個時區的某個狀態。在此狀態下,如果目前時區是
time_zone_detector
確定的時區之一,則目前時區保持原樣。否則,將使用可用時區之一。如果使用者之前手動選擇了時區或當設備接近邊界時,這將為time_zone_detector
提供黏性元素。
time_zone_detector
服務的確定或不確定狀態由演算法發送的時區建議決定。
一般來說,建議有兩種類型,與time_zone_detector
的可能狀態緊密匹配: certain和uncertainty 。以下是建議類型的範例:
類型 =
uncertain
,zoneIds = []
- 該演算法不知道時區是什麼。
type =
certain
,zoneIds = ["Europe/London"]
- 該演算法確定該區域是歐洲/倫敦。
類型 =
certain
,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 在位置檢測無法檢測時區或位置檢測比電話檢測需要更長的時間來檢測時區的情況下臨時使用電話檢測建議。
電話回退模式適用於同時支援電話和位置偵測,且使用者已在時區設定中啟用使用位置設定時區 的裝置。當裝置重新啟動以及停用飛航模式時,此模式會自動啟用。
在 Android 14 及更高版本中,可以透過LTZP 狀態報告 API觸發電話回退,也就是說,如果 LTZP 報告不確定且其偵測位置或時區的能力因環境而降低,則會觸發電話回退模式。
當處於電話回退模式時, time_zone_detector
服務會使用電話建議,就像停用位置偵測一樣,直到位置演算法提出特定建議。收到特定建議後,電話回退模式將被停用,並且僅使用位置建議。
有關電話回退模式的配置詳細信息,請參閱時區檢測配置。
時區設定
使用者可以在 AOSP 設定應用程式中啟用和設定自動時區偵測的設定。
圖 2. “設定”中的自動時區偵測。
下表描述了 AOSP 設定應用程式中用於時區偵測的使用者控制項。
*在 Android 11 及更低版本上,此設定標記為使用網路提供的時區 | |||
AOSP 設定位置 | AOSP 設定名稱 | 範圍 | 行為 |
---|---|---|---|
系統 > 日期和時間 | 自動設定時區* | 全部用戶 | 一個切換開關。 開啟時,設備負責偵測目前時區。關閉時,將為使用者提供手動設定設備時區的控制。 |
系統 > 日期和時間 | 使用位置設定時區 | 目前用戶 | 一個切換開關。 從 Android 12 開始可用。僅當裝置支援位置時區偵測時才會顯示此切換。 有關 14 中引入的更改,請參閱僅支援位置時區偵測的裝置。 |
地點 | 使用地點 | 目前用戶 | 一個切換開關。 通常允許或阻止使用設備的位置。如果設備支援位置時區檢測,則該值相關。 |
下面概述了在給定使用者選擇的設定的情況下時區檢測的設備行為:
[日期和時間] 自動設定時區:關閉
- 使用者必須手動選擇時區。
[日期與時間] 自動設定時區:開
[位置] 使用位置: OFF
- 電話訊號用於偵測時區。
[地點] 使用地點: ON
[日期和時間] 使用位置設定時區: ON
- 位置用於偵測時區。
[日期和時間] 使用位置設定時區:關
- 電話訊號用於偵測時區。
多用戶設備
由於涉及的多個設定的範圍僅限於當前用戶,因此噹噹前用戶在多用戶 Android 裝置上發生變更時,裝置的時區偵測行為可能會發生變化。
「使用位置設定時區」切換的範圍僅限於當前用戶,並且不受設備策略的限制,這意味著用戶始終可以更改其值,即使「自動設定時區」切換關閉或有其他時間或時區控制時也是如此受設備策略控制器的限制。
僅支援位置時區偵測演算法的設備
本節介紹僅支援定位演算法的設備的行為。
Android 14 及更高版本
- 「使用位置」選項不會在 AOSP 設定應用程式中向使用者顯示,且裝置的行為就像啟用「使用位置」選項一樣。
- 使用者範圍的
SettingsProvider
設定location_time_zone_detection_enabled
的值將被忽略。該值記錄了使用者對其他類型設備的偏好。
安卓 12 或安卓 13
- 使用者可以在 AOSP 設定應用程式中看到「使用位置」選項,並且使用者可以停用該選項。如果停用該選項,裝置將不會自動偵測時區。
變更為自動偵測或變更為自動偵測時的行為
當使用者將時區偵測從手動切換為自動時, 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
設定的值。如果您想要確保不會從備份中恢復此設置,請在frameworks/base/packages/SettingsProvider/res/values/blocked_settings.xml
中定義的restore_blocked_global_settings
數組中包含auto_time_zone
。
時區調試與測試
本節提供有關如何調試和測試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 | 設備策略控制器是否阻止使用者控制日期和時間設定。 |
mTelephonyDetectionSupported | 設備是否具有電話時區偵測功能。 |
mGeoDetectionSupported | 設備是否支援位置時區檢測。這是基於配置和至少一個 LTZP 的存在的有效狀態。 |
mAutoDetectionEnabled | 是否啟用自動時區偵測。 |
mLocationEnabled | 主要位置切換。 |
mGeoDetectionEnabled | 演算法開關: false 表示電話演算法, true 表示定位演算法。 |
建議歷史資訊表明透過設定(手動)以及電話和位置演算法提出了哪些建議。