[Android] AlarmManagerをBroadcastRecieverと使う

ある時間にアプリから通知して欲しいという場合がよくあります。目覚まし時計とかスケジュール系のアプリなど、これらの通知には時間を管理する AlarmManager 及びその関連APIを使います。
 
 
1x1.trans - [Android] AlarmManagerをBroadcastRecieverと使う

Android Studio
2021.2.1

 




AlarmManager

 

いきなりですが、アプリのオプションでアラームを鳴らしたいだけなら、Intentを使ったアラーム クロックを使うと簡単です。
 
また、setExactAndAllowWhileIdleをサービスを使って繰り返す方法もあります。

短時間の単純なタイマーや時間計測にはAlarmManagerではなく、Handlerを使うことが推奨されています。

For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.

Ref: AlarmManager


 
また、AlarmをBroadcastReceiver で受けるケースでは、ブロードキャストの制限事項 があります。

Android 8.0 を対象にしているアプリは、暗黙的なブロードキャストに対するブロードキャスト レシーバーをマニフェストで登録できなくなりました。 

明示的な登録であれば大丈夫のようです。元々の理由が暗黙的BroadcastRecieverがたくさんあると関係ないアプリも毎回呼び出しを食らってリソース、消費電力の観点からよくないと言う理由からです。

また、AlarmManagerを使う上で、Dozeモードという低消費電力モードを考えないといけないのですが、API levelによって挙動が異なります。
つまり目覚まし時計を作ろうとした場合、このあたりをうまくやらないと時間通りにアラームが鳴りません。

setexact 01b 100x100 - [Android] AlarmManagerをBroadcastRecieverと使う
AlarmManagerで繰り返しのアラーム機能を実装したいのですが、バックグラウンド実行制限があります。本来の機能として定期的なバックグラ...

この他にタスクスケジュールを実行できるののとしてJobSchedulerやJobDispatcherなどがあります。
 

 

AlarmManager

 

このクラスを直接インスタンス化してはいけないようで
Context.getSystemService(Context.ALARM_SERVICE) を使います

 
その後、例えば繰り返しのアラームメソッド set はこのように設定します

 
sender は PnedingIntent のインスタンスです。
これは単発アラームの例ですが、他にもメソッドがいくつもあります。

また、API levelによって様々追加されました。AlarmManager | Android Developers

  • API level 19: アラーム時間の精度が低いものが使えるようになる
  • API level 23: Dozeモードの導入でDoze中でも起動できるメソッドの追加
  • API level 24: Direct callbackが使えるメソッド

set

: ワンショットのアラーム, API level 19 以降では低精度

 
set: 上記set に Direct callback が追加

 
setRepeating: 繰り返しアラーム

 
setInexactRepeating: 繰り返しアラーム、API level 19 以降では低精度

   
setExact: setよりも正確なワンショットアラーム

 
setExact: 上記setExactに Direct Callback が追加

 
setAndAllowWhileIdle: setと同じだが low-power idleモードでも実行される。

 

 

setExactAndAllowWhileIdle

: setExactと同じだが low-power idleモードでも実行される。

Doze中でも定期的にアラームを出にはこれらを使います。
 
 
setWindow: 設定したwindow内でアラームが実行

 
setWindow: 上記setWindowにDirect Callbackが追加

 
setAlarmClock: Dozeモードでもアラームを出してくれるようです。

 
また、その他に

  1. cancel
    • 設定したアラームの取り消し
  2. setTime
    • ミリ秒での時間設定
  3. setTimeZone
    • タイムゾーンの設定

などがあります
 
また、アラームに関する定数が幾つかあります。例えば、

  1. ELAPSED_REALTIME
    • スリープ時間を含んだブートアップからの経過時間
  2. ELAPSED_REALTIME_WAKEUP
    • ELAPSED_REALTIME に加えて、実機スリープ中では wake up してくれる
  3. RTC
    • 時刻
  4. RTC_WAKEUP
    • RTCに加えて実機スリープ中では wake up してくれる

 

 

PendingIntent

 

PendingIntent は作成した Intent をタイミングを見て他のアプリケーションに渡す場合に使います。

Android 12からは PendingIntentのmutability(可変性) を指定するために
FLAG_IMMUTABLE を設定する必要があります。

PeindingIntentでは受け取った側が指定されていないパラメータを追加して投げることができるためにFLAG_IMMUTABLEを明示的に指定して上書きできないようにします。
(FLAG_MUTABLE は書き換えできる)

getBroadcastの第2引数は requestCode です。PendingIntent が1つの場合は0で大丈夫ですが複数ある時は、この requestCode を使って Receiver 側で切り分けます

Ref: PendingIntent
http://developer.android.com/reference/android/app/PendingIntent.html

setExactなどの正確なアラームを設定したアプリでは、システム設定の [特別なアプリアクセス] 画面に表示される「アラームとリマインダー」機能へのアクセス権が必要になります。

マニフェストで SCHEDULE_EXACT_ALARM 権限をリクエストします。

 

BroadcastReceiver

 

PendingIntent からの Intent を受け取りるクラスを新しく作ります。そこでアラームを受けトーストします。
 

 

サンプルコード

 

これらの内容をふまえて実際にコードを組んでみましょう
 
WAKE_LOCK パーミッションとBroadcast の receiver を入れます。
AndroidManifest.xml

 
ボタンをタップしてアラームをセットするようにします
MainAcrivity.java

 
アラームをBroadcastReceiver で受けます
AlarmBroadcastReceiver.java

 
activity_main.xml

 

サンプル動画

 

 

アラームを設定して開始
BroadcastReceiver で受け取るという簡単な例でした
次はアラームを通知できるようにしてみます
 
 
関連:

 

References:
AlarmManager | Android Developers
BroadcastReceiver | Android Developers
PendingIntent | Android Developers

シェアする

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

フォローする