alarm manager
android development
scheduling tasks
mobile app programming
android examples

Alarm Manager Example

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

AlarmManager lets an Android app ask the system to trigger work at a future time, even if the app is not currently in the foreground. It is useful for clock-style reminders, calendar alerts, and other time-based events, but it should be used deliberately because exact alarms affect battery life and modern Android places tighter limits on background execution.

Choose AlarmManager for Time-Based Triggers

AlarmManager is a good fit when the user expects something to happen at or near a particular time. Typical examples are:

  • a reminder notification at 8:00 AM
  • an alarm clock
  • a calendar alert

If the work is flexible and can run later, WorkManager is often the better choice. AlarmManager is for time-sensitive triggers, not general background processing.

Basic Components

A common pattern has three parts:

  • a BroadcastReceiver that runs when the alarm fires
  • a PendingIntent pointing to that receiver
  • a scheduling call made through the AlarmManager system service

Here is a basic receiver.

kotlin
1import android.content.BroadcastReceiver
2import android.content.Context
3import android.content.Intent
4import android.widget.Toast
5
6class ReminderReceiver : BroadcastReceiver() {
7    override fun onReceive(context: Context, intent: Intent) {
8        Toast.makeText(context, "Alarm fired", Toast.LENGTH_SHORT).show()
9    }
10}

You also need to declare the receiver in the manifest.

xml
<receiver android:name=".ReminderReceiver" />

Schedule a One-Time Alarm

The next step is to build a PendingIntent and register the trigger time.

kotlin
1import android.app.AlarmManager
2import android.app.PendingIntent
3import android.content.Context
4import android.content.Intent
5
6fun scheduleReminder(context: Context, triggerAtMillis: Long) {
7    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
8
9    val intent = Intent(context, ReminderReceiver::class.java)
10    val pendingIntent = PendingIntent.getBroadcast(
11        context,
12        1001,
13        intent,
14        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
15    )
16
17    alarmManager.setExactAndAllowWhileIdle(
18        AlarmManager.RTC_WAKEUP,
19        triggerAtMillis,
20        pendingIntent
21    )
22}

This schedules an exact wall-clock alarm that can wake the device if necessary. Use exact alarms only when the user experience truly requires that level of timing precision.

Understand the Alarm Type

The first parameter controls what clock the alarm uses.

  • 'RTC_WAKEUP: wall-clock time and may wake the device'
  • 'RTC: wall-clock time without waking the device'
  • 'ELAPSED_REALTIME_WAKEUP: time since boot and may wake the device'
  • 'ELAPSED_REALTIME: time since boot without waking the device'

If you are scheduling a real date and time like "tomorrow at 9:00 AM," RTC_WAKEUP or RTC is usually the relevant choice. If you only need "10 minutes from now," elapsed real time is often safer because it is not tied to wall-clock changes.

Repeating Alarms Need Care

Android also supports repeating alarms, but repeated exact wakeups are expensive. In practice, many apps schedule the next one-time alarm each time the current alarm fires instead of relying on a rigid repeating schedule.

That pattern gives you more control and works better with modern background restrictions.

kotlin
val tenMinutesFromNow = System.currentTimeMillis() + 10 * 60 * 1000L
scheduleReminder(context, tenMinutesFromNow)

If your job is periodic but not exact, do not force AlarmManager into acting like a batch worker. Use the tool that matches the requirement.

Cancellation Matters

A schedule API is incomplete without cancellation. To cancel an existing alarm, rebuild the same PendingIntent and call cancel().

kotlin
1fun cancelReminder(context: Context) {
2    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
3    val intent = Intent(context, ReminderReceiver::class.java)
4    val pendingIntent = PendingIntent.getBroadcast(
5        context,
6        1001,
7        intent,
8        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
9    )
10
11    alarmManager.cancel(pendingIntent)
12}

The request code, target receiver, and intent identity must match the original alarm.

Common Pitfalls

The most common mistake is using AlarmManager for work that does not need time precision. That wastes battery and makes the app harder to maintain.

Another mistake is forgetting that background execution restrictions affect what happens after the alarm fires. The alarm may trigger, but long-running background work still needs the right execution model.

A third issue is building a different PendingIntent when trying to cancel or replace an alarm. If the identity differs, the old alarm remains scheduled.

Finally, exact alarms should be reserved for user-visible scenarios. If the app only needs eventual execution, a more defer-friendly scheduler is usually the right answer.

Summary

  • Use AlarmManager when the app needs a time-based trigger, not general background work.
  • A typical setup uses a BroadcastReceiver, a PendingIntent, and an AlarmManager call.
  • Choose the alarm clock type based on whether you care about wall-clock time or elapsed time since boot.
  • Exact alarms are powerful but should be used sparingly.
  • Always implement cancellation with a matching PendingIntent.
  • For flexible background work, consider WorkManager instead of forcing everything through alarms.

Course illustration
Course illustration

All Rights Reserved.