cancel a PendingIntent - android

I have a PendingIntent which is used in an AlarmManager The PendingIntents have unique ids which I keep track of. Because of this, I should be able to cancel the PendingIntent by passing the unique id when I try to cancel it. I am trying to cancel it in a different Fragment from the one I created it in, if that makes any difference.
But I have not been able to cancel it even after looking at many past questions.
I have looked at eg.: https://stackoverflow.com/a/4350149/2442638 , https://stackoverflow.com/a/12257277/2442638 , https://stackoverflow.com/a/11682008/2442638
This is how I create the PendingIntent and set it with the AlarmManager:
// remCounter is unique for each PendingIntent
Intent remIntent = new Intent();
remIntent.setAction("com.example.test.remBroadcast");
Bundle extras = new Bundle();
extras.putString("content_title", (String) s_content_title);
extras.putString("content_text", (String) s_content_text);
extras.putBoolean("bOngoing", boolean_ongoing);
extras.putInt("remCounter", remCounter); // This is how I keep track of the unique id. I have proved this to work.
remIntent.putExtras(extras);
PendingIntent remPendingIntent = PendingIntent.getBroadcast(
getActivity(), remCounter, remIntent,
PendingIntent.FLAG_ONE_SHOT);
getActivity(); // (Do I need this?)
AlarmManager remAlarmManager = (AlarmManager) getActivity()
.getSystemService(Context.ALARM_SERVICE);
remAlarmManager.set(AlarmManager.RTC_WAKEUP,
setForCal,
remPendingIntent);
This is how I'm trying to cancel a PendingIntent:
// cancelCounter is the value of the unique id of the PendingIntent I want to cancel
Intent intent = new Intent();
PendingIntent pi = PendingIntent.getBroadcast(getActivity(),
cancelCounter, intent, PendingIntent.FLAG_UPDATE_CURRENT);
pi.cancel();
AlarmManager am = (AlarmManager) getActivity()
.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);

Related

Canceling alarms from AlarmManager

