The API of Unintended Consequences

A change to the Android API that arrived in the KitKat is that alarms don’t necessarily arrive when your code requested them to. From the docs:

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; seesetWindow(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.
Now, many apps won’t be especially bothered, but I have two apps with clock widgets that rely on the alarms being delivered exactly on time; otherwise, the clock widget is wrong until the alarm does get delivered. Which means that my widgets now need to use setExact() rather than just set().

Which is fine as far as it goes – but what’s not mentioned above is that there is no setExactRepeating(). Here’s another extract from that same page:

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 whosetargetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.”

This means that my widgets must now reschedule their alarms every minute. Which means my widgets are now running more code every minute than they were before. Which means that my widgets are now using more battery than they were before – exactly the opposite of Google’s stated intent with this change.

Footnote #1: I should also mention that, in my testing, these inexact alarms occur on KitKat devices even if targetSdkVersion is set to 18. That’s not what the docs (quoted above) say, but that’s how it works on my Nexus 7.

Footnote #2: No, I can’t use AnalogClock and Chronometer to avoid these alarms (and use less battery). They’re too limited for my widgets. My analog clocks are 24-hour (the AnalogClock class is 12-hour only), and the Chronometer class really isn’t suitable for digital clocks.