cancel all the alarms set using alarmmanager - android

I want to cancel all the alarms that are set..... I have searched a lot and tried a lot of things but nothing worked... When I set alarm for say after 2 minutes and then I cancel it, it will still fire after 2 minutes.....
Any help will be appreciated.
Method for creating alarms :
Intent intent = new Intent(c, AlarmReceiver.class);
intent.putExtra("task", task);
intent.putExtra("id", id);
PendingIntent pendingIntent = PendingIntent.getActivity(c, code, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)c.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
This is to cancel alarms :
Intent intent = new Intent(c, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(c, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)c.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);

When you schedule your alarms, your second parameter to getActivity() is code.
When you try to cancel your alarms, your second parameter to getActivity() is 0. This will only successfully cancel an alarm whose code was 0.
If you want to consistently cancel the alarms, you need to create equivalent PendingIntents, and that means, among other things, that the second parameter to getActivity() needs to be the same.

You are setting the alarm with request code (second parameter for getActivity) equals to code, while when you are cancelling the alarm, the second parameter is 0. If the value of code is not 0 the alarm wouldn't be cancelled.
In order to fire and cancel multiple alarms, you need to use unique value for requestCode (second parameter) in PendingIntent.getActivity
see this code that will set 3 Alarms using three unique request Codes,
for (int requestCode = 1; requestCode <= 3; requestCode++) {
PendingIntent pendingIntent = PendingIntent.getActivity(c, requestCode, intent,PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)c.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
You can cancel the Alarm using the same requestCode (and other parameters) that were used to set it.
The other parameters which are needed to matched are,
The "action" in the Intent must be the same (or both null). Otherwise they do not match.
The "data" in the Intent must be the same (or both null). Otherwise they do not match.
The "type" (of the data) in the Intent must be the same (or both null). Otherwise they do not match.
The "package" and/or "component" in the Intent must be the same (or both null). Otherwise they do not match. "package" and "component" fields are set for "explicit" Intents.
The list of "categories" in the Intent must be the same. Otherwise they do not match.
Please see this answer for more details.

To cancel an alarm you need no re-create the same PendingIntent and pass the same request code.
You can see my solution here

When you cancel alarm its intent must be same with intent which used for set alarm .
so just add following 2 line
intent.putExtra("task", task);
intent.putExtra("id", id);
So your final code will be
Intent intent = new Intent(c, AlarmReceiver.class);
intent.putExtra("task", task);
intent.putExtra("id", id);
PendingIntent pendingIntent = PendingIntent.getActivity(c, code, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)c.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);

Related

How to properly cancel pending alarms

I can't seem to find an answer to this, but what is the criteria for passing in a matching PendingIntent to be removed from an alarm? It it based on the just the name like com.blah.package.myclass or do the Extras matter?
For example, I'm doing something like this and all alarms fire the same intent:
public void setAlarm(Context context, long nextAlarmMillis) {
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("alarm", this);
PendingIntent sender = PendingIntent.getBroadcast(context, 1234 /* unused */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
am.cancel(sender);
am.set(AlarmManager.RTC_WAKEUP, nextAlarmMillis, sender);
}
What happens is that the Alarm class can be altered, etc and passed in as an Extra. I am canceling the previous alarm, but I'm not sure if it's doing anything or if any left over alarms will remain.
Anyone know for sure?
Following is mentioned in AlarmManager documentation
Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.
Which, the filterEquals() is defined as:
Determine if 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.
I think the easiest to do is you keep the reference of PendingIntent passed to AlarmManager, and pass it to cancel. Or have a factory method to construct such pi.

cancel a particular alarm

I am setting alarms at diffrent time . I want to delete a particulat alarm.
Ex. I set 100 alarms at diiferents times , now I want to Delete an alarm set at 25 Feb 2012 10.45 AM. How Can I do that.
I written following code to set alarm.
final AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
GregorianCalendar gc=new GregorianCalendar();
gc.set(2012, 1, 22, 10, 42,0);
Intent intent = new Intent(this, AlarmService.class);
gc.set(Calendar.AM_PM,0);
final PendingIntent sender = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, gc.getTimeInMillis(), sender);
I have a broadcast receiver to recieve the alarm.
You need to save the request code of alarm,that is 1 in your case here. The 2nd parameter you pass in your PendingIntent.getBroadcast() method is your request code for a particular alarm.So when you save request code along with the time for what you set alarm,it would be easy for you to get the particular alarm instance and then you can cancel it using:
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, OneShotAlarm.class); //OneShotAlarm is the broadcast receiver you use for alarm
PendingIntent sender = PendingIntent.getBroadcast(context,alarm_request_code, intent, 0);
am.cancel(sender);
You should take care that each of your request code for different alarms should be unique,otherwise your alarm will be rescheduled with new time you set with the older request code.
Hope you get the point.
You might need to store it in some form of data structure to keep track of the time and the object. That being said, I have not tried storing AlarmManager objects before.

