5

I'm fairly new to Android, so please forgive my naiveté.

The app I am working on needs to wake up every hour and do some background data collection. I'm using AlarmManager to set a repeating alarm that starts the service.

I'm currently setting up the alarm in the MainActivity in the onCreate method. My concern is that if the app is closed and reopened and the onCreate method is called again, it would duplicate the alarms. Am I incorrect in assuming this?

One way I'm thinking about circumventing this to use a boolean in SharedPreferences. Is there a more standard way of approaching this issue?

Thank you!

  • I think the user should have the option to set the alarm versus the alarm automatically being created in the onCreate method. That way, the user can decide whether or not to set multiple alarms. – krikara May 17 '15 at 16:17

2 Answers2

5

You can set alarm once avoiding duplicates without any problem.

  1. You can statically set broadcast receiver once the OS finishes booting. Register pending intent via PendingIntent.getService() and configure the AlarmManager in the receiver's onReceive() method.

  2. Please note also that every method PendingIntent.getBroadcast(), PendingIntent.getService(), PendingIntent.getActivity() or PendingIntent.getActivities() has flags parameter. You can request your PendingIntent with PendingIntent.FLAG_NO_CREATE flag set. This means that if the system has identical PendingIntent registered then the null is returned. Otherwise new PendingIntent instance is created. Thus, you can rely on this flag to check if your alarm is already set.

Read more about PendingIntent in my response to the similar problem, please(Usage of PendingIntent.cancel() and AlarmManager.cancel()).

Basically, you can still rely on setting your alarm in launching activity by checking first whether you have PendingIntent registered thanks to the PendingIntent.FLAG_NO_CREATE set.

Hope you now understand how to do it.

Community
  • 1
  • 1
dawid gdanski
  • 2,432
  • 3
  • 21
  • 29
  • 2
    On point 2, if my reading of the docs is correct then it sounds like you have it backwards. Null will be returned if the Intent _isn't_ already registered, not if it is. https://developer.android.com/reference/android/app/PendingIntent.html#FLAG_NO_CREATE – aaronmarino Apr 06 '17 at 14:36
3

In onCreate I would probably just cancel all alarms, then set a new alarm. Psuedo code would be something like

  1. Create pending intent for your alarm
  2. call AlarmManager.cancel with that pending intent http://developer.android.com/reference/android/app/AlarmManager.html#cancel%28android.app.PendingIntent%29
  3. set your alarm with the same pending intent.
Sam Dozor
  • 40,335
  • 6
  • 42
  • 42
  • Ah. I see! Thank you. That makes sense. Do you think onCreate is the correct place to do something like this? Thanks again. –  May 17 '15 at 17:06
  • If you have an `Application` class that's a little better suited. Also, alarms are cleared on every reboot, so you'll need a `BroadcastReceiver` that listens for the boot completed broadcast so you can reset your alarms. – Sam Dozor May 17 '15 at 18:46
  • `if (!TextUtils.isEmpty(userId) && alarmManager == null) { alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(MainScreenActivity.this, AlarmReceive.class); pendingIntent = PendingIntent.getBroadcast(MainScreenActivity.this, 0, intent, 0); alarmManager.cancel(pendingIntent); alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constants.trackTimeInterval, pendingIntent); // every 60 minutes }` Is this right way? – Shailendra Madda Apr 05 '18 at 11:12