2

I'm in the process of updating a customer's application and have hit a problem with the timer mechanism they have adopted. Previously they had been using AlarmManager.setRepeating to create an alarm which recurs after a specified interval.

AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnAlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);    
mgr.setRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP, 
        SystemClock.elapsedRealtime() + interval, 
        interval, 
        pi
);

As of Android 4.4 this results in inaccurate timings, so I tried to replace this with an exact timer.

mgr.setExact(
        AlarmManager.ELAPSED_REALTIME_WAKEUP, 
        SystemClock.elapsedRealtime() + interval, 
        pi
);

However setExact is only available from API 19. Currently MinSDK is set to 15 and Target to 21. While I believe that I could simply set the minimum API to be 19, the customer would still like to support devices runnning APIs 15-18.

Is there any way to support both processes, using setRepeating on API 15-18, then setExact on 19+?

EDIT: Is anything lost by dropping the target API from 21 to 18, and would this fix the problem?

Jacksonkr
  • 31,583
  • 39
  • 180
  • 284
Iain Smith
  • 23
  • 4
  • Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested. http://developer.android.com/reference/android/app/AlarmManager.html – ecle Jan 08 '15 at 16:47
  • Currently minimum is set to 15 and target is 21. I guess this is why the timing problems are appearing when testing on Lollipop devices. – Iain Smith Jan 08 '15 at 16:50

1 Answers1

2

You can get version of the installed os with Build.VERSION.SDK_INT (Retrieving Android API version programmatically)

if (Build.VERSION.SDK_INT >= 19)
    mgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + interval, pi);
else if (Build.VERSION.SDK_INT >= 15)
    mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + interval, interval, pi);
Community
  • 1
  • 1
Longi
  • 3,913
  • 2
  • 28
  • 38
  • Okay, so I set the minimum API to 15 and the target to 21, then added the Build.VERSION branch and everything seems to work fine for the first instance, I guess that I just need to reschedule the Exact timer on API 19 and higher from within the Pending Intent. – Iain Smith Jan 09 '15 at 08:40