[android]AlarmMangerのset系メソッドの精度

Android6.0からDozeという状態が増え、それに伴いAlarmMangerでアラームをセットするメソッドも増えたようです。
たくさんありすぎて複雑。整理しました。

★Nexus5 (Android6.0)で以下のメソッドを試したざっくりな感触
上2つは、たぶんAndroid5.0とかでも同じかと思われます。
・set、setRepeating
  → 数秒遅れることが多い。
    例えば、12:00ちょうどに受け取とりたいという場合には使えなさそう。
・setExact、setWindow
  → ほぼ、ちょうどに受け取れます。1秒以内のずれはあるかも。。。
・setExactAndAllowWhileIdle
  → 通常の起動している場合は、setExactと同じ感じでした。
    Doze状態中は数分遅れます。
    10回ほど試したところ、3~7分とか遅れることがありました。
    最大で15分遅れるようです。
    参考:AlarmManagerを攻略する
・setAlarmClock
  → 制限がなく、スリープさせていてもだいたいちょうどに受け取れました。
    しかし、常に端末が起きている状態=電力の消費が大きいのため、一般的なアプリとして使用は向かないと思われます。
    そのため、細かくは検証していません。

メモ:Doze modeのメモ android6.0以上

=====機能詳細=====

■API Level 1 から使える
・set(int type, long triggerAtMillis, PendingIntent operation)
  → 単発アラーム
・setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
  → 繰り返しアラームの設定

■API Level 19 (android 4.4) から使える
※このAPIができたことにより、API Level 1 から使えたメソッド set、setRepeatingは正確ではなくなったようです。
・setExact(int type, long triggerAtMillis, PendingIntent operation)
  → 開始時間からの(多少正確な)アラーム設定
・setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
  → おおまかなアラームの繰り返し設定
・setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation)
  → 設定したwindow内でアラームが起動する

■API Level 21 (android 5.0) から使える
・setAlarmClock (AlarmManager.AlarmClockInfo info, PendingIntent operation)
  → 制限が全て無いメソッド、つねにバッテリーへの影響が非常に大きい。

■API Level 23 (android 6.0) から使える
・setAndAllowWhileIdle (int type, long triggerAtMillis, PendingIntent operation)
  → Doze状態中も発火されるスケジュール
・setExactAndAllowWhileIdle (int type, long triggerAtMillis, PendingIntent operation)
  → Doze状態中も発火されるスケジュール(多少正確な)
 
 #Doze状態でも使えるメソッドも、IDLEからの復帰は15minに一度だけ許されるらしい。

精度について、API Level 19までの情報ですが、以下のサイトが見やすかったです。

実装例:

    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    long triggerAtMillis = ~~~アラームの時間~~~;
    PendingIntent pending = ~~~アラームのPendingIntent~~~;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // android6.0以上
        am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, pending);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // android4.4以上
        am.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, pending);
    }else {
        am.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, pending);
    }

シェアする

  • このエントリーをはてなブックマークに追加

フォローする