Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force stop application - also cancels any alarms it had set?

Tags:

android

My app is setting an alarm:

AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.setRepeating(
  AlarmManager.RTC_WAKEUP, 
  firstRun, 
  interval, 
  makePendingIntent(context));

Works fine. If I go into system settings -> applications, and force-stop my app, it seems that this also has the effect of canceling any alarms I had scheduled. Is this true? If so, I'm in a weird situation where my last-known settings are that the user had in fact set the alarm, but the system may have canceled behind my back, so I'm now showing the user the wrong status as to whether the alarm is set or not.

Thanks

like image 854
user291701 Avatar asked Mar 25 '11 15:03

user291701


1 Answers

Yes, it's true. All you can do, as far as I know, is to make your status right. To check if your alarms are still there you have to take 2 steps:

  1. Atempt to create your PendingIntent with FLAG_NO_CREATE - the function checkPendingIntent will be exactly like makePendingIntent except for this flag in PendingIntent.getBroadcast and a check of the result - if the alarm has been canceled in an ordinary way (by yourself, of course if you called cancel() for your PendingIntents) or if your app crashed without Force Stop (i.e. with an uncaught exception), PendingIntent.getBroadcast will return null.
  2. If the PendingIntent exists your alarm might be set. To check it you have to dump system information about all alarms and search for yours there. To dump the info you have to call

    String collectAlarmsInfo() {
        StringBuilder result = new StringBuilder();
        try {
            Process process = Runtime.getRuntime().exec("dumpsys alarm");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                result.append(line);
                result.append("\n");
            }
        } catch (IOException e) {
            Log.e(TAG, "Could not retrieve data", e);
        }
        return result.toString();
    }
    

    To use dumpsys you need to have user-permission DUMP. When you have the dump you can identify you alarms in it by you package name, so the check will be

    boolean alarmIsSet = collectAlarmsInfo().contains(<your package name>);
    
like image 172
lapis Avatar answered Nov 01 '22 10:11

lapis