Programming is like sex: one mistake and you have to support it for the rest of your life.
— Michael Sinz
How would I guess, back when writing the first version of I’m sleeping, that I would constantly need to come back to it with each release of a major Android version?
Even though Android has a mechanism which is supposed to eliminate such kind of burden, it wouldn’t work in this particular app’s case.
The purpose of the app is simple: wake at a precise time, twice per day to set or unset the volume of the phone’s ringer.
Easy enough! Simply use the framework’s AlarmManager:
alarmManager.set()
No, wait! Starting from Android KitKat (4.4), set() doesn’t guarantee precise timing anymore because of battery saving reasons. One has to use a new call:
alarmManager.setExact()
No, wait! In Android Marshmallow (6.0), setExact() doesn’t work when the device is in idle mode (ie. left alone on a table without moving), which means you’ll miss alarms. One has to use another new call:
alarmManager.setExactAndAllowWhileIdle()
The annoying thing is that each of these API changes would simply break my app if I wasn’t closely monitoring the framework’s evolution. I really hope there’s won’t be a setExactAndAllowWhileIdleAndDeepFreeze() or so call in a future revision of the framework.
This is a good example of why perfectly working and stable code still needs to be maintained because of all the changes around it (OS, drivers and libraries).
Update:
They did it again! From Android 12+, the following permission is required:
SCHEDULE_EXACT_ALARM
Enough is enough. I give up.