Search code examples
androidnotificationsalarmmanager

Android: Notification cancels it's repeating alarm


I want my notification to cancel it's own repeating alarm. However, I don't know how to pass pendingIntent (to cancel it later) before it is even created.

Alarms sets here:

public class Schedule extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wakeLock.acquire();

        //next is notification code. //

        ...

        //create intent.
        Intent notificationIntent = new Intent(context, MainActivity.class);

        PendingIntent contentIntent = PendingIntent.getActivity(context,
                NOTIFY_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        ...

        ////
        wakeLock.release();
    }

    public void setAlarm(Context context) {

        ...

        Intent intent = new Intent(context, Schedule.class);
        intent.putExtra("DELAY", delay);
        intent.putExtra("NOTIFICATION_ID", id);
        intent.putExtra("TITLE_TEXT", titleText);
        intent.putExtra("BIG_TEXT", bigText);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000 * 60 * delay, 1000 * 60 * delay, pendingIntent);
    }
}

The key problem is that I want to cancel the repeating alarm on notification click (intent in onRecieve method), but canceling alarms requires pendingIntent, which notification is a part of. Any way to cheat the system?


Solution

  • Use AlarmManager.cancel() to cancel the specific alarm and use same PendingIntent that was used to create the alarm. Of course, you should use same requestCode(NOTIFY_ID) that was used before.

    Try this:

    Intent intent = new Intent(this, Schedule.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIFY_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    
    alarmManager.cancel(pendingIntent);
    

    Add this code portion into your MainActivty's onCreate() method as your notification will intent to MainActivity when click on it from notification panel.

    Hope this will help~