Alternatives for AlarmManager setRepeating in API 19 and above?

4.1k views Asked by At

My app requires very accurate timing of a repeating alarm. Since API 19 the AlarmManager setRepeating is now inexact to save battery ( Save the trees and all ).

Is there any workaround to get API 19's setExact method to work on a loop?

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

2

There are 2 answers

0
CommonsWare On

Is there any workaround to get API 19's setExact method to work on a loop?

Sure. Have your BroadcastReceiver, or whatever is getting control from the alarm, call setExact() to schedule the next recurrence, in addition to doing its existing work.

Bear in mind, though, that the changes to background processing in Android M may cause you difficulty.

0
Daniel Mi On

If Google provides a setExactRepeating() method, it may solve your problem. (It's a joke)

For now, you have to reschedule the alarm by yourself.

  1. use the setExact() method to schedule the alarm for the first time, for example:

    alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);

  2. reschedule the alarm in the onReceiver() of your BroadcastReceiver, the repeating time is a day(AlarmManager.INTERVAL_DAY in the following code):

    public void onReceive(Context context, Intent intent){

        Context danielContext = MonitorApp.getContext();
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, ReceiverName.class);//put your own ReceiverName
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, i, 0);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + AlarmManager.INTERVAL_DAY, pendingIntent);
    

    }

Of course, do something in the onReceiver() method to achieve your aim.