While writing an application, need arises to schedule execution of code in future. You may require AlarmManager to schedule your work at a specified time. AlarmManager accesses to system alarm and schedules the execution of code even when the application is not running.

Project Information:  Meta-information about the project.

Platform Version : Android API Level 10.
IDE : Eclipse Helios Service Release 2
Emulator: Android 4.1

Prerequisite: Preliminary knowledge of Android application framework, and Intent Broadcast receiver.

AlarmManager:

AlarmManager has access to the system alarm services. With the help of AlarmManager you can schedule execution of code in future. AlarmManager object can’t instantiate directly however it can be retrieved by calling Context.getSystemService(Context.ALARM_SERVICE). AlarmManager is always registered with intent. When an alarm goes off, the Intent which has been registered with AlarmManager, is broadcasted by the system automatically. This intent starts the target application if it is not  running. It is recommended to use AlarmManager when you want your application code to be run at a specific time, even if your application is not currently running. For other timing operation handler should be used because it is easy to use. Handler is covered in other tutorial.

Method Description
set() Schedules an alarm for one time.
setInexactRepeating() Schedules an alarm with inexact repeating. Trigger time doesn’t follow any strict restriction.
setRepeating() Schedules an alarm with exact repeating time.
setTime() Sets the system’s wall clock time.
setTimeZone() Sets the system’s default time zone.

Check out the AlarmManager documention for more info.

In this tutorial let’s learn to create one-time timer and the repeating timer, and also to cancel the repeating timer. Here timer and alarm have been used interchangeably, but in this tutorial context both of them have the same meaning.

Example Code:

Let’s create three buttons start repeating timer, cancel repeating timer and one-time timer in the layout file. These buttons are attached with methods i.e startRepeatingTimer, cancelRepeatingTimer and onetimeTimer respecitively. These methods will be defined in the Activity class. The layout file is shown below(activity_alarm_manager.xml).

 <linearlayout android:layout_height="match_parent" 
    android:layout_width="match_parent" android:orientation="vertical" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools">

    <button android:id="@+id/btStart" android:layout_height="wrap_content" 
      android:layout_width="match_parent" android:onclick="startRepeatingTimer" 
      android:padding="@dimen/padding_medium" android:text="@string/btStart"   
      tools:context=".WidgetAlarmManagerActivity"/>
    <button android:id="@+id/btCancel" android:layout_height="wrap_content" 
      android:layout_width="match_parent" android:onclick="cancelRepeatingTimer"  
      android:padding="@dimen/padding_medium" android:text="@string/btCancel" 
      tools:context=".WidgetAlarmManagerActivity"/>
     <button android:id="@+id/btOneTime" android:layout_height="wrap_content" 
     android:layout_width="match_parent" android:onclick="onetimeTimer" 
     android:padding="@dimen/padding_medium" android:text="@string/btOneTime"   
     tools:context=".WidgetAlarmManagerActivity"/>
   </linearlayout>

We are going to define the BroadcastReciever which handles the intent registered with AlarmManager. In the given class onReceive() method has been defined. This method gets invoked as soon as intent is received. Once we receive the intent we try to get the extra parameter associated with this intent. This extra parameter is user-defined i.e ONE_TIME, basically indicates whether this intent was associated with one-time timer or the repeating one. Once the ONE_TIME parameter value has been extracted, Toast message is  displayed accordingly. Helper methods have also been defined, which can be used from other places with the help of objects i.e setAlarm(), cancelAlarm() and onetimeTimer() methods. These methods can also be defined somewhere else to  do operation on the timer i.e set, cancel, etc. To keep this tutorial simple, we have defined it in BroadcastReceiver.


setAlarm(): This method sets the repeating alarm by use of setRepeating() method. setRepeating() method needs four arguments:

  1. type of alarm, 
  2. trigger time: set it to the current time
  3. interval in milliseconds: in this example we are passing 5 seconds ( 1000 * 5 milliseconds)
  4. pending intent: It will get registered with this alarm. When the alarm gets triggered the pendingIntent will be broadcasted.

