You will find in this document


1. Basic research on Android AlarmManager API
2. Useful api references while working with AlarmManager
3. Not-so-intuitive truths about AlarmManager
4. Sample code
5. Downloadable Sample project
6. Finally what I call the AlarmManager Predicates

satya - Saturday, May 22, 2010 12:53:58 PM

the api

the api

satya - Friday, June 11, 2010 11:02:32 PM

Alarm uses a broadcast to call the target functionality

This is done through an intent.

what about invoking an activity? or calling a service?

satya - Friday, June 11, 2010 11:05:07 PM

A key statement at the link above

If your alarm receiver called Context.startService(), it is possible that the phone will sleep before the requested service is launched. To prevent this, your BroadcastReceiver and Service will need to implement a separate wake lock policy to ensure that the phone continues running until the service becomes available.

satya - Saturday, June 12, 2010 11:50:46 AM

Creating an intent to call your class when it goes off


Intent intent = new Intent(AlarmController.this, 
              YourBroadcastReceiver.class);

PendingIntent pi = 
    PendingIntent.getBroadcast(AlarmController.this,
            0, intent, 0);

satya - Saturday, June 12, 2010 11:56:18 AM

showing a toast


// Tell the user about what we did.
if (mToast != null) {
        mToast.cancel();
}
mToast = Toast.makeText(<some-context>, 
       R.string.one_shot_scheduled,
       Toast.LENGTH_LONG);
mToast.show();

satya - Saturday, June 12, 2010 12:02:16 PM

Toast API

Toast API

satya - Saturday, June 12, 2010 12:03:20 PM

Possible toast durations


LENGTH_LONG
LENGTH_SHORT

satya - Saturday, June 12, 2010 12:05:38 PM

Figuring out 30 secs from now


Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);

satya - Saturday, June 12, 2010 12:07:44 PM

Telling the alarm to go off once


// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

satya - Saturday, June 12, 2010 12:47:12 PM

Cancelling the alarms


Intent intent = new Intent(AlarmController.this, RepeatingAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,
                 0, intent, 0);
            
// And cancel the alarm.
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.cancel(sender);

satya - Saturday, June 12, 2010 12:49:41 PM

alarm boot

alarm boot

Search Google for: alarm boot

Search Android Developers Group for: alarm boot

Search Android Beginers Group for: alarm boot

Search Google Code for: alarm boot

Search Android Issues Database for: alarm boot

satya - Saturday, June 12, 2010 12:51:42 PM

alarm not set

alarm not set

Search Google for: alarm not set

Search Android Developers Group for: alarm not set

Search Android Beginers Group for: alarm not set

Search Google Code for: alarm not set

Search Android Issues Database for: alarm not set

satya - Saturday, June 12, 2010 1:02:17 PM

alarm preferences

alarm preferences

Search Google for: alarm preferences

Search Android Developers Group for: alarm preferences

Search Android Beginers Group for: alarm preferences

Search Google Code for: alarm preferences

Search Android Issues Database for: alarm preferences

satya - Saturday, June 12, 2010 1:03:35 PM

android saving alarm manager settings

android saving alarm manager settings

Search for: android saving alarm manager settings

satya - Saturday, June 12, 2010 1:07:19 PM

alarms lost

alarms lost

Search Google for: alarms lost

Search Android Developers Group for: alarms lost

Search Android Beginers Group for: alarms lost

Search Google Code for: alarms lost

Search Android Issues Database for: alarms lost

satya - Saturday, June 12, 2010 1:10:23 PM

Nice post on lost alarms

Nice post on lost alarms

satya - Saturday, June 12, 2010 1:17:08 PM

Read this long thread on stopping an app and alarms

Read this long thread on stopping an app and alarms

satya - Monday, June 14, 2010 9:34:10 PM

rtc_wakeup

rtc_wakeup

Search Google for: rtc_wakeup

Search Android Developers Group for: rtc_wakeup

Search Android Beginers Group for: rtc_wakeup

Search Google Code for: rtc_wakeup

Search Android Issues Database for: rtc_wakeup

satya - Monday, June 14, 2010 11:05:00 PM

