Android の AlarmManager で onReceive が呼ばれない
- 2017年05月09日
- Android, Java
- AlarmManager, PendingIntent
Android の AlarmManager での処理を実装していたときにハマったので注意点を書いておきます。
異なる時間に実行する複数のアラームを同時にセットする
今回は定期的ではなく、いくつかの時刻で少しずつ異なる処理をさせたかったのですが、それを一度にセットしようと考えていました。内容が異なる Intent をそれぞれセットした pendingIntent を複数 AlarmManager に送るということをしていました。
しかし、指定した時間が来ても BroadcastReceiver の onReceive が呼ばれません。単体のアラームだと呼ばれますが、複数にすると呼ばれません。
AlarmManager の状態を確認すると複数のアラームがセットされて見える
AlarmManager の状態を取得するには、開発環境から以下のようにコマンドを実行します。
1 2 3 |
adb shell dumpsys alarm > alarm.txt |
アラームマネージャーの状態がダンプされた alarm.txt を確認すると、複数のアラームがセットされているように見えます。
しかし、あとでわかったことですが、実際には最後のアラームだけが有効になっていました。
原因は単純なことですが、Intent を PendungIntent に渡すときに以下のようにして第4引数に PendingIntent.FLAG_CANCEL_CURRENT
を指定していました。
1 2 3 4 5 6 7 8 |
//intent を PendingIntent にセット PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); //アラームマネージャーの取得 AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); //アラームマネージャーにセット alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender); |
この状態だと、次の PendingIntent が AlarmManager に渡されたときに、前ものと同一だと判断されてキャンセルされていました。そのため、一番最後に追加した(かなり時間が先の)予定だけが有効になった状態になっていたようです。しかし、キャンセルされているにもかかわらず AlarmManager の状態ダンプではすべて実行されているよう見えてしまいます(ここでハマりました)……。
第4引数に PendingIntent.FLAG_UPDATE_CURRENT
を指定してみると、1つだけ有効になりました。しかし複数を事前にセットしてしまうと、上書きされていくので、最後のものだけが残る感じです。これはこれで便利なのですが。
解決策
複数の予定を AlarmManager に登録することはあきらめて、直近で呼び出したいもの1つだけを登録しました。第4引数には PendingIntent.FLAG_ONE_SHOT
を指定して呼び出しました。そしてレシーバーの onReceive で必要な処理をしたあと、改めて次のアラームをセットするようにしました。
今回は単純な繰り返しアラームではないので、こちらの方が柔軟に対応できました。Intent の使っていないパラメータをセットして別のアラームとして認識させる方法もありますが、Android のアラームは時間がずれることがあり、定期的にセットし直さないといけないという理由もあり、今回は1件ずつ登録するようにしました。
参考サイト
- PendingIntentのフラグ設定による振る舞いの違い | Workpiles ここの解説がわかりやすかったです。
- Y.A.M の 雑記帳: Android AppWidget の PendingIntent で putExtra するときの注意 ここによると第2引数を 0 ではなくて異なる値にすれば別の intent と認識してくれそうですが、今回はうまくいきませんでした。
- AlarmManagerに異なるintentと認識させる方法 | Android Techfirm Lab異なるダミーのパラメーターをセットして時間差で複数のアラームを使う方法が書かれています。今回は試していませんがこの方法も使えると思います。
ITエンジニア募集中!
キュアコード株式会社はITエンジニアを募集しております。少人数の職場なので、上流・下流やサーバー・クライアント対応の垣根なく、あなたの強みを活かしながら いろいろなことにチャレンジ可能です。エンジニアとしての未経験の方、経験が少ない方も歓迎しています。
下記よりITエンジニア募集の採用情報をご覧いただけます。