Scheduling a Task to run repeatedly in Android

pugg-wall-clock__13080_PE040801_S4There are times when an app needs to run at specific times without user intervention. Something very similar to cronjobs in Linux and Scheduled Tasks in Windows.

Android has a built-in AlarmManager class which makes scheduling tasks very easy.

What we will do is to setup an Activity to be run at 00:01:00 every day i.e 1 minute past midnight.

There are 3 steps to doing this:

  1. Check if the AlarmManager already has our schedule configured
  2. Set up the task in AlarmManager
  3. Write code which will get activated at the scheduled time

WHAT IS A PENDING INTENT

Assuming you are familiar with the concept of an Intent, a Pending Intent is granting another app the permission and rights to execute a piece of your own code. In other words, its like giving power of attorney. So if App A gives a Pending Intent to App B, then App B can execute the Pending Intent code, even if App A is not running.

To schedule a task in AlarmManager requires creating a Pending Intent and passing it to the AlarmManager.

THE MAIN CODE

The sample code below checks if the task has been already scheduled. If not then it creates the task in AlarmManager.

				// check task is scheduled or not
		boolean alarmUp = (PendingIntent.getBroadcast(this, 0, 
		        new Intent("com.example.dummy.AlarmReceiver"), 
		        PendingIntent.FLAG_NO_CREATE) != null);
		
		if (  !alarmUp) {
			Intent intent = new Intent("com.example.dummy.AlarmReceiver");
			intent.putExtra("activate", true);
			PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, 
			                                      intent, PendingIntent.FLAG_UPDATE_CURRENT);
			
			Calendar calendar = Calendar.getInstance();
			calendar.setTimeInMillis(System.currentTimeMillis());
			calendar.set(Calendar.HOUR_OF_DAY, 0);   
			calendar.set(Calendar.MINUTE, 1);
			calendar.set(Calendar.SECOND, 0);

			AlarmManager alarmManager = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
			alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
			
			calendar = Calendar.getInstance();
			calendar.setTimeInMillis(System.currentTimeMillis());
			calendar.set(Calendar.HOUR_OF_DAY, 7);   
			calendar.set(Calendar.MINUTE, 0);

			alarmManager = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
			PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, 1, 
                    intent, PendingIntent.FLAG_UPDATE_CURRENT);
			alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent2);			
			
		}
		

So what we are doing above is , query for a PendingIntent which matches our Activity class name which will run at the scheduled time.  The flag PendingIntent.FLAG_NO_CREATE is important otherwise if it does not find our class scheduled as a PendingIntent, it will automatically create it.  If the task is not already scheduled, then we go ahead and create it.

Note that the Activity in which we are querying for and creating the schedule IS NOT the same Activity which will be called on activation.  So from Activity A we are creating a PendingIntent for Activity B.

Below is the Activity which gets called by the AlarmManager. This Activity extends BroadcastReceiver and overrides the  onReceive() method . We also check if the String value  “activate” has been passed in getExtra() .  This is the signal that AlarmManager has activated the task.

public class AlarmReceiver extends BroadcastReceiver { 
	
    @Override
    public void onReceive(Context context, Intent intent) {
    	
    	if (!intent.hasExtra("activate")) {
            // ignore this part
    		
    	}
				
		/// your processing code comes here

    }
}

1 Comment

Leave a Reply

Your email address will not be published.


*