Location.getTime()
不一定是衛星時間Daniel HuangSat, May 27, 2023 4:21 PM
最近的專案需要取定位的時間,並用該時間判斷使用者是否有在指定時間完成任務,而業主就提出希望以定位所取得的時間做為判斷依據。
然後,就發現事情沒有想像中的那麼單純。
原來目前在 Android 的定位結果中所取得的時間,只有在定位來源為純 GPS 的情況下才會是衛星所回傳的時間。
來看看究竟是怎麼一回事吧…
不論是使用 Android 官方推薦的 Fused Location Provider 或是 LocationManager ,定位結果所回傳的型別都是 Location
。這個型別除了基本的經緯度與海拔等資訊,其中也包含定位的時間。
通常開發上指的定位時間,我們會使用 Location.getTime()
取得 Unix epoch time,再將這串數字轉成人類可閱讀的時間格式。
Unix epoch time: 從 UTC 1970年1月1日0時0分0秒起至現在的總秒數,不考慮閏秒。
–Wikipedia
Location.getTime()
會跟定位來源有關從 Android Doc: Location.getTime() 的說明會發現,
不同的定位結果所取得的時間來源不見得相同。
當定位結果是由 LocationManager.GPS_PROVIDER
提供的時候,時間會是由衛星所提供。如果是其他的 Provider,時間來源則不一定,不過通常會是使用裝置系統的 Unix epoch time。
There is no guarantee that different locations have times set from the same clock. Locations derived from the LocationManager#GPS_PROVIDER are guaranteed to have their time originate from the clock in use by the satellite constellation that provided the fix. Locations derived from other providers may use any clock to set their time, though it is most common to use the device’s Unix epoch time system clock (which may be incorrect).
除了以上,文件上也提醒了
看完文件的説明,再加上 StackOverflow: GPS-time in Android 的回答,目前已知訊息可以歸納如下。
getProvider()
會回傳 fused
getTime()
回傳的會是裝置系統時間。LocationManager.NETWORK_PROVIDER
:
getProvider()
會回傳 network
getTime()
回傳的會是裝置系統時間。LocationManager.GPS_PROVIDER
:
getProvider()
會回傳 gps
getTime()
回傳的會是 GPS (Satellite) 時間。將裝置時間設為 2023/05/21,實際時間是 2023/05/23。實測後會發現只有 GPS Provider 下的 GPS 時間會顯示現實世界的時間,其他的都會是顯示裝置設定的時間。
定位類型 | 實測結果 |
---|---|
LocationManager Network Provider |
|
LocationManager GPS Provider |
|
Fused Location |
在 Android 裝置上,如果要取得不受裝置時間設定影響的衛星時間,要使用 LocationManager
並將請求的定位來源設定為 LocationManager.GPS_PROVIDER
,否則拿到的時間都會是裝置時間哦!!
Daniel HuangMon, Aug 26, 2024 1:59 PM
經過實測發現,有些裝置的 GPS 晶片受到 GPS Week Number rollover 問題的影響,產出的 GPS 時間是錯誤的。在開發上需要手動將相差時間秒數加回原始值,才能取得正確的時間。
有關這個問題,細節可以看 Android 取得準確的時間 (GPS/NTP) 這篇文章中的說明。
本文同步更新在 Medium