AlarmManager は、アプリケーションが指定した時間にタスクを実行できるようにするAndroidのシステムサービスです。アプリケーションが実行されていない場合やデバイスがスリープモードの場合でも機能します。JobSchedulerやWorkManagerとは異なり、AlarmManagerは正確なトリガーを保証するため、アラーム、カレンダーのリマインダー、時間に敏感なタスクに不可欠です。Android Developers, 2026によると、Android 4.4以降、setRepeatingは不正確な繰り返しとして動作し、正確なアラームにはsetExactまたはsetAlarmClockが必要です。
重要なポイント
AlarmManager は、正確またはおおよその実行時間でタスクをスケジュールするためのAPIを提供するAndroidシステムサービスです。Androidの最初のバージョンから存在し、アプリケーションやデバイスの状態に関係なく、指定された瞬間にコードを実行する唯一の信頼できる方法です。
動作原理はシンプルです。アプリケーションは、指定されたトリガー時間とともにPendingIntentをシステムに送信します。指定された時間になると、システムは登録された BroadcastReceiver にIntentを送信するか、Serviceを開始します。デバイスがスリープモードであっても、WakeLockによってプロセッサが起動してイベントを処理できます。
AlarmManagerの主な適用分野 は、正確なタイミングを必要とするタスクです。アラーム、カレンダーのリマインダー、特定の時間に長時間の操作を開始するなどです。精度が重要でないタスク(毎日の同期)には、GoogleはWorkManagerまたはJobSchedulerを推奨しています。これらはよりエネルギー効率が良いためです。
AlarmManager はアプリケーションからPendingIntentとトリガー時間を受け取ります。システムはこのリクエストを内部スケジューラーに保存し、指定された時間にプロセッサを起動してIntentを配信します。開発者はこのIntentを処理するために事前にBroadcastReceiverを登録する必要があります。
AlarmManager は4種類のアラームをサポートしています:ELAPSED_REALTIME(起動からの時間、起動しない)、RTC(リアルタイム、起動しない)、ELAPSED_REALTIME_WAKEUP(起動からの時間、デバイスを起動する)、RTC_WAKEUP(リアルタイム、起動する)。WAKEUPバージョンは、デバイスがスリープしている場合でもタスクを実行する必要がある場合に必要です。
| 種類 | 時間 | 起動 | 例 |
|---|---|---|---|
| ELAPSED_REALTIME | 起動からの経過時間 | いいえ | 稼働時間タイマー |
| RTC | Unixタイムスタンプ | いいえ | ロギング |
| ELAPSED_REALTIME_WAKEUP | 起動からの経過時間 | はい | 定期的なタスク |
| RTC_WAKEUP | Unixタイムスタンプ | はい | アラーム時計 |
Android 12(API 31)以降、正確なアラーム(setExact)を使用するには SCHEDULE_EXACT_ALARM 権限が必要です。ユーザーは設定からこれを取り消すことができます。表示付きの正確なアラームが必要なアプリケーション(時計アプリなど)には、インストール時に付与されるUSE_EXACT_ALARMが使用されます。
AlarmManager はタスクをスケジュールするための3つの主要なメソッドを提供します。メソッドの選択により、トリガーの精度とデバイスの電力消費への影響が決まります。
set — 1回限りの不正確なトリガーのための基本メソッド。システムは他のイベントとグループ化するために時間を数分までずらすことができます。精度が重要でないタスク(アプリケーションを開くリマインダー)に適しています。
setRepeating — 定期的な繰り返しのためのメソッド。Android 4.4(API 19)以降、setRepeatingは不正確になりました。間隔が変動する可能性があります。システムはもはや一定の期間を保証しません。setRepeatingの代わりに、再スケジュール付きのsetExact、またはPeriodicWorkRequestを使用したWorkManagerを使用することをお勧めします。
setExact — 正確な1回限りのトリガーのためのメソッド。システムは指定された時間にできるだけ近い時間にデバイスを起動します。setAlarmClock はsetExactの特殊なケースで、ステータスバーにアラームアイコンを表示し、すべてのアラームタイプの中で最も高い優先順位を持ちます。
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// 正確な1回限りのアラーム
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
典型的なシナリオ は、特定の時間に毎日のリマインダーを作成することです。この目的にはsetExactとRTC_WAKEUPを使用します。トリガーされると、BroadcastReceiverが通知またはServiceを起動します。処理後、タスクは翌日に再スケジュールする必要があります。
class ReminderReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
val notification = NotificationCompat.Builder(
context, "reminder_channel"
)
.setContentTitle("リマインダー")
.setContentText("タスクを完了する時間です")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
毎日の繰り返しには、次のトリガー時間を計算して setExact を使用します。Intentにフラグを渡して、異なる種類のリマインダーを識別できます。BroadcastReceiverがWAKEUPアクション処理とともにAndroidManifest.xmlに登録されていることを確認してください。
fun scheduleDailyReminder(context: Context, hour: Int, minute: Int) {
val calendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, minute)
set(Calendar.SECOND, 0)
if (before(Calendar.getInstance())) {
add(Calendar.DAY_OF_MONTH, 1)
}
}
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
pendingIntent
)
}
AlarmManager は強力ですが、電力を多く消費するツールです。各WAKEUPアラームはデバイスをスリープモードから解除し、バッテリーを消費します。Googleは正確なアラームの使用を最小限に抑え、Doze Modeへの影響を減らすためにAndroid 6+でsetExactAndAllowWhileIdleを優先することを推奨しています。精度を必要としない定期的なタスクには、PeriodicWorkRequestを使用したWorkManagerを使用してください。デバイスを起動する必要がなく、実行のたびにバッテリーを消耗しません。
AlarmManager のテストには、Android Test FrameworkのTestAlarmManagerを使用します。実際の時間を待たずにアラームトリガーをエミュレートできます。RobolectricはShadowAlarmManagerを提供し、set、setExact、setRepeatingの呼び出しをインターセプトし、強制トリガーやスケジュールされたタスク数の確認のためのメソッドを提供します。BroadcastReceiverの単体テストには、Robolectric.getForegroundScheduler()を使用します。統合テストでアラームトリガーを待機するIdlingResourceを使用したEspressoテストも利用できます。
アプリケーションが正確なタイミングを必要としない定期的なタスクに AlarmManager を使用している場合は、WorkManagerへの移行を検討してください。最小間隔15分のPeriodicWorkRequestがsetRepeatingを置き換えます。一方、WorkManagerは再起動後の実行を保証し、Doze Modeを処理し、SCHEDULE_EXACT_ALARM権限を必要としません。時間に厳しいタスク(午前7時のアラーム)には、AlarmManagerが唯一の正しい選択肢です。最適な戦略は、setAlarmClockを使用するアラームにのみAlarmManagerを使用し、その他のバックグラウンドタスクはすべてWorkManagerに移行することです。
精度を必要としない定期的なタスクには、PeriodicWorkRequestを使用した WorkManager を使用します。正確なタイミングが必要だがスリープモードでのトリガーが重要でないタスクには、WAKEUPなしのsetExactを使用します。そして、必須のウェイクアップが必要なアラームにのみ、setAlarmClockまたはRTC_WAKEUPを使用します。
Android 12+で SCHEDULE_EXACT_ALARM 権限を確認することも重要です。権限が付与されていない場合、setExactは通常のset(不正確)として動作します。確認するにはAlarmManager.canScheduleExactAlarms()を使用します。権限がない場合は、Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)を介してユーザーに設定画面へ移動するよう促すことができます。
AlarmManager の非常に重要な特徴 — デバイスの再起動後、スケジュールされたすべてのアラームはリセットされます。それらを復元するには、Intent.ACTION_BOOT_COMPLETEDを処理するBroadcastReceiverを宣言し、onReceiveメソッドですべてのアクティブなアラームを再スケジュールする必要があります。これがないと、ユーザーは電話の電源をオフにしてオンにした後、すべてのリマインダーを失います。
class BootReceiver : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
if (intent.action ==
Intent.ACTION_BOOT_COMPLETED
) {
val prefs =
context.getSharedPreferences("alarms", 0)
val savedTime =
prefs.getLong("next_alarm", 0L)
if (savedTime > System.currentTimeMillis()) {
scheduleReminder(context, savedTime)
}
}
}
}
実際には、AlarmManager はアラーム時計アプリ、カレンダー、服薬リマインダー、および実行時間がユーザーにとって重要なあらゆるタスクに最適なソリューションです。その他のバックグラウンド作業シナリオでは、WorkManagerまたはJobSchedulerが推奨されます。
AlarmManagerとWorkManagerの選択では、次のルールに従ってください。ユーザーが明示的に午後2時30分にリマインダーを依頼した場合は、setAlarmClockを使用したAlarmManagerを使用します。タスクが「およそ1時間に1回」実行されるべき場合は、PeriodicWorkRequestを使用したWorkManagerの方がエネルギー効率が高く信頼性があります。
よくある質問
どちらのメソッドも正確なトリガーを保証しますが、setAlarmClock はさらにステータスバーにアラームアイコンを表示し、システムにユーザーアラームであることを通知します。Android 6+では、setAlarmClockはDoze Modeから免疫がありますが、setExactは遅延する可能性があります。
再起動後、スケジュールされたすべてのアラームはリセットされます。それらを復元するには、BOOT_COMPLETEDアクションの BroadcastReceiver を登録し、onReceiveですべてのタスクを再スケジュールする必要があります。これがないと、デバイスの電源を入れた後にアラームはトリガーされません。
API 19以降、setRepeating は不正確になりました。システムは電力節約のために間隔をずらす可能性があります。代わりに、手動再スケジュール付きのsetExact、またはより予測可能な動作を提供するPeriodicWorkRequestを使用したWorkManagerを使用してください。
setExact にはSCHEDULE_EXACT_ALARM権限が必要で、ユーザーは設定で許可または取り消すことができます。時計インターフェース表示付きのsetAlarmClockには、ストアからのインストール時に自動的に付与されるUSE_EXACT_ALARMが使用されます。
いいえ、AlarmManager は常にPendingIntentを介して動作します。BroadcastReceiverの場合はPendingIntent.getBroadcast、Serviceの場合はPendingIntent.getService、Activityの場合はPendingIntent.getActivityです。PendingIntentがないと、システムはアプリケーションにイベントを配信できません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。