Cancelling an alarm intent

For cancelling intents, two intents are the same for the purposes of intent resolution (filtering). That is, if their action, data, type, class, and categories are the same. This does not compare any extra data included in the intents.

satya - Monday, June 14, 2010 11:05:23 PM

This equivalence is defined by filterEquals

This equivalence is defined by filterEquals

satya - Monday, June 14, 2010 11:10:15 PM

Sending alarm once


private void sendAlarmOnce()
{
   //Get the instance in time that is 
   //30 secs from now.
   Calendar cal = Utils.getTimeAfterInSecs(30);
   
   //If you want to point to 11:00 hours today.
   //Calendar cal = Utils.getTodayAt(11);

   //Print to the debug view that we are 
   //scheduling at a specific time
   String s = Utils.getDateTimeString(cal);
   appendText("Schdeduling alarm at: " + s);
   
   //Get an intent to invoke
   //TestReceiver class
   Intent intent = 
      new Intent(this, TestReceiver.class);
   intent.putExtra("message", "Single Shot Alarm");

   PendingIntent pi = 
      PendingIntent.getBroadcast(
        this,    //context
        0,       //request id - not used
        intent,    //intent to be delivered 
        0);       //pending intent flags
   // Schedule the alarm!
   AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
   am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
}

satya - Monday, June 14, 2010 11:13:08 PM

work with a repeating alarm


private void sendRepeatingAlarm()
{
   Calendar cal = Utils.getTimeAfterInSecs(30);
   //Calendar cal = Utils.getTodayAt(11);
   String s = Utils.getDateTimeString(cal);
   appendText("Schdeduling alarm at: " + s);
   
   //Get an intent to invoke
   //TestReceiver class
   Intent intent = 
      new Intent(this, TestReceiver.class);
   intent.putExtra("message", "Repeating Alarm");

   PendingIntent pi = 
      PendingIntent.getBroadcast(
        this,    //context
        0,       //request id - not used
        intent,    //intent to be delivered 
        0);       //pending intent flags
   // Schedule the alarm!
   AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
   am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5*1000, pi);
   //am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
}

Start the first alarm 30 secs from now. Then repeat it every 5 secs.

The code also inclues a commented out section to start the alarm at 11:00 hrs today and you can then repeat it at the interval you would like. Notice however that when you use he wake option you will be waking the device.

satya - Monday, June 14, 2010 11:18:23 PM

AlarmManager partial wakeup?

AlarmManager partial wakeup?

Search Google for: AlarmManager partial wakeup?

Search Android Developers Group for: AlarmManager partial wakeup?

Search Android Beginers Group for: AlarmManager partial wakeup?

Search Google Code for: AlarmManager partial wakeup?

Search Android Issues Database for: AlarmManager partial wakeup?

satya - Monday, June 14, 2010 11:20:38 PM

Cancelling the alarm based on intent equivalence


private void cancelRepeatingAlarm()
{
   //Get an intent to invoke
   //TestReceiver class
   Intent intent = 
      new Intent(this, TestReceiver.class);
   intent.putExtra("message", "Repeating Alarm");

   PendingIntent pi = 
      PendingIntent.getBroadcast(
        this,    //context
        0,       //request id - not used
        intent,    //intent to be delivered 
        0);       //pending intent flags
   // Schedule the alarm!
   AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
   am.cancel(pi);
}

satya - Tuesday, June 15, 2010 4:31:39 PM

flag_one_shot

flag_one_shot

Search Google for: flag_one_shot

Search Android Developers Group for: flag_one_shot

Search Android Beginers Group for: flag_one_shot

Search Google Code for: flag_one_shot

Search Android Issues Database for: flag_one_shot

satya - Tuesday, June 15, 2010 4:42:44 PM

As per Dianne from one of the threads

You need to have something unique in the intent action, type, data, or categories to get different pending intent objects.

Having data (action, type, Uri, categories, component) that is unique within the intent is the way to do this. You can also use the request code to disambiguate them.

