Scheduling and repeating alarms are generally used as a local reminder to notify user about some event. For example, a mobile live TV streaming application can use local reminder to notify users when a specific program starts. Note that, this is different form Server push notification, mainly because it is purely managed by mobile client.

1. AlarmManager in Android

AlarmManager is a class in Android allows you to access device system alarm service. Using AlarmManager, you can schedule to execute certain piece of code a particular time. Let us dive into details of AlarmManager specifics:

  • AlarmManager runs outside the lifetime of your application. Once an alarm is scheduled, it will invoke even when your application is not running or in sleep mode.
  • An scheduled alarm will execute unless it is stopped explicitly by calling cancel() method, or until device reboots.
  • All scheduled alarms will be stopped when device reboots. This means, you need to re-schedule them explicitly when device boot completes.
  • AlarmManger fires an Intent at given intervals. This can be used along with broadcast receivers to start a service to perform network operations.
  • AlarmManager is different form java Timer and TimerTask.
Note, You need to take extra care while working with AlarmManager. A poorly designed AlarmManager can drain your device battery.

2. Setting Repeat Alarm

Android supports two clock types for alarm service; elapsed real time and real time clock (RTC). Elapsed real time uses the time since device last booted. Real time clock (RTC) uses UTC time for alarm service clock. RTC is most commonly used for setting alarm service in android. The following example, using RTC to schedule alarm.

The application using a single activity containing three buttons. One button is for starting an alarm service, another to cancel scheduled alarm. The third button is to start the alarm at specified calendar time. For example, if you have set a time for your birthday reminder. It will invoke at 10:30 PM and will repeat on every 30 mins.

Let us have a look into our activity layout file (my_activity.xml)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MyActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:text="@string/hint"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/startAlarm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/textView"
        android:layout_marginBottom="20dp"
        android:text="Start Alarm Service" />

    <Button
        android:id="@+id/stopAlarm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/startAlarm"
        android:layout_marginBottom="20dp"
        android:text="Stop Alarm" />


    <Button
        android:id="@+id/stopAlarmAt10"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/stopAlarm"
        android:text="Stop Alarm at 10:30" />

</RelativeLayout>

AlarmManager Example in Android

3. Defining Alarm BroadcastReceiver

In this example, we are associating alarm service with broadcast receiver. Alarm service will invoke this receiver on scheduled time. For the sake of simplicity we are just showing an toast to user for each time the alarm is invoked. You may write your logic to start a service or download task.

Note: If your alarm has to perform network task, then start a download service inside onRecieve() method of your alarm broadcast.
package com.javatechig.alarmservice;

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

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        // For our recurring task, we'll just display a message
        Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
    }
}

4. Schedule & Cancel Alarm

In the above two steps we have defined activity layout and alarm broadcast receiver. Let us have a look into MainActivity.java file. Inside MyActivity class, we have defined three simple methods start(), stop() and startAt10(). The start() method schedule the alarm, cancel() method cancel the scheduled alarm, and startAt!0() method will start the alarm at 10:30 PM with a fixed 20 minutes interval.

package com.javatechig.alarmservice;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.util.Calendar;

public class MyActivity extends Activity {

    private PendingIntent pendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

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

        findViewById(R.id.startAlarm).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                start();
            }
        });

        findViewById(R.id.stopAlarm).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cancel();
            }
        });

        findViewById(R.id.stopAlarmAt10).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAt10();
            }
        });
    }

    public void start() {
        AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        int interval = 8000;

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

    public void cancel() {
        AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        manager.cancel(pendingIntent);
        Toast.makeText(this, "Alarm Canceled", Toast.LENGTH_SHORT).show();
    }

    public void startAt10() {
        AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        int interval = 1000 * 60 * 20;

        /* Set the alarm to start at 10:30 AM */
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 10);
        calendar.set(Calendar.MINUTE, 30);

        /* Repeating on every 20 minutes interval */
        manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                1000 * 60 * 20, pendingIntent);
    }

}

5. Re-Starting Alarm Service on Device Reboot

