Search code examples
androidbroadcastreceiveralarmmanagerintentfilter

Delete specific Alarm from AlarmManager


I want to delete an Alarm which i have set in a Broadcastreceiver. this it how it should execute:

I receive a GCM message, which contains an user_state field.

if user_state is 0 no notification is triggered
if user_state is 1 a notification is triggered
if user_state is 2 an Alarm is set and the notification is triggered 20 Minutes later.

This all works well.

Now I want to delete an specific Alarm, depending on the Data received from the GCM-intent. Unfortunately AlarmManager.cancel() does not compare Extra fields. I also tried to use intent.setType("data to compare") but if I set this field the Broadcast is not received...

I have now tried to register a new BroadcastReceiver with the Data which should be compared in the Action field. As I understand, this should work fine, BUT it is not possible to register a BroadcastReceiver from within a BroadcastReceiver.

Also it is not possible to get a list of Pendingintents from the AlarmManager. So all i can do now is delete ALL alarms - which is not an option,

The only other idea I have is using my own Service instead of the AlarmManager... I would like to avoid that one. I don't want to use extra Resources when there is an buildin Option.

Here is my set Alarm Method:

private void setTimed(Intent intent, Notify notify) {
    Bundle bundle = intent.getExtras();
    bundle.remove("userstate");
    bundle.putString("userstate", "3");

    Intent ringintent = new Intent("de.pluetzner.waveobserver.TRECEIVE");
    ringintent.setType(notify.getHost()+"&&&"+notify.getService());
    ringintent.putExtras(bundle);
    AlarmManager am = (AlarmManager) this.context.getSystemService(this.context.ALARM_SERVICE);
    PendingIntent pi = PendingIntent.getBroadcast(this.context, 0, ringintent, 0);
    am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (this.waittime * 60 * 1000), pi);
    Log.d("timer", "time set");
}

The ringintent.setType() should be an identifier for the alarm but that does not work. Without this the Alarm is received

This one here is the Method to delete an Alarm.

private void deleteAlarm(Intent intent, Notify notify) {
    Intent ringintent = new Intent("de.pluetzner.waveobserver.TRECEIVE");
    ringintent.setType(notify.getHost() + "&&&" + notify.getService());
    PendingIntent pi = PendingIntent.getBroadcast(this.context, 0, ringintent, 0);
    AlarmManager am = (AlarmManager) this.context.getSystemService(this.context.ALARM_SERVICE);
    am.cancel(pi);
    Log.d("timer", "time removed");
}

It is the same here - with setType set it does not work. Without it, it deletes every Alarm.

I also know that it would be a somehow abusive use of setType - but I am out of Ideas. Do you have any?


Solution

  • RequestCode parameter of getBroadcast method uniquely identify each PendingIntent.

    You could assign an Unique integer code for each PendingIntent.

    Alarm1:

          PendingIntent pi = PendingIntent.getBroadcast(this.context, 1, ringintent, 0); 
    

    Alarm2:

          PendingIntent pi = PendingIntent.getBroadcast(this.context, 2, ringintent, 0); 
    

    Now if you want to kill Alarm2 alone, recreate the PendingIntent with same identifier and then call cancel method of AlarmManager

          PendingIntent sender = PendingIntent.getBroadcast(this, 2, intent, 0);
          AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
          alarmManager.cancel(sender);