AlarmManager#setInexactRepeatingにバグ? | sola's note

sola's note

日ごろのメモを書いていきます。何か新しいものを作るために。

定期的な処理を実行する時に、
AlarmManagerとBroadcastReceiverを使ってバックグラウンド処理を実装すると思いますが
AlarmManager側のバグっぽいものにぶつかってハマりました。

以下簡単な設定です。

・HogeActivity→呼び出し用Activity
・HogeReceiver→BroadcastReceiverを拡張した受け取りクラス

--呼び出し側ソース(一部)--

Intent intent = new Intent(HogeActivity.this,
        HogeReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(
        HogeActivity.this, 0, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);

//初回実行時間の設定
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_HOUR, sender);

こんな感じにしたのですが、
デバッグしてみると、HogeReceiver#onReceiveがまあ呼ばれない

色々試した結果
バグor失敗率急上昇の要因はAlarmManager#setInexactRepeatingの第三引数に
AlarmManager.INTERVAL_HOUR(または3600000)を設定していた事と判明。

これが、デバッグ時限定なのかというのは確認していないので分かりません。
Android Developersのリファレンスを見てみると
次のように書いてあります。

--引用--
interval in milliseconds between subsequent repeats of the alarm. If this is one of INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY then the alarm will be phase-aligned with other alarms to reduce the number of wakeups. Otherwise, the alarm will be set as though the application had called setRepeating(int, long, long, PendingIntent).
--引用ここまで--

まあ、ざっくり言えば
「特定の時間(※1)を起動間隔として設定すると、他のアラーム設定と一緒に扱うよ」
という事らしいのですが、これが関係しているのか分かりませんが、

第三引数のAlarmManager.INTERVAL_HOURを上記で指定されている秒数以外である
AlarmManager.INTERVAL_HOUR + 1にしたらデバッグ時に動作が確認出来ました。

ただ、AlarmManagerには
setInexactRepeating()以外にsetRepeating()という、
殆ど同じ動作をするものがあって、違いが起動時間間隔の正確さ(0秒丁度に起動するかどうか)
みたいなので、

setInexactRepeating()に"特定の時間"以外を指定して使う

という事をするならば、
多分setRepeating()の方が無駄が無いのではないでしょうか。
ちなみにsetRepeating()に変更するとAlarmManager.INTERVAL_HOURでも問題なく動きました。

ちなみにのちなみにですが、本件「バグかどうか」はわかっておりません。
1msec違うだけで指定した時間にブロードキャストが実行されなかったので、ほぼそうだと思いますが
ソースファイルは解析していないので悪しからず。

※1 特定の時間
INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY
を指していて、
15分、30分、1時間、12時間、24時間が該当するようです。