Some time ago I wrote an Android app called Fake Dawn, mainly to learn about the basics of Java development on Android, and also to implement something that I can use everyday: an alarm that wakes you up gently by gradually increasing the volume and the light in a customizable way.
I collected the things to do in Google Code, mainly by writing down ideas about improvements and transcribing the crash reports that were transmitted to Google Play Developer Console.
Recently I received bug reports by users about the app not working correctly after the phone had been upgraded to KitKat, and I discovered that the cause was that Android API has been changed.
Permission to access storage
Starting from API level 16, there’s a new permission called READ_EXTERNAL_STORAGE. Starting from API 19 (Android 4.4 KitKat) this permission is enforced and the apps that don’t ask for that permission won’t be able to access SD cards and the like.
My app can choose any sound to be the alarm tone, and that sound could be a file on the SD card. I didn’t pay attention to the changes in API for some time, so I missed the addition of READ_EXTERNAL_STORAGE. By the time Android reached API 19, my app started to misbehave for some users because they chose as alarm tone a sound in the SD card and the Android system denied my app the permission to access it and play it.
So the fix was to modify the manifest by raising the targetSdkVersion to 19 and adding the new permission. I could have set the target API to 16 and it probably would have worked anyway, but I chose to set it as the last version because the official guide suggests it:
To maintain your application along with each Android release, you should increase the value of this attribute to match the latest API level, then thoroughly test your application on the corresponding platform version.
Inexact timers in system alarm manager
In my app I used AlarmManager.setRepeating() to schedule the alarms. But in API 19 the behaviour changed and the repeating timers are inexact: they can happen any time between two successive intervals, and in my case it means they can happen anytime in the day since the alarm fires with a repeat period of one day. Since the objective of my app is the same as any alarm: to notify you at a specific time, it’s clear that’s not acceptable.
The fix was to use AlarmManager.setExact() instead, and write the code to repeat the alarm the next day.
Thoughts about backward compatibility
These two issues have been a bit of a hassle for me: I wrote an application that worked, then it didn’t work any more. By distributing an app that didn’t work well I probably caused discomfort, especially since the app is supposed to do something reliably that could have impact on your life: waking you up at the wrong time or crashing altogether without waking you up can have big effect on your plans.
Google developers took care of the second issue in a graceful way: if I didn’t raise the targetSdkVersion, the behaviour would have been the same.
The first issue is a more delicate one because it involves security and the privacy of your own data: previously an app could scan your storage without asking for permissions. In this case Google developer chose a compromise between security and usability that rendered KitKat devices secure at the cost of breaking many apps. There have been some talks about it, as I recently found out, and I think the solution is correct as long as you communicate properly to the user what they should expect: if an app doesn’t work properly, they should not blindly blame the developers but understand that it might be a matter of improving their security. I think this issue is bigger for apps that you buy, but in my case Fake Dawn is free open source software, distributed with GPL3, without warranties, so at least from a legal point of view I’m in the clear.
Anyway, the app is now updated with multiple bug fixes. Enjoy your mornings!