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);
}
Related
In my app, the user can set multiple alarms for the same movie e.g "On release date", "A week before release", "A month before release" and now I'm stuck on cancelling a specific alarm, I know how to cancel an alarm with and movie id, but how to I cancel it with the movie id and the type. do I concatenate both together and pass it as the id to my pending intent?
Code:
public void cancelAlarm(Context context, _Alarm alarm) {
//Log.d(TAG, "{cancelAlarm}");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, (int) alarm.getGameId(), intent, 0);
alarmManager.cancel(alarmIntent);
}
Alarm class has the id of the movie and the type of the alarm
do I concatenate both together and pass it as the id to my pending
intent?
It seems logical.
Also you can use below way to know if your PendingIntent exists.
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, requestCode,
intent, PendingIntent.FLAG_NO_CREATE);
if (broadcast != null) {
alarmManager.cancel(alarmIntent );
}
Create note Activity from where Alarm trigger! and Alarm delete code in other Activity,it delete only last trigger Alarm means if 3 Alarm are created and I want to delete Alarm 1 it deletes but when the time of Alarm 1 reaches it trigger while it already deleted and it wont trigger other Alarm 2 and 3, on static broadcast id it trigger only last alarm for example alarm 3 trigger delete code in other activity if it delete on using same pending intent in other activity how can i use the pending intent which use trigger alarm in my delete alarm activity
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
String alertTitle = mTitleText.getText().toString();
intent.putExtra(getString(R.string.alert_title), alertTitle);
// broadcastCode++;
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), broadcastCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.set(AlarmManager.RTC_WAKEUP, calender.getTimeInMillis(), pendingIntent);
cv.put(mDbHelper.TIME, timeString);
cv.put(mDbHelper.DATE, dateString);
public void delete(int id)
{
db.delete( DbHelper.TABLE_NAME, DbHelper.C_ID + "="+id, null);
db.close();
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), CreateNote.broadcastCode, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
The PendingIntent needs to be created exactly as it was when you started the AlarmManager.
Use PendingIntent.FLAG_UPDATE_CURRENT instead of 0 when creating the PendingIntent to cancel the alarm. FLAG_UPDATE_CURRENT is equal to the constant 134217728, not 0.
Use this code:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, _id, intent, 0);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Hope this helps.
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);
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.
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);