Using AlarmManager in Android

In this blog post, I would like to explain how to use AlarmManager to schedule your work at a specified time or repeating at specific time. AlarmManager accesses to system alarm and schedules the execution of code even when the application is not running.

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).

Method Description
cancel() Remove any alarms with a matching Intent.
set() Schedules an alarm for one time.
setExact() Schedule an alarm to be delivered precisely at the stated 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 notification from background, repeating it and also to cancel the repeatation.

First, create a activity_main.xml XML file, and add the following code:

<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>

Then, create a AlarmManagerBroadcastReceiver.java, and add folowing code:


import java.util.Calendar;

import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
 
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
 
    final static int ALARM_ID = 1;//use unique id while creating multiple alarms
  static AlarmManager alarmManager;
 @Override
 public void onReceive(Context context, Intent intent) {
 //we are starting an service here
     Intent service1 = new Intent(context, MyService.class);
     context.startService(service1);
 }
 
//setAlarm method to start alarm for repeating
 public void SetAlarm(Context context)
    {
     Intent myIntent = new Intent(context, AlarmManagerBroadcastReceiver.class);
     PendingIntent pendingIntent =
 PendingIntent.getBroadcast(context, ALARM_ID, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
     alarmManager =
 (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
     Calendar calendar = Calendar.getInstance();
     calendar.setTimeInMillis(System.currentTimeMillis());
     long interval = 5 * 60 * 1000;
     alarmManager.cancel(pendingIntent);
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
 calendar.getTimeInMillis(), interval, pendingIntent);
    }
 
//CancelAlarm method to stop any previous alarms
    public void CancelAlarm(Context context)
    {
        Intent myIntent =
 new Intent(context, AlarmManagerBroadcastReceiver.class);
        PendingIntent pendingIntent =
 PendingIntent.getBroadcast(context,ALARM_ID, myIntent, 0);         
 alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         alarmManager.cancel(pendingIntent);
     }  
//setOnetimeTimer method to set one time alarm for 1 hour from when the alarm was created    
public void setOnetimeTimer(Context context){
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
         PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(System.currentTimeMillis());
         calendar.add(Calendar.HOUR_OF_DAY, 1); //1 hour from when the alarm was created
        calendar.add(Calendar.MINUTE, 0);
         calendar.add(Calendar.SECOND, 0);
         calendar.add(Calendar.MILLISECOND, 0);
 
         alarmManager = (AlarmManager) context
 .getSystemService(Context.ALARM_SERVICE);
 alarmManager.cancel(pi);
 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
 alarmManager.set(AlarmManager.RTC_WAKEUP,
 calendar.getTimeInMillis(), pi);
 } else {
 setAlarm(context, calendar, pi);
 }
     }
 // alarm for one time only.
 @SuppressLint("NewApi")
 private static void setAlarm(Context context, Calendar calendar,
 PendingIntent pIntent) {

 alarmManager.setExact(AlarmManager.RTC_WAKEUP,
 calendar.getTimeInMillis(), pIntent);

 }
 } 

Remember to add this line in your AndroidManifest.xml.

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

      

Now, Create a class MyService.java and add the following.

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;

public class MyService extends Service
{
        @Override
        public IBinder onBind(Intent arg0)
        {
           // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void onCreate()
        {
           // TODO Auto-generated method stub
           super.onCreate();
        }
       
       @Override
       public void onStart(Intent intent, int startId)
       {
           NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.drawable.ic_launcher)
           .setContentTitle("Hey, i'm notifying you from service.")
//           .setContentText("")
           .setTicker(null)
           .setDefaults(Notification.DEFAULT_SOUND)
           .setAutoCancel(true);

           Intent notificationIntent = new Intent(this, MainActivity.class);
                  notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                  notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//single top to avoid                //creating many activity stacks queue
           PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
           
           mBuilder.setContentIntent(contentIntent);
           NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
           mNotificationManager.notify(1, mBuilder.build());
        }
    
        @Override
        public void onDestroy()
        {
            // TODO Auto-generated method stub
            super.onDestroy();
        }
    
    }

Remember to add this line in your AndroidManifest.xml.

<service android:name=".MyService"
                 android:enabled="true" />

Now, Add these in your MainActivity.java file.

</pre>
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;

public class MainActivity extends Activity {

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

@Override
protected void onStart() {
super.onStart();
}

public void startRepeatingTimer(View view) {
Context context = this.getApplicationContext();

alarm.SetAlarm(context);

}

public void cancelRepeatingTimer(View view){
Context context = this.getApplicationContext();

alarm.CancelAlarm(context);

}

public void onetimeTimer(View view){
Context context = this.getApplicationContext();

alarm.setOnetimeTimer(context);

}

}

Your AndroidManifest.xml should like this.

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

   <uses-sdk android:minsdkversion="10" android:targetsdkversion="19"/>
   <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.example.alarmmanagerdemo.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>
        <receiver android:name=".AlarmManagerBroadcastReceiver">
        </receiver>
        <service android:name=".MyService"
                 android:enabled="true" />
    </application>
</manifest>

Few Tips to remember:
1) To stop repeating alarms, you need to provide the same unique id to stop it.

// on AlarmManagerBroadcastReceiver.java line-no:12
final static int ALARM_ID = 1;
// on AlarmManagerBroadcastReceiver.java line-no:26 & 43
PendingIntent.getBroadcast(context,ALARM_ID, myIntent, 0);

2) Good practice to stop all alarms before creating it again.

// on AlarmManagerBroadcastReceiver.java line-no:32
alarmManager.cancel(pendingIntent);
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
 calendar.getTimeInMillis(), interval, pendingIntent);

Congrats, you have sucessfully created Notification from background Service using AlarmManager in Android.
Hope this helpful. Your valuable comments are always welcomed. It will help to improve my post and understanding.

Download Source Code from here.

durga chiranjeevi

durga chiranjeevi

I'm currently working as Android developer at Energy Alternatives India. Interested in Application and Game development.
durga chiranjeevi
Comments
  1. PaulD
    • durga chiranjeevi

Leave a Reply

Your email address will not be published. Required fields are marked *