Android: How to use AlarmManager

88,708

Solution 1

"Some sample code" is not that easy when it comes to AlarmManager.

Here is a snippet showing the setup of AlarmManager:

AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);

mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

In this example, I am using setRepeating(). If you want a one-shot alarm, you would just use set(). Be sure to give the time for the alarm to start in the same time base as you use in the initial parameter to set(). In my example above, I am using AlarmManager.ELAPSED_REALTIME_WAKEUP, so my time base is SystemClock.elapsedRealtime().

Here is a larger sample project showing this technique.

Solution 2

There are some good examples in the android sample code

.\android-sdk\samples\android-10\ApiDemos\src\com\example\android\apis\app

The ones to check out are:

  • AlarmController.java
  • OneShotAlarm.java

First of, you need a receiver, something that can listen to your alarm when it is triggered. Add the following to your AndroidManifest.xml file

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

Then, create the following class

public class MyAlarmReceiver extends BroadcastReceiver { 
     @Override
     public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

Then, to trigger an alarm, use the following (for instance in your main activity):

AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);

.


Or, better yet, make a class that handles it all and use it like this

Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);

this way, you have it all in one place (don't forget to edit the AndroidManifest.xml)

public class MyAlarm extends BroadcastReceiver {
    private final String REMINDER_BUNDLE = "MyReminderBundle"; 

    // this constructor is called by the alarm manager.
    public MyAlarm(){ }

    // you can use this constructor to create the alarm. 
    //  Just pass in the main activity as the context, 
    //  any extras you'd like to get later when triggered 
    //  and the timeout
     public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
         AlarmManager alarmMgr = 
             (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent intent = new Intent(context, MyAlarm.class);
         intent.putExtra(REMINDER_BUNDLE, extras);
         PendingIntent pendingIntent =
             PendingIntent.getBroadcast(context, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
         Calendar time = Calendar.getInstance();
         time.setTimeInMillis(System.currentTimeMillis());
         time.add(Calendar.SECOND, timeoutInSeconds);
         alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                      pendingIntent);
     }

      @Override
     public void onReceive(Context context, Intent intent) {
         // here you can get the extras you passed in when creating the alarm
         //intent.getBundleExtra(REMINDER_BUNDLE));

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

Solution 3

What you need to do is first create the intent you need to schedule. Then obtain the pendingIntent of that intent. You can schedule activities, services and broadcasts. To schedule an activity e.g MyActivity:

  Intent i = new Intent(getApplicationContext(), MyActivity.class);
  PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
  PendingIntent.FLAG_CANCEL_CURRENT);

Give this pendingIntent to alarmManager:

  //getting current time and add 5 seconds in it
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 5);
  //registering our pending intent with alarmmanager
  AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
  am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

Now MyActivity will be launched after 5 seconds of the application launch, no matter you stop your application or device went in sleep state (due to RTC_WAKEUP option). You can read complete example code Scheduling activities, services and broadcasts #Android

Solution 4

I wanted to comment but <50 rep, so here goes. Friendly reminder that if you're running on 5.1 or above and you use an interval of less than a minute, this happens:

Suspiciously short interval 5000 millis; expanding to 60 seconds

See here.

Solution 5

Some sample code when you want to call a service from the Alarmmanager:

PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);    
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);

You dont have to ask userpermissions.

Share:
88,708
Tom
Author by

Tom

Updated on January 14, 2020

Comments

  • Tom
    Tom over 4 years

    I need to trigger a block of code after 20 minutes from the AlarmManager being set.

    Can someone show me sample code on how to use an AlarmManager in ِAndroid?

    I have been playing around with some code for a few days and it just won't work.

  • Tom
    Tom almost 15 years
    Hello again. Thanks for the reply. If I purchase your book does it explain how to implement a alarm manager in full detail?
  • CommonsWare
    CommonsWare almost 15 years
    The Advanced Android book (Version 0.9) has ~9 pages covering AlarmManager, WakeLocks, and the rest of that example. That will probably expand slightly in Version 1.0 as I make the fix I mentioned in my answer above. And if you have questions regarding the book or its sample code, hop over to groups.google.com/group/cw-android and I'll be happy to answer them.
  • Bostone
    Bostone over 14 years
    Any android developer should have subscription to Mark's books :) At least once
  • Nuno Gonçalves
    Nuno Gonçalves about 12 years
    Hi there! I tested this code and it worsk fine (+1). but I tried this for multiple alarms (like one for 10 secons, and another for 15, and only the sencond one is fired. Am I doing somehting wrong, or is it some king of problem? EDIT: Ok, I found the problem here: stackoverflow.com/questions/2844274/…
  • Phantômaxx
    Phantômaxx over 10 years
    A very common abbreviation.
  • A.Alqadomi
    A.Alqadomi about 10 years
    +1 great answer ,exactly what i needed , a working 'set' example.
  • CommonsWare
    CommonsWare almost 10 years
    @MarioGalván: You need to set it when your app is run for the first time and on a reboot.
  • Edward Falk
    Edward Falk almost 9 years
    FWIW, I would use a static method rather than a constructor for this.
  • Damon Yuan
    Damon Yuan about 8 years
    I think you should use AlarmManager.RTC_WAKEUP if you want it to fire right away and then every PERIOD. In your code, it will fire after SystemClock.elapsedRealtime() and then every PERIOD.
  • CommonsWare
    CommonsWare about 8 years
    @DamonYuan: You are incorrect. That is equivalent of thinking that RTC_WAKEUP, with a value of System.currentTimeMillis(), will not invoke the alarm for ~46 years (the difference in time between now and 1 January 1970). The second parameter to setRepeating() is the time in the stated timebase when the alarm should go off.