request id is ignored as far as delivering the pending intent goes, because broadcasts don't (currently) have requests codes. It is not ignored for intent matching, but taken as another identifying part of the pending intent. And none of this has anything specifically to do with the alarm manager, which just gets pending intents, and calls equals() and send() on them.

This is actually just a general Intent thing -- if you make a subclass of Intent and pass it to pretty much any system API, your subclass is going to be lost as it moves across processes. One could argue that Intent itself should be final, but I am loath to make things final when they don't absolutely have to be, and end up in annoying situations like String. (And anyway, the SDK is published, so it is too late to make any of these APIs final anyway.)

satya - Tuesday, June 15, 2010 4:43:46 PM

The above is taken from the following topic

The above is taken from the following topic

satya - Tuesday, June 15, 2010 4:46:47 PM

pendingintent requestid

pendingintent requestid

Search Google for: pendingintent requestid

Search Android Developers Group for: pendingintent requestid

Search Android Beginers Group for: pendingintent requestid

Search Google Code for: pendingintent requestid

Search Android Issues Database for: pendingintent requestid

satya - Tuesday, June 15, 2010 5:08:46 PM

Cancel Alarms

Cancel Alarms

Search Google for: Cancel Alarms

Search Android Developers Group for: Cancel Alarms

Search Android Beginers Group for: Cancel Alarms

Search Google Code for: Cancel Alarms

Search Android Issues Database for: Cancel Alarms

satya - Monday, June 21, 2010 10:24:25 PM

A simple utility for creatinga pending intent for an alarm manager


private PendingIntent 
getDistinctPendingIntent(Intent intent, int requestId)
{
    PendingIntent pi = 
        PendingIntent.getBroadcast(
          mContext,     //context
          requestId,     //request id
          intent,         //intent to be delivered
          0);

    //pending intent flags
    //PendingIntent.FLAG_ONE_SHOT);        
    return pi;
}

satya - Monday, June 21, 2010 10:27:20 PM

On FLAG_ONE_SHOT

I would have thought, when I am scheduling an intent for a single shot alarm, that I could use flag_one_shot. The idea is that the scheduled intent will be taken off after that.

however it seem to work fine even for a repeating alarm. Not sure what gives. but again I haven't done lot of testing.

satya - Monday, June 21, 2010 10:32:08 PM

Here is a single shot alarm that uses the request id


/*
 * An alarm can invoke a broadcast request
 * at a specified time.
 * The name of the broadcast receiver is explicitly
 * specified in the intent.
 */
public void sendAlarmOnce()
{
    //Get the instance in time that is 
    //30 secs from now.
    Calendar cal = Utils.getTimeAfterInSecs(30);
    
    //If you want to point to 11:00 hours today.
    //Calendar cal = Utils.getTodayAt(11);

    //Print to the debug view that we are 
    //scheduling at a specific time
    String s = Utils.getDateTimeString(cal);
    mReportTo.reportBack(tag, "Schdeduling alarm at: " + s);
    
    //Get an intent to invoke
    //TestReceiver class
    Intent intent = 
        new Intent(mContext, TestReceiver.class);
    intent.putExtra("message", "Single Shot Alarm");

    PendingIntent pi = 
        PendingIntent.getBroadcast(
          mContext,     //context
          1,            //request id, used for disambiguating this intent
          intent,       //intent to be delivered 
          PendingIntent.FLAG_ONE_SHOT); //pending intent flags
    // Schedule the alarm!
    AlarmManager am = 
        (AlarmManager)
             mContext.getSystemService(Context.ALARM_SERVICE);
    
    am.set(AlarmManager.RTC_WAKEUP, 
            cal.getTimeInMillis(), 
            pi);
}

satya - Monday, June 21, 2010 10:35:14 PM

Here is the code for the test receiver


public class TestReceiver extends BroadcastReceiver 
{
    private static final String tag = "TestReceiver"; 
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        Utils.logThreadSignature();
        Log.d("TestReceiver", "intent=" + intent);
        String message = intent.getStringExtra("message");
        Log.d(tag, message);
    }
}

satya - Monday, June 21, 2010 10:37:26 PM

Ofcourse you will have to define the receiver in the manifest


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

