有沒有辦法檢測Android系統時鐘已被重置由用戶在Android?有沒有辦法檢測用戶何時更改了設備上的時鐘時間?
我正在設計一個應用程序,該應用程序使用系統時間來確定某個用戶在特定時間處於某個特定位置的時間,而且我不想依賴此時的網絡可用性。很明顯,當用戶更改系統時鐘時很好,所以他們不能「欺騙」。
有沒有辦法檢測Android系統時鐘已被重置由用戶在Android?有沒有辦法檢測用戶何時更改了設備上的時鐘時間?
我正在設計一個應用程序,該應用程序使用系統時間來確定某個用戶在特定時間處於某個特定位置的時間,而且我不想依賴此時的網絡可用性。很明顯,當用戶更改系統時鐘時很好,所以他們不能「欺騙」。
是的,有。 ACTION_TIME_CHANGED
Intent在設備時間改變時被廣播,並且你可以有一個方法在檢測到這個意圖時觸發。
這個意圖從API級別1開始就在Android中,所以它應該可以在任何可能需要兼容的平臺上工作。
你需要用BroadcastReceiver
處理廣播:
public class TimeChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do whatever you need to
}
}
您還需要像這樣添加到您的清單:
<receiver android:name=".TimeChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
這將讓安卓知道當檢測到此類意圖時觸發您的接收器。
看起來好像這並不在乎誰編輯時間,而且在與網絡同步時不會觸發自動調整。但是,如果您失去了網絡並重新獲得網絡,那麼這可能會引發火災,因爲您的時間稍有不同(假設您使用自動網絡時間)。但是,雖然手機上的時鐘不是,特別是準確(因爲它們通常依賴於他們接收的時間信號進行同步),但根據我的經驗,它們絕對不應該損失大約30秒或每分鐘一分鐘,在絕對最大值,所以如果時間變化很小,你可以假設它是自動的。閏秒,當它們被添加時,也可能產生時間改變信息,儘管這些信息顯然很小且不經常發生。
您可以使用ConnectivityManager
來跟蹤手機是否有連接,並且您可以基於此來更改行爲(即只要網絡連接存在,時間爲自動/網絡時間,忽略時間更改或其他),但我找不到任何有關丟失/恢復網絡連接的意圖,因此您可能必須使用輪詢方法。
如果你不介意你的應用程序在用戶時鐘由於* DT/* ST轉換而被更新的情況下進行更新,那麼偶爾的時間會與可以倒回時鐘的NTP源同步,你自己的進程停止,你可以對系統時間進行「結果性」檢查,以便如果時間「回來」,則認爲它是「作弊」。否則,你必須依賴服務器,這將是你的「有效」時間的來源。即使如此,你的服務器的時間也可能偶爾會倒退。
其實我只是想的東西:我可以測量System.currentTimeMillis的()'和'SystemClock.elapsedRealtime('之間的差)'如果其更多改變比幾分鐘我知道什麼事了。顯然,我不得不在系統啓動時重置它,但是我可以爲系統啓動事件添加一個'BroadcastReceiver'。感謝您對自動時鐘更新的支持;我希望有一種方法來檢測用戶的變化,但我猜不是! –
如果用戶調整了時鐘,但系統時間(System.currentTimeMillis()
)會發生變化,但自啓動以來的時間(SystemClock.elapsedRealtime()
)希望不會。通過跟蹤這兩者之間的差異,可以檢測到用戶對系統時鐘的重大改變。
重要的是不要跟蹤可能由網絡更新系統時鐘引起的小的變化。我會假設爲了我的目的,在大約半小時之內的任何改變都是不相關的;系統時間不應該在Locale
國家發生變化,但這也可能值得消除。
經過的實時時間顯然會在啓動時重置,所以我應該包含一個BroadcastReceiver
以在接收android.intent.action.BOOT_COMPLETED
時重置差分。
無法直接使用SystemClock.elapsedRealtime()System.currentTimeMillis() – Suranga
關於matt5784答案的一點注意:我發現在Android 4.1.2上,意圖操作不可用,不知道這是針對所有android版本還是隻針對我的。取而代之的
"android.intent.action.ACTION_TIME_CHANGED"
使用
"android.intent.action.TIME_SET"
對不起,我按下了按鈕錯誤:(我會嘗試反轉它以後。現在stackoverflow阻止我撤消它:|對不起。 – ahmedibrahim085
:) ....沒問題.... – Opiatefuchs
我再次嘗試,但它給了我一個紅色的消息:「除非編輯此答案,否則您的投票現在被鎖定。」我真的很抱歉 – ahmedibrahim085
我們可以同時使用TIME_SET
和TIMEZONE_CHANGED
。
<application
...>
<receiver android:name=".TimeChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
</intent-filter>
</receiver>
</application>
TimeChangedReceiver.java
public class TimeChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "time change " + intent.getAction(), Toast.LENGTH_SHORT).show();
}
}
此方法區分**用戶**更改時間和由於網絡更新而改變時間嗎? –
這是一個非常好的問題。答案似乎是否定的,因爲當我將手機放入飛行模式幾分鐘後觸發,然後打開收音機。但是,當您從網絡獲取自動時間更新時,它不會觸發,並且會進行微調以保持時間準確。有幾個選項可以獲得非常準確的時間:您可以在位置對象上使用時間戳,這非常準確,但無法按需提供請求(您可以聽取他們進來,當您知道時間的時候在那時候)。 – matt5784
請參閱http://stackoverflow.com/a/12320918/1003511以瞭解從該位置獲取時間的可能實施方式。此外,似乎還有一種方法可以啓用設備的自動時間同步設置,但如果用戶由於某種原因手動設置了時間,則這對用戶來說可能不是最佳選擇。有關這方面的更多信息,請參閱http://stackoverflow.com/a/8214204/1003511。我也編輯了我的答案。 – matt5784