AlarmManager is a system service in Android that allows applications to execute tasks at a specified time, even if the application is not running or the device is in sleep mode. Unlike JobScheduler or WorkManager, AlarmManager guarantees triggering accuracy, making it indispensable for alarms, calendar reminders, and time-critical tasks. According to Android Developers, 2026, starting from Android 4.4, setRepeating behaves as an inexact repeat, and precise alarms require setExact or setAlarmClock.
Key Takeaways
AlarmManager is an Android system service that provides an API for scheduling tasks with precise or approximate execution time. It has existed since the first version of Android and remains the only reliable way to execute code at a specified moment, regardless of the application and device state.
The working principle is straightforward: the application sends the system a PendingIntent with the scheduled time. When the specified time arrives, the system sends the Intent to a registered BroadcastReceiver or starts a Service. Even if the device was in sleep mode, WakeLock allows the processor to wake up and process the event.
The main application area of AlarmManager is tasks requiring precise timing: alarms, calendar reminders, launching long-running operations at a specific hour. For tasks where precision is not critical (daily synchronization), Google recommends WorkManager or JobScheduler as they are more energy-efficient.
AlarmManager receives a PendingIntent and a trigger time from the application. The system saves this request in its internal scheduler and wakes up the processor at the specified time to deliver the Intent. The developer must register a BroadcastReceiver in advance to handle this Intent.
AlarmManager supports 4 alarm types: ELAPSED_REALTIME (time since boot, does not wake), RTC (real time, does not wake), ELAPSED_REALTIME_WAKEUP (time since boot, wakes the device), and RTC_WAKEUP (real time, wakes). WAKEUP versions are necessary if the task must execute even when the device is sleeping.
| Type | Time | Wakes | Example |
|---|---|---|---|
| ELAPSED_REALTIME | since boot | no | uptime timer |
| RTC | Unix timestamp | no | logging |
| ELAPSED_REALTIME_WAKEUP | since boot | yes | periodic task |
| RTC_WAKEUP | Unix timestamp | yes | alarm clock |
Starting from Android 12 (API 31), using precise alarms (setExact) requires the SCHEDULE_EXACT_ALARM permission. The user can revoke it through settings. For applications that need a precise alarm with display (e.g., clock apps), USE_EXACT_ALARM is used, which is granted upon installation.
AlarmManager provides three main methods for scheduling tasks. The choice of method determines triggering accuracy and impact on device power consumption.
set — the basic method for a one-time inexact trigger. The system may shift the time by up to a few minutes to group with other events. Suitable for tasks where precision is not critical: reminders to open the application.
setRepeating — a method for periodic repetitions. Since Android 4.4 (API 19), setRepeating has become inexact — intervals may vary. The system no longer guarantees a constant period. Instead of setRepeating, it is recommended to use setExact with rescheduling or WorkManager with PeriodicWorkRequest.
setExact — a method for precise one-time triggering. The system wakes the device as close to the specified time as possible. setAlarmClock is a special case of setExact that also shows an alarm icon in the status bar and has the highest priority among all alarm types.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Precise one-time alarm
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
A typical scenario is creating a daily reminder at a specific time. RTC_WAKEUP with setExact is used for this purpose. When triggered, the BroadcastReceiver launches a notification or Service. After processing, the task must be rescheduled for the next day.
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("Reminder")
.setContentText("Time to complete the task")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
For daily repetition, setExact is used with calculation of the next trigger time. Flags can be passed in the Intent to identify different types of reminders. Make sure the BroadcastReceiver is registered in AndroidManifest.xml with WAKEUP action handling.
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 is a powerful but power-hungry tool. Each WAKEUP alarm brings the device out of sleep mode, consuming battery charge. Google recommends minimizing the use of precise alarms and preferring setExactAndAllowWhileIdle on Android 6+ to reduce impact on Doze Mode. For periodic tasks without precision requirements, use WorkManager with PeriodicWorkRequest, which does not require waking the device and does not drain battery on each execution.
For testing AlarmManager, use TestAlarmManager from the Android Test Framework. It allows emulating alarm triggers without waiting for real time. Robolectric provides ShadowAlarmManager, which intercepts set, setExact, and setRepeating calls, providing methods for forced triggering and checking the count of scheduled tasks. For Unit tests of BroadcastReceiver, use Robolectric.getForegroundScheduler(). Espresso tests with IdlingResource that waits for alarm triggering in integration tests are also available.
If your application uses AlarmManager for periodic tasks that do not require precise timing, consider migrating to WorkManager. PeriodicWorkRequest with a minimum interval of 15 minutes replaces setRepeating, while WorkManager guarantees execution after reboot, handles Doze Mode, and does not require the SCHEDULE_EXACT_ALARM permission. For time-critical tasks (alarm at 7 AM), AlarmManager remains the only correct choice. The optimal strategy is to use AlarmManager only for alarms with setAlarmClock, and move all other background tasks to WorkManager.
For periodic tasks without precision requirements, use WorkManager with PeriodicWorkRequest. For tasks with precise timing but not critical to trigger in sleep mode — use setExact without WAKEUP. And only for alarms with mandatory wakeup — use setAlarmClock or RTC_WAKEUP.
It is also important to check for the SCHEDULE_EXACT_ALARM permission on Android 12+. If the permission is not granted, setExact will work like regular set (inexact). Use AlarmManager.canScheduleExactAlarms() to check. If the permission is missing, you can prompt the user to go to settings via Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).
A critically important feature of AlarmManager — all scheduled alarms are reset after device reboot. To restore them, you must declare a BroadcastReceiver handling Intent.ACTION_BOOT_COMPLETED and reschedule all active alarms in the onReceive method. Without this, the user will lose all reminders after turning the phone off and on.
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)
}
}
}
}
In practice, AlarmManager remains the best solution for alarm clock applications, calendars, medication reminders, and any tasks where execution time is critical for the user. For all other background work scenarios, WorkManager or JobScheduler are preferred.
When choosing between AlarmManager and WorkManager, follow this rule: if the user explicitly asked to remind at 2:30 PM — use AlarmManager with setAlarmClock. If the task should execute “approximately once an hour” — WorkManager with PeriodicWorkRequest will be more energy-efficient and reliable.
Frequently Asked Questions
Both methods guarantee precise triggering, but setAlarmClock additionally shows an alarm icon in the status bar and informs the system that it is a user alarm. On Android 6+, setAlarmClock has immunity from Doze Mode, while setExact may be delayed.
After a reboot, all scheduled alarms are reset. To restore them, you must register a BroadcastReceiver for the BOOT_COMPLETED action and reschedule all tasks in onReceive. Without this, no alarm will trigger after the device turns on.
Since API 19, setRepeating has become inexact — the system may shift intervals for power saving. Instead, use setExact with manual rescheduling or WorkManager with PeriodicWorkRequest, which provides more predictable behavior.
For setExact, the SCHEDULE_EXACT_ALARM permission is required, which the user can grant or revoke in settings. For setAlarmClock with clock interface display, USE_EXACT_ALARM is used, granted automatically upon installation from the store.
No, AlarmManager always works through PendingIntent. This can be PendingIntent.getBroadcast for BroadcastReceiver, PendingIntent.getService for Service, or PendingIntent.getActivity for Activity. Without PendingIntent, the system cannot deliver the event to the application.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also