Android: Unable to cancel repeating alarm

I am creating a repeating alarm. This works fine using the following code:
Intent intent = new Intent(this.ctx, AlarmReceiver.class);
intent.setAction("" + notificationId);
intent.putExtra(AlarmReceiver.TITLE, alarmTitle);
intent.putExtra(AlarmReceiver.SUBTITLE, alarmSubTitle);
intent.putExtra(AlarmReceiver.TICKER_TEXT, alarmTicker);
intent.putExtra(AlarmReceiver.NOTIFICATION_ID, notificationId);
PendingIntent sender = PendingIntent.getBroadcast(this.ctx, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = getAlarmManager();
am.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, 60000, sender);
Now I want to cancel an existing notification message (which pops up every minute for testing purposes), I invoke the following code, passing it an identical notificationId:
Intent intent = new Intent(this.ctx, AlarmReceiver.class);
intent.setAction("" + notificationId);
PendingIntent pi = PendingIntent.getService(this.ctx, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = getAlarmManager();
try {
am.cancel(pi);
} catch (Exception e) {
Log.e(PLUGIN_NAME, "AlarmManager update was not canceled. " + e.toString());
}
I see that pi != null, however the notification keeps coming and is not being cancelled. Both code snippets reside in the same class.
Basically I have two questions:
- How can I cancel a single alarm using its unique ID?
- How can I cancel all alarms, regardless of the ID?
UPDATE: I found that posting my issue here helps to get my mind straight. Changing the cancel code from:
PendingIntent sender = PendingIntent.getService( ... )
To:
PendingIntent sender = PendingIntent.getBroadcast( ... )
Helps to solve question 1. However the code to cancel all events, still does not work:
Intent intent = new Intent(this.ctx, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this.ctx, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = getAlarmManager();
am.cancel(pi);
I'm a noob here. But I think if you want to cancel the alarm, you have to use the exact same instance of PendingIntent. That means "their action, data, type, class, and categories are the same" as defined by filterEquals(Intent) . Therefore, you need to use the same requestCode here, not 0. Maybe you could use a list to store the Notification Ids, and iterate them to cancel all alarms.
I think , you should use same AlarmManager object to cancel the alram and also try to use same PendingIntent.

When trying to set an AlarmManager event, previous one is resetting with new time and the new one is not getting triggerred

Here is my code which I tried, Steps.
1) creating an AlarmManager event by calling AM.Set( ) method suppose with time X.
2) creating another AlarmManager event suppose with time Y.
Result = first event is triggered at time Y in place of time X. and second is not triggered at all.
AlarmManager AM =(AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent();
intent.setAction(Constants.ALARM_ACTION);
intent.putExtra(Constants.EXTRA_DATA1, data[0]);
intent.putExtra(Constants.EXTRA_DATA2, data[1]);
long selectedTime = Long.parseLong(data[2]);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent,0);
AM.set(AlarmManager.RTC,selectedTime, pi);
Am I doing something wrong? I need to trigger all the events .
Your first and second Intents are equivalent, and so you wind up with the same PendingIntent object as a result of your getBroadcast() call. Either:
Use a unique requestCode (2nd parameter to getBroadcast()), which I think will clear this up, or
Do something to have a unique action, data (Uri), categories, or MIME type on each Intent (extras being different are not sufficient)
By adding a count variable which will automotically increase when try to getBroadcast. it is working now.
AlarmManager AM =(AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent();
intent.setAction(Constants.ALARM_ACTION_MESSAGE);
intent.putExtra(Constants.EXTRA_NUMBER, data[0]);
intent.putExtra(Constants.EXTRA_BODY, data[1]);
long selectedTime = Long.parseLong(data[2]);
PendingIntent pi = PendingIntent.getBroadcast(mContext, count++, intent,0);
AM.set(AlarmManager.RTC,selectedTime, pi);

Why wont this work android canceling Alarm?

This is what sets the alarm
public void setSilent(Long taskId, Calendar when){
Intent i = new Intent(mContext, SilentReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 1 , i, PendingIntent.FLAG_ONE_SHOT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
It takes in an id and date to use with the intent.
I am canceling it in another file when the user clicks delete. using
Intent i = new Intent(null, SilentReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(null, 1 , i, PendingIntent.FLAG_ONE_SHOT);
should this work because it has the same request code as the first one or am I doing something wrong?
You have to save a reference to your first PendingIntent. This way you can use:
mAlarmManager.cancel(pi);
And the alarm should be cancelled.
This answer has been repeated many times. Please search before asking.
Be careful to send a PendingIntent to stop the alarm with the same data than the Intent to create the alarm: problem with cancel the alarm manager pending intent

Categories

Resources