satya - Monday, June 21, 2010 10:39:47 PM

Here is how to schedule a repeat alarm


/*
 * An alarm can invoke a broadcast request
 * starting at a specified time and at 
 * regular intervals.
 * 
 * Uses the same intent as above
 * but a distinct request id to avoid conflicts
 * with the single shot alarm above.
 * 
 * Uses getDistinctPendingIntent() utility.
 */
public void sendRepeatingAlarm()
{
    Calendar cal = Utils.getTimeAfterInSecs(30);
    //Calendar testcal = Utils.getTodayAt(11);
    String s = Utils.getDateTimeString(cal);
    this.mReportTo.reportBack(tag,
        "Schdeduling Repeating alarm in 5 sec interval starting at: " + s);
    
    //Get an intent to invoke
    //TestReceiver class
    Intent intent = 
        new Intent(this.mContext, TestReceiver.class);
    intent.putExtra("message", "Repeating Alarm");

    PendingIntent pi = this.getDistinctPendingIntent(intent, 2);
    // Schedule the alarm!
    AlarmManager am = 
        (AlarmManager)
            this.mContext.getSystemService(Context.ALARM_SERVICE);
    
    am.setRepeating(AlarmManager.RTC_WAKEUP, 
            cal.getTimeInMillis(), 
            5*1000, //5 secs 
            pi);
}

satya - Monday, June 21, 2010 10:44:07 PM

here is how you cancel the repeating alarm


/*
 * An alarm can be stopped by canceling the intent.
 * You will need to have a copy of the intent
 * to cancel it.
 * 
 * The intent needs to have the same signature
 * and request id.
 */
public void cancelRepeatingAlarm()
{
    //Get an intent to invoke
    //TestReceiver class
    Intent intent = 
        new Intent(this.mContext, TestReceiver.class);
    
    //To cancel, extra is not necessary to be filled in
    //intent.putExtra("message", "Repeating Alarm");

    PendingIntent pi = this.getDistinctPendingIntent(intent, 2);
    
    // Schedule the alarm!
    AlarmManager am = 
        (AlarmManager)
           this.mContext.getSystemService(Context.ALARM_SERVICE);
    am.cancel(pi);
    this.mReportTo.reportBack(tag,"You shouldn't see alarms again");
}

satya - Monday, June 21, 2010 10:47:41 PM

Whats up with scheduling the same intent for multiple alarms


/*
 * Same intent cannot be scheduled multiple times.
 * If you do, only the last one will take affect.
 * 
 * Notice you are using the same request id.
 */
public void scheduleSameIntentMultipleTimes()
{
    //Get the instance in time that is 
    //30 secs from now.
    Calendar cal = Utils.getTimeAfterInSecs(30);
    Calendar cal2 = Utils.getTimeAfterInSecs(35);
    Calendar cal3 = Utils.getTimeAfterInSecs(40);
    Calendar cal4 = Utils.getTimeAfterInSecs(45);
    
    //If you want to point to 11:00 hours today.
    //Calendar cal = Utils.getTodayAt(11);

    //Print to the debug view that we are 
    //scheduling at a specific time
    String s = Utils.getDateTimeString(cal);
    mReportTo.reportBack(tag, "Schdeduling alarm at: " + s);
    
    //Get an intent to invoke
    //TestReceiver class
    Intent intent = 
        new Intent(mContext, TestReceiver.class);
    intent.putExtra("message", "Single Shot Alarm");

    PendingIntent pi = this.getDistinctPendingIntent(intent, 1);
    
    // Schedule the alarm!
    AlarmManager am = 
        (AlarmManager)
             mContext.getSystemService(Context.ALARM_SERVICE);
    
    am.set(AlarmManager.RTC_WAKEUP, 
            cal.getTimeInMillis(), 
            pi);
    
    am.set(AlarmManager.RTC_WAKEUP, 
            cal2.getTimeInMillis(), 
            pi);
    am.set(AlarmManager.RTC_WAKEUP, 
            cal3.getTimeInMillis(), 
            pi);
    am.set(AlarmManager.RTC_WAKEUP, 
            cal4.getTimeInMillis(), 
            pi);
}