As discussed earlier, once an alarm service is started, it execute until it is explicitly stopped or until device reboots. This means that, if your device is restarted then your alarm is stopped. To avoid such situation, you have to restart your alarm service as soon as device boot completes. Below code snippet will help you to start alarm service once device reboots.

package com.javatechig.alarmservice;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

/**
 * @author Nilanchala
 *         <p/>
 *         Broadcast reciever, starts when the device gets starts.
 *         Start your repeating alarm here.
 */
public class DeviceBootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
            /* Setting the alarm here */
            Intent alarmIntent = new Intent(context, AlarmReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);

            AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            int interval = 8000;
            manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

            Toast.makeText(context, "Alarm Set", Toast.LENGTH_SHORT).show();
        }
    }
}

6. Declaring Application Manifest

To start your alarm on device reboot, you have to register your above declared DeviceBootReciever class in your application manifest. This also need android.permission.RECEIVE_BOOT_COMPLETED

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javatechig.alarmservice" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <!-- Permission to start Alarm on device reboot -->
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

        <activity
            android:name=".MyActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".AlarmReceiver">
	      <intent-filter>
	           <action android:name="android.intent.action.BOOT_COMPLETED"/>
	      </intent-filter>
        </receiver>

        <!-- Will not be called unless the application explicitly enables it -->
        <receiver android:name=".DeviceBootReceiver"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>
</manifest>

7. Download Source Code

Download Complete source code from GitHub

This article is about: Service,

Nilanchala

A blogger, a bit of tech freak and a software developer. He is a thought leader in the fusion of design and mobile technologies. He is the author of Xamarin Mobile Application Development for Android Book (goo.gl/qUZ0XV3), DZone MVB and founder of stacktips.com.

Join The Discussion

Please note: We reserve the right to delete comments that contains snarky remarks, offensive or off-topic. To know more read our comments policy.
  • Thanks ShivOm Bhatt.

  • Arnaldo Raposo

    Hi
    Don’t know why but when I reboot the device the alarm only run once?

  • Sami

    Thank you so much. It was simple and fair enough.

  • Christian C

    Very Good, thank you!!

  • Good Tutorial Thanks

  • Cesar Mosta

    This tutorial is really good, but I had a problem with the reboot, I included the “” in the manifest, but, when I restart the device, the alarm doesn’t wake up, untill I start it from the activity

  • anant sophia

    thanx, good tutorial!

  • Nilanchala Panigrahy

    Thanks for pointing out Kiran.

    Have updated the example code.

    • paul

      Hi Nilanchala… Please i need your help in debugging my alarm app. the app is running well but i have one challenge that am struggling to fix. after onboot receiver is completed the alarm fires up (Rings) even if its not the right time to get fired. how can i stop this. thanks

    • Dmitry

      Thank you, good article! BTW, on Github AlarmReceiver is also missed in AndroidManifest.xml.

  • Nilanchala Panigrahy

    Do you see any error? It is difficult to trace the problem without the code.

    Share me the code..

  • Elixtor

    I had to move the tag before the tag and add , then work fine, thank you for the example!

  • Not the exact solution you looking at. But this will certainly give you an idea of how to do this.

    //Alarm will appear 2 hours after current time
    long time = 7200000;
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.MINUTE, time);

    int REQUEST_CODE = 1004;
    Intent intent = new Intent(ctx, AlarmReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
    am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);

  • Broadcast receivers enable applications to receive intents that are broadcast by the system or by other applications, even when other components of the application are not running.

    There are two ways to make a broadcast receiver known to the system: One is declare it in the manifest file with this element. The other is to create the receiver dynamically in code and register it with the Context.registerReceiver() method. See the BroadcastReceiver class description for more on dynamically created receivers.

  • Alon

    You probably need to register the Receiver. Try to add the below to your manifest

  • Haleem

    have u tried before u post this article?

  • you must have a device or emulator. You can download Genymotion.

    http://stacktips.com/android/fastest-android-emulator-for-testing-genymotion