One of my pet projects shows notifications on specific dates defined by user. I use
AlarmManger.setRepeating(AlarmManager.RTC_WAKEUP, millis, AlarmManager.INTERVAL_DAY, pendingIntent)
to schedule daily alarm which launches app to decide if it should show notification today.
The problem is that sometimes daily alarm stops working. I know a number of reasons for that (device reboot, date/time change, app reinstall, doze mode) and I am sure there are some reasons I did not find yet (ideas are welcome!).
My question is how to test alarms properly against all possible risks? Do instrumentation tests fit here?
Since AlarmManager is part of Android OS and therefore well tested, you don't have to do any instrumentation or unit tests to test it. You can test your services called by an alarm, but there is no need to test whether your alarm set properly or not.
Your app can set exact alarms using one of the following methods. These methods are ordered such that the ones closer to the bottom of the list serve more time-critical tasks but demand more system resources. Invoke an alarm at a nearly precise time in the future, as long as other battery-saving measures aren't in effect.
You can test your services called by an alarm, but there is no need to test whether your alarm set properly or not. There are only a few situations where your alarm is dropped, get invalid or ignored.
You can use blip blip (hourly chime) alarn apk. That can help you to schedule an alarm every one hour on your android devices... It is available on play store..
My question is how to test alarms properly against all possible risks? Do instrumentation tests fit here?
Since AlarmManager
is part of Android OS and therefore well tested, you don't have to do any instrumentation or unit tests to test it. You can test your services called by an alarm, but there is no need to test whether your alarm set properly or not.
There are only a few situations where your alarm is dropped, get invalid or ignored. You called them already:
Now what you can do, is to use the system notifications (OS broadcasts) to reconfigure your alarms.
On reboot
Alarm are dropped on device shutdown, so set it again on reboot
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
// set repeating alarm
MyAlarmMangerSupport.set(context);
}
}
}
On time change
The same procedure on time change:
public class TimeChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_TIME_CHANGED.equals(action ) || Intent.ACTION_TIMEZONE_CHANGED.equals(action )) {
// cancel previous alarm and set a new one
MyAlarmMangerSupport.cancelAndSet(context);
}
}
}
On doze mode
I believe there is no need to show any irrelevant notifications if a device entered the doze mode
Anyway, there is a way to get an alarm fired even if a device is in doze.
It's important to know, that doze mode is a new feature starting from API level 23.
Users have to whitelist your app and disable Battery Optimization for your app.
Use setExactAndAllowWhileIdle
method to set your alarm for devices with android level 23+:
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, period, pendingIntent);
Important: This as an single shot alarm you have to set it again in your alarm receiver:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if ("my-Pet-Notification".equals(action )) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
// set repeating alarm, calls setExactAndAllowWhileIdle
MyAlarmMangerSupport.set(context);
}
//execute service to show notification
[..]
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With