Search code examples
androidalarmmanager

Update ongoing notification every 60 seconds


A core functionality of my app is that it has an ongoing notification with a countdown timer that updates every minute - even if the app gets shut down by Android OS.

First I was using a service to run the timer and update the notification, but this was a memory/battery hog. So I switched to using AlarmManager to finish the timer and a repeating alarm to wake up every 60 seconds or so to update the notification:

Intent repeatingIntent = new Intent(this, AlarmReceiver.class);
repeatingIntent.putExtra(PERFORM_ACTION, ALARM_ACTION_UPDATE_NOTIFICATION);
PendingIntent repeatingAlarmIntent = PendingIntent.getBroadcast(this, 
       REQUEST_CODE_UPDATE_NOTIFICATION, repeatingIntent, 0);
AlarmManager am = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);       
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
    SystemClock.elapsedRealtime()+1000, 
    REPEATING_ALARM_INTERVAL*1000, repeatingAlarmIntent);

This works on most devices I've tried it on (and it's much kinder on RAM/battery/CPU) but on Galaxy S6 for example, the repeating alarm is being triggered only every 5 minutes or even less frequently. It sometimes get triggered on time when the device is plugged in but it is very inconsistent. I've tried setting the repeating interval to 30 seconds or less, but it has no effect, the alarm is not triggered (I see every time it's triggered in LogCat). Other, non-repeating alarms are triggered on time.

What would be a good way to ensure that the ongoing notification is updated at least every 60 seconds come hell or high water? Other than going back to using a service (ugh! plus the OS sometimes outright kills the service on devices with little RAM), the only other thing that comes to mind is to set like 5 different repeating alarms (with different request codes) and have each one trigger every 5 minutes in a staggered fashion.


Solution

  • Instead of using setRepeating() use setExact() or setWindow() and set a new alarm each time it's fired. This works well above API19.