AlarmManager
AlarmManagerを使うと、アンドロイドのコンポーネントを指定した時間に呼び出す事ができる。
また、一定の時間間隔で呼び出す事もできる。サンプルプログラム
サンプルプログラムをまず示します。
このプログラムは、AlarmManagerを使って指定した時間にブロードキャスト レシーバを呼び出します。
ブロードキャスト レシーバでは、トーストとログに呼び出し時の情報を出力します。
eclipseに新しいアンドロイドプロジェクトを作成して、以下のようなアクティビティクラスを記述します。
プログラム(1)-AlarmManagerを使ってブロードキャストレシーバを呼び出すアクティビティクラス(AlarmManagerSample.java)
プロジェクトに、BroadcastReceiverを継承したクラスを追加して、以下のようなコードを記述します。
プログラム(2)-呼び出されるブロードキャストレシーバクラス(GudonReceiver.java)
ブロードキャストレシーバクラスをアンドロイドが認識できるように、マニフェストファイル「AndroidManifest.xml」を修正します。プログラム(3)-マニュフェストファイル(AndroidManifest.xml)
このプログラムを実行するとアクティビティクラスAlarmManagerSampleが起動して、以下のような画面が表示されます。
この画面には、4つのボタンが表示されています。
それぞれのボタンのイベントメソッドが、AlarmManagerの使用パターンの例を示しています。
「ELAPSED_REALTIMEの例」ボタンを押すと、以下のようなトースト画面が表示されるとともにログが出力されます。
AlarmManagerの基本的動作
「ELAPSED_REALTIMEの例」ボタンが押された時の処理をみていきます。
この処理は、プログラム(1)の34~45行目に記述されています。
35,36行目で、AlarmManagerオブジェクトを取得しています。
38,39,40行目で、ブロードキャストレシーバクラスGudonReceiverを呼び出すためのインテントオブジェクトを作成して、 このクラスに渡すためのパラメータをエクストラに格納しています。
41,42行目で、PendingIntentクラスの静的メソッドgetBroadcastを実行して、 このインテントすなわち、GudonReceiverクラスを呼び出すためのPendingIntentオブジェクトを取得します。
インテントについては「謎めいたインテント」を参照して下さい。
PendingIntentについては、「サービスとNotification」を参照して下さい。
43行目のSystemClock.elapsedRealtimeメソッドで、アンドロイドマシーンのブートからの起動時間をミリ秒単位で取得します。
44,45行目でAlarmManagerクラスのsetメソッドを指定して、1秒後にGudonReceiverクラスを起動するように設定しています。
setメソッドには、PendingIntentの呼び出し時間の設定にデバイスのブートからの時間をミリ秒単位で指定する方法と、通常の時間をミリ秒単位で指定する方法とがあります。
ブートからの時間で指定する場合には、44行目のようにsetメソッドの第1引数に、AlarmManagerクラスの定数「ELAPSED_REALTIME」 または「ELAPSED_REALTIME_WAKEUP」を指定します。
「ELAPSED_REALTIME」と「ELAPSED_REALTIME_WAKEUP」の違いは、 「ELAPSED_REALTIME_WAKEUP」の場合はデバイスがオフの場合にデバイスを起動する事です。
「RTCの例」ボタンが押されたときの処理(56~67行目)は、通常の時間をミリ秒単位で指定する例です。
setメソッドの第1引数に「RTC」定数を指定して(66行)、 System.currentTimeMillisメソッドにてミリ秒単位の現在の時間を取得した値に、1秒を加えた値を第2引数に指定しています。
setメソッドの第1引数に「RTC_WAKEUP」を指定して、デバイスがオフの場合にデバイスを起動する事もできます。
指定時間が経過すると、プログラム(2)のonReceiveメソッドが呼び出されます。
onReceiveメソッドでは、現在の日付・時刻とエクストラに渡されたPARAMパラメータをトーストとログに出力しているだけです。
以下に、このプログラムを実行して「ELAPSED_REALTIMEの例」ボタンと「RTCの例」ボタンを押した時の、LogCat出力を示します。
PARAMパラメータにはsetメソッド実行時の時間が渡されているので、指定時間後にonReceiveメソッドが実行されているのがわかります。
コンポーネントを定期的に起動する。
コンポーネントを定期的に起動するには、setメソッドのかわりにsetRepeatingメソッドまたはsetInexactRepeatingメソッドを使います。
setInexactRepeatingのInexactは「不正確な」という意味で、 リファレンスによるとsetInexactRepeatingの方が時間が多少不正確であるが、setRepeatingよりも電力効率が良いらしい。 (英文なのでよくわからないが多分そういう事だと思う。)
「setRepeatingの例」ボタンと「setInexactRepeating の例」ボタンの処理の、89行と112行でそれぞれのメソッドを実行しています。
setRepeatingメソッドとsetInexactRepeatingメソッドの第1引数の意味はsetメソッドと同じです。
ここでは「RTC」定数を指定していますが、もちろんsetメソッドと同様、他の定数も使う事ができます。
第2引数には初回の実行時間,第3引数には実行間隔を指定します。
setInexactRepeatingメソッドの第3引数には定義済みの定数「INTERVAL_FIFTEEN_MINUTES」, 「INTERVAL_HALF_HOUR, INTERVAL_HOUR」, 「INTERVAL_HALF_DAY, INTERVAL_DAY」 を指定できます。
リファレンスを見ると、この定数を指定した時とそれ以外の場合でなにやら違いがあるらしいのだがよく理解できなかった。
インテントにsetDataメソッドを使用して、85行目と108行目で異なるデタラメなURIを指定していますが、 これは、setRepeatingメソッドとsetInexactRepeatingメソッドで指定したインテントを区別するためです。
これを指定しないと、「setRepeatingの例」ボタンと「setInexactRepeating の例」ボタンの両方を押した場合に、片方のタイマーしか実行されなくなります。
setメソッドも同じなのですが、指定したインテントを区別するために、IntentクラスのfilterEqualsメソッドが使われていて action, data, type, class, categoriesのすべて(エクストラは含まれていない)が同じなら同じインテントと判断されてしまうためです。
プログラム(1)の120行目からのonDestroyメソッドで、アクティビティ終了時にsetRepeatingメソッドとsetInexactRepeatingメソッド のそれぞれのタイマーをキャンセル(129行と135行)していますが、インテントにsetDataメソッド(126行と132行)を使って対応するそれぞれのURIを指定しています。
タイマーをキャンセルしないとアクティビティを終了しても、タイマーは生き続けたままになってしまいます。
「setRepeatingの例」ボタンと「setInexactRepeating の例」ボタンの両方を押した場合の、LogCat出力を以下に示します。
それぞれのタイマーが平行して動作している事がわかります。