我正在開發一個應用程式,我可以通過使用在多個地方檢索當前日期new Date(),如果用戶更改了手機中的日期,則不允許使用該日期,因為它是錯誤的。
由于應用程式的性質,當獲取日期的操作完成時,可能沒有互聯網連接,因此我們可以越來越少地確保日期正確,而不是像處理NTP服務器這樣的東西如果用戶有選項使用網路日期/時間和使用網路時區啟用并且他連接到電話網路(當然,如果可能篡改日期但它看起來足夠安全)。
問題是也可能沒有電話網路正在使用電話,我已經檢查了以下內容:
您可以禁用使用網路日期/時間并設定您喜歡的日期。
您激活飛行模式(或類似的無連接情況)
你重啟手機。
您啟用使用網路日期/時間。
現在,盡管設定了使用網路日期/時間和使用網路時區,但手機上的日期不正確。確實,如果我退出飛行模式日期會再次正確設定。
也許可以通過諸如檢查用戶是否已重新啟動手機的服務來檢測之前的情況,然后在手機啟動時確定日期的服務再次被正確使用,然后應用程式檢查該服務說它被正確使用所以它允許用戶接受它......但這一切似乎很難做到,我們可能會打擾誠實的用戶,他們不得不在沒有電話連接的區域重新啟動手機,然后嘗試使用該應用程式而不試圖欺騙其他人日期。
那么,有沒有關于不太復雜的方法的想法,對于誠實的用戶沒有竊聽,可以在沒有任何類的連接的情況下獲得日期?或者這是不可能的?
uj5u.com熱心網友回復:
為了在 Java 中獲取系統時間,您可以使用System.currentTimeMillis(),盡管此模塊與電話時間和日期同步。為了獲得與手機日期和時間System.nanoTime()無關的系統時間,您可以使用,它與手機時鐘無關。
但是,該nanoTime模塊不是絕對的——它測量與某個任意點相關的值,因此您應該nanoTime在代碼中保存一些已知日期的值,然后與它進行比較。
了解如何從格式化的時間nanoSeconds迄今在這個文章。
關于nanoTime 的相關文章。
uj5u.com熱心網友回復:
你在談論
System.currentTimeMillis().
// user can change it by adjusting the DATE of the phone.
但這可以幫助你。
SystemClock.elapsedRealtime()
這兩者之間的區別可以幫助您。
https://developer.android.com/reference/android/os/SystemClock
- 編碼后,您應該將毫秒轉換為日期
uj5u.com熱心網友回復:
沒有僅離線的解決方案將滿足“我怎么知道用戶沒有將日期更改為錯誤的日期”標準。
您唯一可以做的并避免這些問題的方法就是與服務器時間同步。然后,在這樣做之后,有一種簡單的方法可以確定。
您想使用 SystemClock.elapsedRealtime() (每次啟動后都會重置,并且需要新的服務器時間同步)
沿著這些路線的東西:
public class DeviceTimeProvider {
public long getElapsedRealtimeMillis() {
return SystemClock.elapsedRealtime();
}
public long getCurrentTimeMillis() {
return System.currentTimeMillis();
}
}
public TimeSnapshot createTimeSnapshot() {
long upTime = deviceTimeProvider.getElapsedRealtimeMillis();
long clock = deviceTimeProvider.getCurrentTimeMillis();
String bootId = bootIdProvider.getBootId();
return new TimeSnapshot(upTime, clock, bootId);
}
. . .
public class TimeSnapshot {
public final long upTime;
public final long clockTime;
public final String bootId;
public TimeSnapshot(long upTime, long clockTime, String bootId) {
this.upTime = upTime;
this.clockTime = clockTime;
this.bootId = bootId;
}
. . .
}
public class BootIdProvider {
private final Context context;
private String cachedBootId = null;
public BootIdProvider(Context context) {
this.context = context;
}
public String getBootId() {
if (cachedBootId != null) {
return cachedBootId;
}
String bootId = null;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
try {
bootId = String.valueOf(Settings.Global.getInt(context.getContentResolver(),
Settings.Global.BOOT_COUNT));
} catch (Settings.SettingNotFoundException e) {
LFLog.w(LOG_TAG, "", e);
}
} else {
// try reading "proc/sys/kernel/random/boot_id" or just do this
bootId = UUID.randomUUID().toString();
}
cachedBootId = bootId;
return bootId;
}
}
但是無論這些如何,請務必在每次啟動時至少與服務器時間同步一次(恰好一次就可以),因為其他任何東西都可以用來欺騙您。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/327949.html