satya - Monday, June 21, 2010 10:51:54 PM

Using request id to distinguish intents


/*
 * Same intent can be scheduled multiple times
 * if you change the request id on the pending intent.
 * Request id identifies an intent as a unique intent.
 */
public void scheduleDistinctIntents()
{
    //Get the instance in time that is 
    //30 secs from now.
    Calendar cal = Utils.getTimeAfterInSecs(30);
    Calendar cal2 = Utils.getTimeAfterInSecs(35);
    Calendar cal3 = Utils.getTimeAfterInSecs(40);
    Calendar cal4 = Utils.getTimeAfterInSecs(45);
    
    //If you want to point to 11:00 hours today.
    //Calendar cal = Utils.getTodayAt(11);

    //Print to the debug view that we are 
    //scheduling at a specific time
    String s = Utils.getDateTimeString(cal);
    mReportTo.reportBack(tag, "Schdeduling alarm at: " + s);
    
    //Get an intent to invoke
    //TestReceiver class
    Intent intent = 
        new Intent(mContext, TestReceiver.class);
    intent.putExtra("message", "Single Shot Alarm");

    // Schedule the alarms!
    AlarmManager am = 
        (AlarmManager)
             mContext.getSystemService(Context.ALARM_SERVICE);
    
    am.set(AlarmManager.RTC_WAKEUP, 
            cal.getTimeInMillis(), 
            getDistinctPendingIntent(intent,1));
    
    am.set(AlarmManager.RTC_WAKEUP, 
            cal2.getTimeInMillis(), 
            getDistinctPendingIntent(intent,2));
    am.set(AlarmManager.RTC_WAKEUP, 
            cal3.getTimeInMillis(), 
            getDistinctPendingIntent(intent,3));
    am.set(AlarmManager.RTC_WAKEUP, 
            cal4.getTimeInMillis(), 
            getDistinctPendingIntent(intent,4));
}

satya - Monday, June 21, 2010 10:56:42 PM

Testing the primacy of "alarm" and "intent"


/*
 * It is not the alarm that matters 
 * but the pending intent.
 * Even with a repeating alarm for an intent,
 * if you schedule the same intent again
 * for one time, the later one takes affect.
 * 
 * It is as if you are setting the 
 * alarm on an existing intent multiple
 * times and not the other way around.
 */
public void alarmIntentPrimacy()
{
    Calendar cal = Utils.getTimeAfterInSecs(30);
    String s = Utils.getDateTimeString(cal);
    this.mReportTo.reportBack(tag,
        "Schdeduling Repeating alarm in 5 sec interval starting at: " + s);
    
    //Get an intent to invoke
    //TestReceiver class
    Intent intent = 
        new Intent(this.mContext, TestReceiver.class);
    intent.putExtra("message", "Repeating Alarm");

    PendingIntent pi = getDistinctPendingIntent(intent,0); 
    AlarmManager am = 
        (AlarmManager)
            this.mContext.getSystemService(Context.ALARM_SERVICE);
    
    this.mReportTo.reportBack(tag,"Setting a repeat alarm 5 secs duration");
    am.setRepeating(AlarmManager.RTC_WAKEUP, 
            cal.getTimeInMillis(), 
            5*1000, //5 secs 
            pi);

    this.mReportTo.reportBack(tag,"Setting a onetime alarm on the same intent");
    am.set(AlarmManager.RTC_WAKEUP, 
            cal.getTimeInMillis(), 
            pi);
    this.mReportTo.reportBack(tag,"The later alarm, one time one, takes precedence");
}

satya - Monday, June 21, 2010 10:59:29 PM

Here are some date/time utility functions used


public static Calendar getTimeAfterInSecs(int secs)
{
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.SECOND,secs);
    return cal;
}
public static Calendar getCurrentTime()
{
    Calendar cal = Calendar.getInstance();
    return cal;
}
public static Calendar getTodayAt(int hours)
{
    Calendar today = Calendar.getInstance();
    Calendar cal = Calendar.getInstance();
    cal.clear();
    
    int year = today.get(Calendar.YEAR);
    int month = today.get(Calendar.MONTH);
    //represents the day of the month
    int day = today.get(Calendar.DATE);
    cal.set(year,month,day,hours,0,0);
    return cal;
}
public static String getDateTimeString(Calendar cal)
{
    SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");
    df.setLenient(false);
    String s = df.format(cal.getTime());
    return s;
}

