42

I'm trying to create and delete an alarm in two different methods which are both called at different moments in the application logic.

However when I call AlarmManager's cancel() method, the alarm isn't deleted.

Here's my addAlarm() Method :

AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("ALERT_TIME", alert.date);
intent.putExtra("ID_ALERT", alert.idAlert);
intent.putExtra("TITLE", alert.title);
intent.putExtra("GEO_LOC", alert.isGeoLoc);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
        alert.idAlert, intent, PendingIntent.FLAG_CANCEL_CURRENT);

Calendar calendar = Calendar.getInstance();
calendar.setTime(alert.date);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Log.e("ADD ALERT - WithoutGeoLoc - ",alert.toString());

Here's my deleteAlarm() Method :

AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("ALERT_TIME", alert.date);
intent.putExtra("ID_ALERT", alert.idAlert);
intent.putExtra("TITLE", alert.title);
intent.putExtra("GEO_LOC", alert.isGeoLoc);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
        alert.idAlert, intent, PendingIntent.FLAG_CANCEL_CURRENT);

alarmManager.cancel(pendingIntent);
Log.e(TAG,"REMOVE ALERT - without GeoLoc"+alert.toString());

Here's my Logcat :

01-23 17:44:07.411: E/ADD ALERT - WithoutGeoLoc -(18789): Alert [latitude=0.0, longitude=0.0, title=bfwu, comments=null, address=null, currency=hrk, idAlert=1, date=Sat Feb 23 17:44:04 CET 2013, isGeoLoc=null]
01-23 17:44:13.032: E/REMOVE ALERT without GeoLoc - (18789): Alert [latitude=0.0, longitude=0.0, title=bfwu, comments=null, address=null, currency=hrk, idAlert=1, date=Sat Feb 23 17:44:04 CET 2013, isGeoLoc=null]

Here's a list of pendingIntents in the AlarmManager

Current Alarm Manager state:
Realtime wakeup (now=2013-01-23 17:44:37):
RTC_WAKEUP #48: Alarm{2c1d0588 type 0 com.my.app}
type=0 when=+364d23h59m33s288ms repeatInterval=0 count=0
operation=PendingIntent{2c0a6cb0: PendingIntentRecord{2c1d04e8 com.my.app  broadcastIntent}}
RTC_WAKEUP #47: Alarm{2c2298a0 type 0 com.my.app}
type=0 when=+30d23h59m27s360ms repeatInterval=0 count=0
operation=PendingIntent{2c292af8: PendingIntentRecord{2c22a628 com.my.app broadcastIntent}}

A couple notes:

  • RTC_WAKEUP #47 is My Original Alarm
  • RTC_WAKEUP #48 is a New Alarm that should have overwritten #47 rather than create a new one.

I have compared the two intents (not pendingIntents) from my add and delete methods using Intent's filterEquals() method which returns true ... Yet the alarm is not deleted. What am I doing wrong?


UPDATE

Here's my saveAlert() method that calls addAlarm() and deleteAlarm()

private void saveAlert() {
    // *** If Modifying Alert => REMOVE OLD ALERT (then add new one)
    Intent intent1 = null, intent2 = null;

    if (alert.idAlert != null) {
        if (alert.isGeoLoc == null || alert.isGeoLoc == false) {
            intent2 = ProximityService.removeProximityAlertWithoutGeoLoc(getApplicationContext(), devisesApp.alertsGlobal.getAlertById(alert));
        } else {
            ProximityService.removeProximityAlert(getApplicationContext(), alert);
        }
    }
    // *** Add Alert
    if (alert.isGeoLoc == null || alert.isGeoLoc == false) {
        intent1 = ProximityService.addProximityAlertWithoutGeoLoc(getApplicationContext(), alert, devisesApp.alertsGlobal);
    } else {
        ProximityService.addProximityAlert(getApplicationContext(), alert, devisesApp.alertsGlobal);
    }

    Log.i(TAG, "[saveAlert] Alert ID : " + alert.idAlert);
    devisesApp.alertsGlobal.addById(alert);
    Log.i("INTENT EQUALS", intent1.filterEquals(intent2) + ""); // This returns true
}
Community
  • 1
  • 1
Mike Bryant
  • 2,455
  • 9
  • 39
  • 60

4 Answers4

49

Try this flag:

PendingIntent.FLAG_UPDATE_CURRENT

Instead of:

PendingIntent.FLAG_CANCEL_CURRENT 

So the PendingIntent will look like this:

PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 
        alert.idAlert, intent, PendingIntent.FLAG_UPDATE_CURRENT)  

(Make sure that you use same alert object and mContext!)

A side note: If you want one global AlarmManager, put the AlarmManager in a static variable (and initialize it only if it's null).

Community
  • 1
  • 1
Govil
  • 2,034
  • 20
  • 20
  • 1
    thank you so much, I've been stuck on this for hours and hours I changed my flag to PendingIntent.FLAG_UPDATE_CURRENT) and now it works like a charm – Mike Bryant Jan 24 '13 at 10:11
  • 1
    I had a similar situation. Something for future people that stumble on this post is to maybe try calling Cancel() on the pending intent. Otherwise, getBroadcast will always return that intent. (event though it's alarm won't fire) – Ben Bishop Sep 11 '13 at 19:52
  • 1
    +1. Should also also work with '0' as the flags - there's no need to update an existing pending intent, as long as you don't cancel the existing one. – orip Mar 04 '14 at 10:14
  • Can you explain more about why it can't be cancelled if using FLAG_CANCEL_CURRENT? In my understanding if context, pendingIntent and requestCode are the same, the alarm can be cancelled. – Will Jan 20 '16 at 15:45
  • 1
    Getting an `AlarmManager` requires a `Context` so I'm wondering if it definitely safe to store it in a static variable - i.e., there won't be any memory leaks? – ban-geoengineering Dec 06 '16 at 00:27
  • @BenBishop: I did the same using `PendingIntent.FLAG_CANCEL_CURRENT ` and it worked for me. But, it doesn't cause any memory issues? – oneManArmin Aug 21 '17 at 13:36
3

Cancelling an alarm is a bit confusing. You have to pass the same ID and IntentPending. Here is an example:

private void resetIntentWithAlarm(int time){


        Intent intentAlarm = new Intent(getApplicationContext(), DownloadService.class);
        intentAlarm.putExtra(Your Key, Your stuff to pass here);

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        PendingIntent pendingIntent = PendingIntent.getService(
                getApplicationContext(),
                YOUR_ID,
                intentAlarm,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

    if (time != 0) {

        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (60L * 1000L * time), (60L * 1000L * time), pendingIntent);
        Log.i(TAG, "Alarm setted on for " + time + " mins.");
    }
    // if TIME == Zero, cancel alaram
    else {

        alarmManager.cancel(pendingIntent);
        Log.i(TAG, "Alarm CANCELED. Time = " + time);
    }
oskarko
  • 3,382
  • 1
  • 26
  • 26
0

Cancel the alarm from alarm manager on any specific time which you set:

Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
am.cancel(pendingIntent);
4b0
  • 21,981
  • 30
  • 95
  • 142
-2

If you want to cancel the alarm manager just put the wright id in pending intent and just call cancel() in alarm manager for that pending intent.

  • cancel() javadoc says `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.` requestCode does not have any affect. – boltup_im_coding Oct 20 '16 at 17:45