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.

Free Chapter! HTML5 & CSS3 for the Real World

Get a free chapter of SitePoint's new book, the second edition of our popular HTML5 & CSS3 for the Real World and receive updates on our latest offers.

  • Chris Ward

    Thanks for your comments Mutinda, more from Joyce very soon!

  • Joyce Echessa

    Thanks for that. Yeah, you are right, it is a good practice to use the full qualified names, especially as projects get bigger.

  • Vikram Tiwari

    Hello Joyce,
    A small question: In a hypothetical scenario where I have multiple applications installed on an android device and these individual applications have created their respective RTC_WAKEUP alarms. Since these applications are not running when alarms are fired, I was wondering if Android gives a way of looking up (for example under Settings..) what all alarms are pending for what applications?

    How do you typically troubleshoot such applications?

    Thanks in advance,

    • Joyce Echessa

      Hi Vikram,
      Do you mean being able to check the set alarms (and/or modify them) as an end user?

      As an end user, you are restricted by what the app developer allows you to control and see. Lets say, there is an app that has to sync with a server N number of times a day or after N number of minutes. This is usually not information made available to users, but some applications offer the user an option of cancelling automatic updates, thus stopping the alarm from running. But I have never seen an app that offers this information to users.

      So, to answer your question, if there is a way of checking all the set alarms of all applications installed on your device. No, there isn’t (none that I am aware of at least).

      I hope that answers your question. If it doesn’t let me know.

  • flutin

    great demo!
    only thing i would add is maybe screenshots.

  • ElimiNathan

    Using CPU power drains the battery, waking up a device every 10 seconds is keeping the CPU cycle alive constantly, hence battery drain. What logic does your Service run ? That could be a contributing factor on top of the 10 second alarm

  • Joyce Echessa

    lol I pictured Liam Neeson (Taken) saying that first part.

    I haven’t tried this, so I’m not sure if it’ll work, but this is how I would go about it:

    I would persist the alarm count in memory. So it would start at 0 and every time the alarm fires, I would increment the number. If it gets to 20, cancel the alarm.
    I would do this in the onReceive() method in the BroadcastReceiver since this is called when the alarm fires.

  • Shashank Gudipati

    Hi Joyce,
    I have used alarm manager to start a service that builds a notification to user. However when I force close my app, I am getting ‘Unfortunately your app stopped working’. My main activity (onCreate) has time and date picker that are used to set Alarmmanager, which in turn is used to invoke a Alarmreceiver thru a pending intent. I am not sure why app is not able to close cleanly ? Is it because alarmmanager is still running in background or NotificationService might be causing some problem ?

    Thanks in advance!!

    • Anastasia Shuba

      Please post your logcat output and others might be able to help you :)

  • Anastasia Shuba

    Thank you! I’ve been experimenting with Handlers, Executors, all to no avail. This was what I needed!

  • Ankur Kashyap

    Hey nice article Joyce.Helped me a lot.
    But i am having a problem. Above code doesn’t work after rebooting the system. Should i add intent-filter “receive_boot_completed” in my receiver? And if i add it, how can i start the same AlarmManager intent? Please provide me little code snippet for my problem. Thank you.

  • ranjithstar256

    hi joyce thanks for the post and clear explanation :) Can i have the working example code i mean to download it as a zip file? thanks :)