I am working on application which is get the alarm time from database every 2 AM and then at the specified time the activity shows up, my app works fine, but when I manually change the data/time of the device, previous alarms are triggered and I should prevent to this to happens.
Here is my PendingIntent:
Intent i = new Intent(mContext, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(G.context, _id, i,
PendingIntent.FLAG_UPDATE_CURRENT);
Which each _id is unique and when I make a receiver for date changed event before my alarm cancel method fired previous alarms go off!
Can some body help to solve this problem?
Try this code:
Intent intent = new Intent(this, Mote.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1253, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.cancel(pendingIntent);
For cancel the alarm:
Intent intent = new Intent(this, Mote.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1253, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Edit
Well you can look for the answer and modify as per your requirements:
How to stop Android AlarmManager when there is a manual system time change?
AlarmManager: how to schedule a daily alarm and deal with time changes
Intent intent1 = new Intent(G.context, DailyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(G.context,
G.dateTimesetAlarm.getDayOfYear(), intent1, 0);
mAlarmManager.cancel(pendingIntent);
pendingIntent.cancel();

Stop alarmManager from other activity

I am trying to stop the alarmManager in the MainActivity from the onBackPressed() method in the Map activity. I have tried the code below but the alarmManager is not being stoped and still firing. How can I fix it?
Code in the MainActivity:
Intent intent = new Intent(MainActivity.this, GetLLRD.class);
intent.putExtra("json_data", json);
PendingIntent pendingIntent = PendingIntent.getService(
getApplicationContext(), 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
alarm.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 20 * 1000, pendingIntent);
startService(intent);
Code in the Map Activity:
#Override
public void onBackPressed() {
Intent intent = new Intent(Map.this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getService(
getApplicationContext(), 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
}
u problem is u use two different classes for intent to create and stop alarm:
Intent intent = new Intent(context,
GetLLRD.class);
Intent intent = new Intent(context,
MainActivity.class);
/** as in source code - new intent constructor */
public Intent(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
}
if u want to check if u got the same pending intent as before you can try to use:
Intent.filterEquals(oherIntent);
to cancel alarm you have two options use flag or use the same intent on alarm:
PendingIntent.FLAG_CANCEL_CURRENT
& i advice to make pending intent as final - example:
/**
* create pending intent
*/
final PendingIntent pIntent(Intent alarmIntent) {
// Create a PendingIntent to be triggered when the alarm goes off
return PendingIntent.getBroadcast(getApplicationContext(), AlarmReceiver.REQUEST_CODE,
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
* cancel alarm
*/
public void cancelAlarm(Intent alarmIntent, Context context) {
try {
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
/** use flag cancel here */
PendingIntent pIntent = PendingIntent.getService(context, AlarmReceiver.REQUEST_CODE, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
/** cancel alarm */
alarm.cancel(pIntent);
} catch (Exception e) {
// handle exception here
}
}
why to make pending intent final ?
because to cancel alarm u need:
Create pending intent with the same id and appropriate intent FLAG.
(to get reference to current pending intent)
PendingIntent.getBroadcast(context, REQUEST_CODE, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Cancel that pending intent.
PendingIntent.cancel();
Cancel the alarm using alarm manager.
AlarmManager.cancel(PendingIntent);
A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.
if you are using activity, use
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
12345, intent,0);

Canceling an alarm in AlarmManager

In my code, I create an alarm as follows:
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent("mypackage.START_MONITORING_SERVICE");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
long timeForNextStart = System.currentTimeMillis() + elapsedTime;
am.set(AlarmManager.RTC_WAKEUP, timeForNextStart, pi);
To cancel the alarm I do this:
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent("mypackage.START_MONITORING_SERVICE");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
am.cancel(pendingIntent);
My question is whether this is the correct way to cancel ALL alarms of the same intent. The docs say:
Remove any alarms with a matching Intent. Any alarm, of any type,
whose Intent matches this one (as defined by filterEquals(Intent)),
will be canceled.
I'm not exactly sure what defines a "matching intent". If I create multiple alarms with the above code and then peform the cancel as shown, will it cancel ALL of the alarms I created?
You should use PendingIntent flag ==> PendingIntent.FLAG_CANCEL_CURRENT fourth parameters create pendingIntent instance method.
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
Try this
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent updateServiceIntent = new Intent(context, MyPendingIntentService.class);
PendingIntent pendingUpdateIntent = PendingIntent.getService(context, 0, updateServiceIntent, 0);
// Cancel alarms
try {
alarmManager.cancel(pendingUpdateIntent);
} catch (Exception e) {
Log.e(TAG, "AlarmManager update was not canceled. " + e.toString());
}
My question is whether this is the correct way to cancel ALL alarms of
the same intent?
I dont know if you aware of requestCode should be unique in for each pendingIntent for following syntax
public static PendingIntent getService (Context context, int requestCode, Intent intent, int flags)
I'm not exactly sure what defines a "matching intent".
Each pending intent map with its provided intent to trigger and each request code map with that intent .
We can say it can be same requestcode for two different pendingIntent which ideally having two different intents .
Remember , here if PendingIntent have a same requestCode for a same intent then it can be override or cancel according to int flags
If I create multiple alarms with the above code and then peform the
cancel as shown, will it cancel ALL of the alarms I created?
To create a multiple alarm you have to give a different requestCode with the same intent .
If you want to cancel those created alarm then you have to cancel them according requestCode
For example
To Create :
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
For (int i= 0 ; i <5 ; i++){
PendingIntent contentIntent = PendingIntent.getBroadcast(TaskReminder.this, i,
new Intent(),PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, timeForNextStart, contentIntent);
}
To cancel :
For (int i= 0 ; i <5 ; i++){
//Note here ' i ' is the requestCode which map each pendingIntent with there provided intent
PendingIntent contentIntent = PendingIntent.getBroadcast(TaskReminder.this, i,
new Intent(),PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(contentIntent);
}

How to cancel multiple alarms with duplicate PendingIntent at once?

I am setting multiple alarms which will have the exact same PendingIntent object, but their time of going off is different. If I cancel one alarm by providing the same Intent object to PendingIntent, and pass this to AlarmManager.cancel(), will it cancel all the alarms (i.e. with different starting times) or will it exhibit some other behavior?
Here is the code:
while(size != 0)
{
timeToSet = getNewTime(); //gets calendar object
Intent intent = new Intent(this, MyAlarmReceiver.class);
intent.putExtra("uniqueid", uuid);
intent.putExtra("vibrate", myalarm.getVibrate());
intent.putExtra("important", myalarm.getImportant());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeToSet.getTimeInMillis(), 604800000, pendingIntent);
size--;
}
So the Intent object is same for all the alarms, but the time is different.
Now when I cancel these alarms:
Intent intent = new Intent(this, MyAlarmReceiver.class);
intent.putExtra("uniqueid", uuid);
intent.putExtra("vibrate", myalarm.getVibrate());
intent.putExtra("important", myalarm.getImportant());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Will all the alarms get cancelled? That is what I want it to do. I could use a different requestCode in every PendingIntent, but it will be better if all of them get cancelled as I dont want to maintain and store these extra requestCodes.
Thanks!
If you have a predefined amount of alarms you can set a unique requestCode (second parameter of getBroadcast) for each alarm. But I'm not sure if that works for you. If you don't specify a requestCode all alarms will be seen as equal by filterEqualsand therefore all alarms will be canceled.

How do i know if my alarm manager timer is on?

I'm using this code (from my activity) to start a periodic timer in the application:
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),(i * 1000), pendingIntent);
Toast.makeText(this, "Alarm set in " + i + " seconds",
Toast.LENGTH_SHORT).show();
I want to know how can i know (from a different activity) is the timer is running?
One possibility I can think of is to check if the pending Intent is defined.
You can call
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_NO_CREATE);
this will give you the pending Intent, or null if the Intent was not specified. This will not guarantee that the alarm was set but it is an easy way to check if the set alarm code was called before.
Another possibility is to save all set alarms in a SharedPreferences file. In this way you can look for all alarms set by your app in the shared prefs file.
As far as I can see there is no way to get a list of set alarms for your application from the AlarmManager
in stop function
Intent intent = new Intent(this, LocaitonSampleBroadcaseReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast( this.getApplicationContext(), 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.cancel(pendingIntent);
just add this:
pendingIntent.cancel();
so you can use the string wrote comment Janusz
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_NO_CREATE);

Categories

Resources