cancelAlarm(): This method cancels the previously registered alarm by calling cancel() method. cancel() method takes pendingIntent as an argument. The pendingIntent should be matching one, only then the cancel() method can remove the alarm from the system.

onetimeTimer(): This method creates an one-time alarm. This can be achieved by calling set() method. set() method takes three arguments:

  1. type of alarm
  2. trigger time 
  3. pending intent
package com.rakesh.alarmmanagerexample;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;

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

public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {

 final public static String ONE_TIME = "onetime";

 @Override
 public void onReceive(Context context, Intent intent) {
   PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
         //Acquire the lock
         wl.acquire();

         //You can do the processing here.
         Bundle extras = intent.getExtras();
         StringBuilder msgStr = new StringBuilder();
         
         if(extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)){
          //Make sure this intent has been sent by the one-time timer button.
          msgStr.append("One time Timer : ");
         }
         Format formatter = new SimpleDateFormat("hh:mm:ss a");
         msgStr.append(formatter.format(new Date()));

         Toast.makeText(context, msgStr, Toast.LENGTH_LONG).show();
         
         //Release the lock
         wl.release();
 }

 public void SetAlarm(Context context)
    {
        AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
        intent.putExtra(ONE_TIME, Boolean.FALSE);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
        //After after 5 seconds
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 5 , pi); 
    }

    public void CancelAlarm(Context context)
    {
        Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(sender);
    }

    public void setOnetimeTimer(Context context){
     AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
        intent.putExtra(ONE_TIME, Boolean.TRUE);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);
    }
}

Given below is the manifest file. Here, WAKE_LOCK permission is required because the wake lock is being used while processing in onReceive() method present in AlarmManagerBroadcastReceiver class. AlarmManagerBroadcastReceiver has been registered as broadcast receiver.

<manifest android:versioncode="1" android:versionname="1.0" 
       package="com.rakesh.alarmmanagerexample" 
       xmlns:android="http://schemas.android.com/apk/res/android">

   <uses-sdk android:minsdkversion="10" android:targetsdkversion="15"/>
   <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <application android:icon="@drawable/ic_launcher" 
       android:label="@string/app_name" android:theme="@style/AppTheme">
        <activity android:label="@string/title_activity_alarm_manager" 
           android:name="com.rakesh.alarmmanagerexample.AlarmManagerActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>
        <receiver android:name="com.rakesh.alarmmanagerexample.AlarmManagerBroadcastReceiver">
        </receiver>
    </application>
</manifest>

Now let’s define the activity class which defines some methods. These methods are going to handle the button clicks. Here in this class we create an instance of AlarmManagerBroadcastReciever which will help us to access setAlarm(), cancelAlarm() and setOnetime(). Rest of the code is easy to understand.

package com.rakesh.alarmmanagerexample;

import com.rakesh.alarmmanagerexample.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import android.support.v4.app.NavUtils;

public class AlarmManagerActivity extends Activity {

 private AlarmManagerBroadcastReceiver alarm;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alarm_manager);
        alarm = new AlarmManagerBroadcastReceiver();
    }
    
    @Override
 protected void onStart() {
  super.onStart();
 }

    public void startRepeatingTimer(View view) {
     Context context = this.getApplicationContext();
     if(alarm != null){
      alarm.SetAlarm(context);
     }else{
      Toast.makeText(context, "Alarm is null", Toast.LENGTH_SHORT).show();
     }
    }
    
    public void cancelRepeatingTimer(View view){
     Context context = this.getApplicationContext();
     if(alarm != null){
      alarm.CancelAlarm(context);
     }else{
      Toast.makeText(context, "Alarm is null", Toast.LENGTH_SHORT).show();
     }
    }
    
    public void onetimeTimer(View view){
     Context context = this.getApplicationContext();
     if(alarm != null){
      alarm.setOnetimeTimer(context);
     }else{
      Toast.makeText(context, "Alarm is null", Toast.LENGTH_SHORT).show();
     }
    }
    
 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_widget_alarm_manager, menu);
        return true;
    }
}

