0

I'm using AlarmManager to have a background HTTP request occur every 2 minutes, which can result in a notification to the user depending on the response. This code runs before each request, scheduling the subsequent request:

AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyReceiver.class);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP
    , SystemClock.elapsedRealtime() + CHECK_INTERVAL
    , PendingIntent.getBroadcast(context, 0, intent, 0));

Sometimes an exception occurs, but according to the logs, it was after the call to manager.set was completed successfully. Unfortunately, I'm finding the alarm does not fire after unexpected stop. Correction: didn't fire, perhaps because it took more than 2 minutes for the user to acknowledge the 'unexpected popup' dialog.

Is there a way to make my 'scheduling' to be crash-resistant? The users do not always restart this particular app after seeing the unexpected stop message.

Since the app is not available on Google Play Store for most people, I'm considering implementing an error-reporting and auto-restart via Thread.setDefaultUncaughtExceptionHandler(), but I'm not ready to develop that far at this time; because then we'd lose the possibility of native error reporting for those who have it through Google Play. Is there a better approach to get the HTTP requests to continue after a crash, or is this it?

I know that fixing the cause of the crash would also take care of it, but I'm not perfect, so we should have a fallback plan.

Community
  • 1
  • 1
700 Software
  • 85,281
  • 83
  • 234
  • 341
  • You could try setting the alarms through a service as a process. – Eric Martinez May 26 '15 at 22:55
  • 1
    Why aren't you using `setRepeating()`, instead of `set()`, since your interval is fixed? Admittedly, that may be a short-term fix, as once your `targetSdkVersion` reaches 19 or higher, there is no more exact-repeating option, but it might be a stopgap while you experiment further. – CommonsWare May 26 '15 at 23:04
  • @Commons, I didn't know you could. Would that be crash-resistant? – 700 Software May 26 '15 at 23:05
  • My guess is that it will be better. However, please understand that the answer of mine that you linked to was for a *very specific behavior*: the user going into Settings and clicking Force Stop. My answer there does not address unhandled exceptions which AFAIK do not affect already-scheduled alarms. – CommonsWare May 26 '15 at 23:07
  • @CommonsWare, Thanks for pointing that out. I mis-understood. I thought this was after clicking 'force stop' (since renamed) button on the 'crashed' (now called 'unexpected stop') dialog. – 700 Software May 26 '15 at 23:27
  • I'm guessing that the reason it didn't fire was that the 'unexpected stop' dialog was left open for more than 2 minutes. Seems that setRepeating would certainly take care of that. I'm signing off until tomorrow morning, but welcome additional input. I'll have ping-pong with the client if I'm not careful. – 700 Software May 26 '15 at 23:29

1 Answers1

0

As CommonsWare suggested, using setRepeating works. This will continue even after an unexpected stop. Plus it simplifies my code.

See Android's documentation before using, as of API 19 this now maps to setInexactRepeating. This will still run alarm every 2 minutes on average, but alarms from various apps are shifted up to one interval (2 minutes in my case) so that multiple alarms are grouped together. This reduces the number of wakes and maximizes phone sleep time to improve battery life.

700 Software
  • 85,281
  • 83
  • 234
  • 341