AndroidのユーザーがAndroidのシステム時計をリセットしたことを検出する方法はありますか?
私は、システム時刻を使用して、ユーザーが特定の時間に特定の場所にいる時間を判断するアプリを設計しています。その時点でのネットワークの可用性に依存したくありません。したがって、明らかに、ユーザーがシステムクロックをいつ変更したかを知っておくと、「ごまかす」ことができなくなります。
はいあります。インACTION_TIME_CHANGED
テントは、デバイスの時刻が変更されたときにブロードキャストされ、このインテントが検出されたときにトリガーされるメソッドを使用できます。
このインテントは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>
これにより、このタイプのインテントが検出されたときにAndroidがレシーバーをトリガーするように通知されます。
誰が時間を編集するかは関係ないように見えますが、ネットワークと同期しているときに自動調整がトリガーされることもありません。ただし、ネットワークを失って回復した場合は、時間がわずかに異なるため(自動ネットワーク時間を使用していると仮定して)、これが発生する可能性があります。
ただし、私の経験では、携帯電話の時計は特に正確ではありませんが(通常、受信する時報との同期に依存しているため)、絶対最大で1時間あたり約30秒または1分を超えて失われることはありません。時間の変化が小さい場合は、おそらく自動であると見なすことができます。うるう秒が追加されると、時間変更メッセージも生成される可能性がありますが、これらは明らかに小さく、まれです。
ConnectivityManager
電話が接続されているかどうかを追跡するために使用でき、それに基づいて動作を変更できます(つまり、ネットワーク接続があり、時刻が自動/ネットワーク時刻である限り、時刻の変更などを無視します)。ネットワーク接続の喪失/回復に関する意図が見つからないため、おそらくポーリング方法を使用する必要があります。
ユーザーが時計を調整するとシステム時間(System.currentTimeMillis()
)は変更されますが、起動()からの経過時間は変更されないことがSystemClock.elapsedRealtime()
望まれます。これら2つの差を追跡することにより、ユーザーによるシステムクロックの大きな変化を検出することが可能になります。
ネットワークがシステムクロックを更新することによって引き起こされる可能性のある小さな変更を追跡しないことが重要です。私の目的では、約30分未満の変更は関係ないと想定します。国が変わってもシステム時刻は変わらないはずLocale
ですが、それも排除する価値があるかもしれません。
BroadcastReceiver
経過したリアルタイムは明らかに起動時にリセットされるので、受信時に差分をリセットするためにを含める必要がありますandroid.intent.action.BOOT_COMPLETED
。
matt5784の回答に対するちょっとした注意:Android 4.1.2ではインテントアクションが利用できないことがわかりました。これがすべてのAndroidバージョン用なのか、それとも私のものなのかわかりません。それ以外の
"android.intent.action.ACTION_TIME_CHANGED"
使用する
"android.intent.action.TIME_SET"
との両方を使用でき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();
}
}
* DT / * STシフト、時折時計を巻き戻すことができるNTPソースとの時折の時間同期、独自のプロセスの停止により、ユーザーの時計が更新される場合にアプリがチートをスローすることを気にしない場合は、「システム時刻を「結果的に」チェックして、時刻が「戻った」場合は「チート」であると見なすようにします。それ以外の場合は、「有効な」時間のソースとなるサーバーに依存する必要があります。それでも、サーバーの時間が逆行することがあります。