如何在 Android 上取得準確且不被用戶竄改的時間

一、前言 前陣子專案有一項需求,是希望 App 能夠取得準確且不會被使用者竄改的時間。 研究了一下 StackOverflow: How do I get the most accurate time with Android? 上面的討論,決定整理成一篇完整的筆記,也許能拯救到未來的自己? XD 1-1 在 Android 中取得當下時間 大家應該都會直覺地想到以下幾個方式: System.currentTimeMillis()。 Calendar.getInstance() Instant.now() 但這幾個方式,拿到的時間都是所謂的系統時間,只要使用者到系統設定中手動調整,就可以輕易地修改這幾個方式回傳的時間。 二、Android SDK 的 SystemClock Android 的 SystemClock 類別中,有提供以下兩個方法可以拿到準確的時間。 2-1 SystemClock.currentGnssTimeClock() 時間跟稍後會提到的LocationManager.GPS_PROVIDER拿到的時間一樣。 官方文件 SystemClock.currentGnssTimeClock() Returns a Clock that starts at January 1, 1970 00:00:00.0 UTC, synchronized using the device’s location provider. API 29 以上 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import android.os.Build import android.os.SystemClock import java.time.ZoneId import java.time.ZonedDateTime import java.time.format.DateTimeFormatter fun getGpsApiDateTime(): String { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { try { val zoneClock = SystemClock.currentGnssTimeClock().withZone(ZoneId.of("Asia/Taipei")) ZonedDateTime.now(zoneClock).format(dateTimeFormatter) } catch (e: Exception) { "GNSS NOT AVAILABLE" } } else { "SYSTEM NOT AVAILABLE" } } :::danger 📢 注意! 在部分裝置上,GNSS API 回傳的時間有可能是錯誤的… 細節請看 問題-GNSS-API-與-Location-Provider-所拿到的時間可能是錯誤的。 ::: ...

August 26, 2024 · 6 min · 1093 words · Daniel Huang