Once you are done with the coding, just execute the project and you will find the similar kind of application running in your emulator.

AlarmManagerExample is installed in application list AlarmManager:Onetime timer is triggered

Please download AlarmManagerExample code, if you need reference code.
Your valuable comments are always welcomed. It will help to improve my post and understanding.

“By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest.”
By : Confucius

,
Trackback

16 comments untill now

  1. Khobaib Chowdhury @ 2012-08-16 14:01

    Is there any way to use AlarmManager to activate an alarm for a specific period of time? I have start-time and end-time values stored in the database. I want to start an alarm at start-time that will make the device silent and alarm should end at end-time when the device volume will be normal again.

    One way is set alarm at start-time & then set another alarm at end-time. But the problem is the time period may overlap that will need additional logic to be implemented if I go with 2 different alarms(one at start-time, another at end-time). Is there any procedure in Android to cope with this situation? Or implementing logic is the only way to overcome this issue?

  2. @Khobaib
    I would suggest you to use the handler (http://developer.android.com/reference/android/os/Handler.html). Otherwise you can use the setRepeating() and cancel() methods present in the AlarmManager.

  3. Khobaib Chowdhury @ 2012-08-16 16:18

    Thanx for the reply. I have checked on handler earlier but yet don’t understand how to implement it in my code.

    Basically, in my app, I have several time-slots stored in the database. As user inputs them, so they may/may not overlap. I am already using setRepeating() method to handle if “Alarm Repeat on weekdays” option is selected. My code is fine if the time-slots for silent mode aren’t overlapped. I set an alarm at the start -time of each time-slot to make phone silent, then set another one at the end-time of time-slot to make phone volume normal again.

    But the problem rises when the overlapping occurs. You say it can be done with Handler? Can you give me some details? or link of some tutorials that will guide me?

    BTW, your tutorial is great. Thank you again.

  4. Well in this case you have to develop your own logic to check the overlapping and handle it. Sorry but I don’t know whether such kind of cases can be handled in Android APIs.

  5. how can you please give idea how set alarms to fire at different interval of times. for example i want the alarm to fir tomorrow next alarm will on next month some other date like so.is there any way to achieve this kind of functionality.

  6. Why you have used

    PowerManager pm = (PowerManager) context .getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, “YOUR TAG”);

    is it really reqired. I checked by removing this code and its working fine. With this code unnecessarily on receive is called. please explain

  7. What if I reset the device? Is there a way I can reset on device wake?

  8. ClayMoure @ 2013-04-04 05:10

    Could you please give me an idea on how to create an alarm that automatically sets when the application starts to run without using the alarm button that i have created?

  9. @ ClayMoure
    You can simply put the code of starting the Alarm in the onCreate() method

  10. Jason Hamm @ 2013-04-27 04:14

    Great tutorial. Thanks for the help. Why did you use super.onStart() in the Activity class? Just trying to understand all of the code.

  11. Noumenon72 @ 2013-05-04 08:37

    It is so awesome to have code I can just copy and paste and have it work. I only need a one time alarm and now I don’t have to write the whole class myself.

  12. Thanks a lot. It helps me a lot. I want to just ask you, If I want to pop up toast after 24 hr. at particular time, what do I do for that?

    Thanks in Advance.

  13. @Shailesh Vishwase You can put the toast message in BroadcastReceiver’s onReceive() method. You can associate this broadcast receiver object with PendingInent() and register this PendingIntent with one time timer as shown above.

  14. activity_main.xml throws errors like “No resource found that matches the given name (at ‘padding’ with value ‘@dimen/
    padding_medium’)”… Any suggestion.. Thanks

  15. Thanks for this tutorial it is very help full for creating alarms list. Is there an another tutorial in with SQLite used to store data of different alarms?

  16. Hi,

    Thanks for the nice tutorial. I’ve used the repeatingTimer to take pictures automatically every a given amount of time (e.g., 30 sec.). It works ok but when the phone goes in sleep mode the application is stopped. Is there a way to wakeup the phone?

Add your comment now