satya - Tuesday, June 22, 2010 11:01:12 AM

You can download a sample project here (zip file link)

You can download a sample project here (zip file link)

This zip file has all of the code above and also a driver (a set of menus) to invoke each of the functions mentioned above.

You can see the logcat to see how it behaves.

The project also includes the test receiver.

satya - Tuesday, June 22, 2010 11:27:56 AM

AlarmManager Predicates

  1. Alarms are not persistent across boots. What ever alarms you have set through the alarm manager will be lost when the device reboots.
  2. You will need to persist alarm parameters yourself if you would like to retain them beyond device reboots. You will need to listen to broadcast boot event and also time change events to reset these alarms as needed.
  3. Alarms and pending intents (even intents for that matter) are not independent
  4. A given pending intent cannot be used for multiple alarms. The last alarm will override the previous alarms
  5. It is almost like an alarm is set, repeating or otherwise, on a unique pending intent, although the api gives the impression that you are indepenently scheduling alarms with an intent. It appears it is the exact opposite. You take an intent and specify when that intent will go off.
  6. You can not really derive from an intent because when the intent crosses process or package boundaries and reincarnated it will not have the class definition of the derived class
  7. The implication of the intent based cancel api is that when you use or persist alarms you will also need to persist intents so that those alarms can be cancelled at a later time.
  8. It is as if the api would have been more inuitive if it said "pendingIntent.setAlarm(...)" as opposed to "AlarmManager.setAlarm(pendingintent)" followed by "pendingIntent.cancelAlarm()". The meaning would have been more direct.
  9. You cannot new a pending intent. You really locate a pending intent with an option to reuse/update etc.
  10. An intent is uniquely distinguihed by its action, datauri, and its category. This is specified in the "filterEquals()" api of the intent class.
  11. A pending intent is further qualified (in addition to the base intent it depended on) by the request code.
  12. It appears that pending intents are kept in a pool that are reused

satya - Tuesday, July 13, 2010 6:21:17 PM

flag_one_shot

flag_one_shot

Search Google for: flag_one_shot

Search Android Developers Group for: flag_one_shot

Search Android Beginers Group for: flag_one_shot

Search Google Code for: flag_one_shot

Search Android Issues Database for: flag_one_shot

satya - Tuesday, July 13, 2010 6:33:08 PM

Nature of pending intent

If I create a pending intent twice with the same equality (which doesnt include the extras) then as I understand I get back a reference to the same "token" or a pending intent. This will let me cancel it!!!

Am I then to understand that I am really "fetching" an intent and not creating it??

satya - Tuesday, July 13, 2010 6:39:43 PM

flag_cancel_current

The docs say that this will cancel the current pending intent. When you dont do this probably the extra data in the new intent will not make it to the previous intent and you get back a reference to the previous pending intent.

the doc advises that you will do this so that you prevent previous intents from firing because in your mind that firing is invalid because you want to do somethign different with the newly acquired extras.

If you dont mind firing the old ones, then we are advised, to use the flag_update_current

satya - Tuesday, July 13, 2010 6:40:58 PM

flag_no_create

This will return null if the intent doesnt exist. Perhaps one will use this to locate a previous pending intent and cancel it.

satya - Tuesday, July 13, 2010 6:47:47 PM

flag_update_current

The docs say

if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.

This again shows that we are fundamentally locating an event when we issue a pending event. And in this case we are overloading with the new extras.

Significantly it seem to be wrong to think of a PendingIntent as a message!!

However when you attach a requestid to it, it seem to behave like a message

satya - Tuesday, July 13, 2010 6:55:53 PM

Pending Intent Dianne

Pending Intent Dianne

Search Google for: Pending Intent Dianne

Search Android Developers Group for: Pending Intent Dianne

