Scheduling Background Tasks in Android

Joyce Echessa

Periodically your Android application might need to perform a task, such as checking a server for updates. The AlarmManager class can be used to schedule and execute operations that need to occur even if the application isn’t running.

The AlarmManager class enables the scheduling of repeated alarms that will run at set points in the future. The AlarmManager is given a PendingIntent to fire whenever an alarm is scheduled. When an alarm is triggered, the registered Intent is broadcast by the Android system, starting the target application if it’s not already running.

Alarm Type and Precision

There are two major alarm types, Elapsed Realtime and Real Time Clock. The first corresponds to the time since system boot and the second to UTC time. The different alarm types can be set to either wake up the device’s CPU when in sleep mode, or to fire when the device is next awake. Below is a list of the different alarm type variations available.

  • ELAPSED_REALTIME – Fires the pending intent after the specified length of time since device boot. If the device is asleep, it fires when the device is next awake.

  • ELAPSED_REALTIME_WAKEUP – Fires the pending intent after the specified length of time since device boot. It wakes up the device if it is asleep.

  • RTC – Fires the pending intent at a specified time. If the device is asleep, it will not be delivered until the next time the device wakes up.

  • RTC_WAKEUP – Fires the pending intent at a specified time, waking up the device if asleep.

Deciding on the alarm to use depends on the requirements of the task at hand. Time elapsed is suitable for setting alarms that should fire based on the passage of time, for instance regularly checking a server for changes. If you want to run a task dependent on the current locale, then the real time clock will be more suitable.

Note that elapsed time is usually the better choice. If the user changes their time settings or moves to a new locale, the change might cause some unexpected behaviour in the app. If you set a specific time for an app to sync with a server, the server could be overwhelmed when all instances of the app hit at the same time.

Setting up a recurring task

We’ll create a simple application to show the scheduling of tasks. The task we’ll schedule will be the displaying of a message using Toast (A toast provides simple feedback about an operation in a small popup). Code for this project can be found at this Git Repo.

Create a new Android project. For the view, create two buttons that will start and stop the periodic operations.

In res/layout/activity_main.xml

<LinearLayout xmlns:android=""
    tools:context=".MainActivity" >

        android:text="Start Alarm"
        android:onClick="startAlarm" />

        android:text="Cancel Alarm"
        android:onClick="cancelAlarm" />


To receive intents, we’ll set up a broadcast receiver to perform an operation when the alarm is fired. Create a class that inherits from BroadcastReceiver. In the onReceive method, which is called when the BroadcastReceiver is receiving an Intent broadcast, we will set up the code that runs our task.


package com.example.alarmexample;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class AlarmReceiver extends BroadcastReceiver {

    public void onReceive(Context arg0, Intent arg1) {
        // For our recurring task, we'll just display a message
        Toast.makeText(arg0, "I'm running", Toast.LENGTH_SHORT).show();



We then need to register the BroadcastReceiver in the manifest file. Declare the AlarmReceiver in the manifest file.

    <receiver android:name=".AlarmReceiver"></receiver>

To start the alarm we’ll set up the method startAlarm declared in res/layout/activity_main.xml above as the method to run when the Start Alarm button is clicked.

In declare a PendingIntent and an AlarmManager variable. The PendingIntent will be used to set and cancel the alarms.

In include the following instance variables.

private PendingIntent pendingIntent;
private AlarmManager manager;

In onCreate() we create an Intent that references our broadcast receiver class and uses it in our PendingIntent.

protected void onCreate(Bundle savedInstanceState) {

    // Retrieve a PendingIntent that will perform a broadcast
    Intent alarmIntent = new Intent(this, AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);

We then include the method that will set up the recurring alarms. Once set, the alarm will fire every 10 seconds.

public void startAlarm(View view) {
    manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    int interval = 10000;

    manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
    Toast.makeText(this, "Alarm Set", Toast.LENGTH_SHORT).show();

Run the application and by clicking the “Start Alarm” button an “Alarm Set” message will appear, followed by the message “I’m running” every 10 seconds.

We used the setRepeating() method to set up a recurring alarm, but setInexactRepeating() could also be used. With setInexactRepeating() repeating alarms from multiple applications will be syncronized and fired at the same time. This will reduce the number of times the device is woken up, saving battery power. As of Android 4.4, all repeating alarms are inexact.

The setRepeating() method takes four arguments:

  1. type – alarm type, specified by the units of time to use and whether or not it should occur when the device is in sleep mode. Can be ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC, or RTC_WAKEUP.

  2. triggerAtMillis – time in milliseconds that the alarm should first fire.

  3. intervalMillis – interval in milliseconds between subsequent repeats of the alarm.

  4. operation – Action to perform when the alarm fires

Next, we’ll set up the cancelAlarm() method to stop the alarms. Include the method below in

public void cancelAlarm(View view) {
    if (manager != null) {
        Toast.makeText(this, "Alarm Canceled", Toast.LENGTH_SHORT).show();

Before running the application again, Force Stop or uninstall the app in your device or simulator. If you don’t, the previous alarm schedule will still be running. Run the application and the scheduled alarm can be stopped.

The above is a simple example showing how to use the AlarmManager to set up and cancel alarms. I use the same AlarmManager object to start and stop the alarm. This of course will not persist when the app is exited, so for a real app instead of only canceling the alarm when manager is not null (which it will be if the app was exited, no matter if the alarm is running or not), you should cancel the alarm with an equivalent PendingIntent to the one used setting it. For example you could do this instead.

Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Toast.makeText(this, "Alarm Canceled", Toast.LENGTH_SHORT).show();


We have looked at how the AlarmManager can be used to schedule periodic tasks. The AlarmManager is best used for tasks that need to run even when the application isn’t open. For normal timing operations that need to run during application use (ticks, timeouts, etc), it is more efficient to use the postDelayed() and postAtTime() methods of a Handler. The AlarmManager requires too much overhead to justify it being used this way.

CSS Master, 3rd Edition