24

I have an alarmManager which I am using to send notifications to the user at specific times. Since there are multiple alarms, I have multiple pending intents that I am creating and giving a unique ID, However there are certain situations in which I will need to get all the pending intents and then cancel them, so I can reset the alarms. I have tried doing this and I still cant seem to get it right so I have a couple questions:

Is this how you would correctly get and cancel a PendingIntent?

Intent intent = new Intent(con, AppointmentNotificationReciever.class);
PendingIntent sender = PendingIntent.getBroadcast(con, id, intent,
        PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) con.getSystemService(Context.ALARM_SERVICE);
am.cancel(sender);

Does the intent need to exactly match that of the original pending intent(extras and all)?

Does the PendingIntent flag need to match that of the original pending intent?

Jay Soyer
  • 6,625
  • 8
  • 47
  • 77
ninjasense
  • 13,382
  • 17
  • 71
  • 91
  • The `FLAG_CANCEL_CURRENT` won't make any difference - for a really excellent analysis see [this](http://justanapplication.wordpress.com/tag/flag_cancel_current/#PendingIntentMatching) – Mr_and_Mrs_D May 26 '13 at 13:49

2 Answers2

60

I found out that you do not actually "get" the pending intent...you have to recreate it exactly as it was when you first created it(Intent as well) and then pass it to the AlarmManager's cancel function. So the above code I posted really is not incorrect as long as thats how I first created it. Hopefully someone will find this helpful.

ninjasense
  • 13,382
  • 17
  • 71
  • 91
  • I faced the same problem which you mentioned. Can you explain briefly how can I overcome this problem. If possible can you provide the snippet code for create and cancel pending intent. – Krishna Prasad Jan 10 '13 at 08:00
  • 3
    try this answer: http://stackoverflow.com/questions/9823408/cancelling-a-pendingintent – Whitecat Jan 19 '13 at 23:34
  • What if I cannot recreate the pending intent since I do not know the unique ID and the alarm has been deleted? What can I do to delete this pening intent. I feel like there is an alarm that is still active after it has been deleted. – stanley santoso Sep 08 '15 at 14:06
  • 1
    I had a similar problem. In addition to canceling the PI via alarm manager I also did **pi.cancel** – JenniferG Feb 23 '16 at 11:25
  • 1
    @JenniferG The pending intent's second parameter is where you identify it. By passing the pending intent's "id" along with a bundle of extras in the INTENT, your receiver will have the pending intent's unique id every time it is fired. OR, if you are not inside the receiver, then you can remove all proximity alerts and re-create them again (based on updated data, i suppose). – tony gil Aug 19 '17 at 11:15
1

There is an example of my test implementation of creating and canceling an alarm.

    public void setTHEalarm(Calendar aCalendarToAlarm) {
    int id;
    Intent intent;
    PendingIntent pendingIntent;
    AlarmManager alarmManager;

    //I create an unique ID for my Pending Intent based on fire time of my alarm:

    id = Integer.parseInt(String.format("%s%s%s%s",

            aCalendarToAlarm.get(Calendar.HOUR_OF_DAY),
            aCalendarToAlarm.get(Calendar.MINUTE),
            aCalendarToAlarm.get(Calendar.SECOND),
            aCalendarToAlarm.get(Calendar.MILLISECOND))); //HASH for ID

    intent = new Intent(this,AlarmReceiver.class);
    intent.putExtra("id",id); //Use the id on my intent, It would be usefull later.

    //Put the id on my Pending Intent:
    pendingIntent = PendingIntent.getBroadcast(this,id,intent,0);
    alarmManager = (AlarmManager)

            this.getSystemService(Context.ALARM_SERVICE);


    alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,aCalendarToAlarm.getTimeInMillis(),CustomDate.INTERVAL_MINUTE,pendingIntent);


    Log.w(TAG+" Torrancio","Created alarm id: "
            +id+" -> "
            +CustomDate.dateToHumanString(aCalendarToAlarm.getTime()));

    //Keep a reference in a previously declared field of My Activity (...)
    this.idSaved = id;

}

//Now for canceling
public void setCancel() {
    int id;
    Intent intent;
    PendingIntent pendingIntent;
    AlarmManager alarmManager;

    id = this.idSaved;
    intent =  new Intent(this,AlarmReceiver.class);
    intent.putExtra("id",id);
    pendingIntent = PendingIntent.getBroadcast(this,id,intent,PendingIntent.FLAG_CANCEL_CURRENT);

    //Note I used FLAG_CANCEL_CURRENT 

    alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    alarmManager.cancel(pendingIntent);

    Log.w(TAG+" Torrancio","Canceled->"+id);


}

Need 3 things,

  • Same type of intent (this case we're talking about an AlarmManager).
  • Same PendingIntent ID (Keep a reference of the id, save it some way).
  • A correct flag (FLAG_CANCEL_CURRENT for canceling, no need and nor must be exactly the one you used when created the pendingintent [because we use the cancel flag for calcel, but not create.])

For more details please check this out.

Hope it helps.

Alien74
  • 11
  • 3