Search Android Beginers Group for: Pending Intent Dianne

Search Google Code for: Pending Intent Dianne

Search Android Issues Database for: Pending Intent Dianne

satya - Tuesday, July 13, 2010 7:02:44 PM

An interesting thread to look at on pending intents

An interesting thread to look at on pending intents

satya - Tuesday, July 13, 2010 7:11:40 PM

Here is another discussion

Here is another discussion

satya - Tuesday, July 13, 2010 7:13:02 PM

Here is another recommendation from Dianne

No, I mean setting the explicit component to your broadcast receiver component on the Intent class. I strongly strongly recommend this for this kind of situation where you want someone to deliver some specific thing to a component in your app. Please read the Intent java doc for more info.

satya - Tuesday, July 13, 2010 7:14:55 PM

More on it ...

Different request codes is a perfectly fine way to do it.

That said... I would be -very- suspicious about the code you posted where you are effectively creating random identities for your pending intents. In most of the places where one uses a pending intent, you give it to something that holds on to it indefinitely, so you need to be able to recover the previous pending intent so you can give it back to have it unregistered. That is why the API works the way it does. This API is really not intended to generate tons of pending intents whose lifetime is not being managed.

satya - Tuesday, July 13, 2010 7:28:04 PM

flag_one_shot

As per the docs this seem to set it once and the cancel it right after sending it one time. This is a property of the pending intent and not the intent.

what happens if there is a pending intent already? will the new flags override those old flags??

satya - Tuesday, July 13, 2010 9:33:42 PM

Here is an implementation of the AlarmManagerService.java

Here is an implementation of the AlarmManagerService.java

It is available as


com/android/server/AlarmManagerService.java

satya - Tuesday, July 13, 2010 9:56:54 PM

Here is a link to various other implementations of services

Here is a link to various other implementations of services

satya - Tuesday, July 13, 2010 10:56:59 PM

set removelocked alarm

set removelocked alarm

Search Google for: set removelocked alarm

Search Android Developers Group for: set removelocked alarm

Search Android Beginers Group for: set removelocked alarm

Search Google Code for: set removelocked alarm

Search Android Issues Database for: set removelocked alarm

satya - Tuesday, July 13, 2010 11:31:47 PM

Here is the remove as part of a set


160     public void setRepeating(int type, long triggerAtTime, long interval,  
 161             PendingIntent operation) { 
 162         if (operation == null) { 
 163             Slog.w(TAG, "set/setRepeating ignored because there is no intent"); 
 164             return; 
 165         } 
 166         synchronized (mLock) { 
 167             Alarm alarm = new Alarm(); 
 168             alarm.type = type; 
 169             alarm.when = triggerAtTime; 
 170             alarm.repeatInterval = interval; 
 171             alarm.operation = operation; 
 172  
 173             // Remove this alarm if already scheduled. 
 174             removeLocked(operation); 
 175  
 176             if (localLOGV) Slog.v(TAG, "set: " + alarm); 
 177  
 178             int index = addAlarmLocked(alarm); 
 179             if (index == 0) { 
 180                 setLocked(alarm); 
 181             } 
 182         } 
 183     }

satya - Monday, July 19, 2010 9:48:42 AM

I should have guessed it: Just look at Cancel to see why "set" behaves the way it does

As it turned out I was looking at the wrong method to understand the alarm manager behavior. I was overly focused on the "set" methods to understand it.

There is no indication in the set method that the "pendingintent" is a key on which the alarming timing is set.

However if we look at "cancel" method this becomes quite clear. A cancel operation takes a pendingintent and cancels the alarm. If we were allowed "multiple" alarms for a given pendign intent, what would be the meaning of cancelling an alarm based on a "pendingintent"?? Will it cancel all the alarms?? So in short for "cancel" to work to cancel an "alarm" the "alarm" and the corresponding "pending intent" must be "one to one".

Had I focused on "cancel" this would have become apparent lot more sooner. Well there it is.

satya - 3/8/2014 8:00:49 PM

See the updates to Android Alarm manager as of 2014 here

See the updates to Android Alarm manager as of 2014 here