Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best moment/location for setting an AlarmManager

My application shows content for a site that also has a notification system. I want to show if there are new notifications, and I am using an AlarmManager that calls an IntentService.

My question is: where should I start/register this AlarmManager? I've put it in the onCreate() of my activity just for proof-of-concept (and its working fine, thank you very much :) ), but if you would start that activity twice, you would get multiple alarms.

The only possible solution I've come up with is this, but I don't know if this would be best practice

  • Start the manager in an onCreate() if the preference "alarm started" is false
  • Set some variable that it is started in preferences.

Now if the alarm stops for some reason, there's no way to restart it. So, a variation would be:

  • Always call cancel in the onCreate()
  • And then always set the Alarm.

This seems like a common pattern: Wanting to periodically get information with an alarm, and not setting that alarm more then once. How should I do this? When, where and how to register the alarm?

Also, continueing on @Zelimir 's comment: can you check if a certain alarm is allready set?

Ideally, the alarm would be set regardless of the activity being started or not of course, but that might be another thing.

For completeness, this is the code I'm currently using to start the alarm:

AlarmManager alMan   = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i             = new Intent(this, CommentService.class);
PendingIntent penInt = PendingIntent.getService(this, 0, i, 0);

alMan.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                          SystemClock.elapsedRealtime(), 
                          AlarmManager.INTERVAL_FIFTEEN_MINUTES, 
                          penInt);

For even more completeness, the app description / situation.
The app is basically showing blogs (journals if you will) from a certain page. It has activities for adding entry, viewing entries, adding comments, etc. On the 'mother' site there is an option to recieve notifications (like the number you see here on SO too when you get a message). I want to show if there are new messages, and so retrieve them every xx minutes. It would be shown in the notificationbar for now, but it might feed some sort of widget later.

If you need more info: the app is called Androblip and it supports a site called blipfoto.com

like image 334
Nanne Avatar asked Mar 16 '11 09:03

Nanne


People also ask

Is AlarmManager deprecated?

IntentService + WakefulBroadcastReceiver + AlarmManager are deprecated with API 26 (Android 8.0 Oreo).

How does an application get access to the AlarmManager?

How does an application get access to the AlarmManager? Use the AlarmManager() constructor to create an instance of the AlarmManager. Use the AlarmManager. newInstance() method to retrieve the singleton instance of the AlarmManager.

How is AlarmManager different from WorkManager?

Should I use WorkManager to get the time when I need to alarm and than use AlarmManager ? If you want to use this approach you need to call AlarmManager and dispatch a Worker on WorkManager. The WorkManager need to run before a specific time and is not guaranteed that the Worker finish or will be executed before 4.30.

In which API level did inexact timing become the default for AlarmManager?

The way that AlarmManager works was changed in API level 19 to help save battery life. It was so that events could be batched. What this means is that set() and setRepeating() will be inexact on API 19+. In API versions before 19, you can just use set, which will schedule an alarm for the exact time.


1 Answers

When, where and how to register the alarm?

That is impossible to answer in the abstract. It depends entirely upon what the business rules are for your app, which you declined to supply in your question.

If the monitoring is to be happening all the time, a typical pattern is to register the alarm:

  • in onCreate() of your main activity for the very first run of your app
  • in a BOOT_COMPLETED BroadcastReceiver, to handle reboots, which wipe the AlarmManager roster

can you check if a certain alarm is allready set?

No, but you can cancel it without issue. Just create an equivalent PendingIntent and call cancel() on the AlarmManager.

like image 124
CommonsWare Avatar answered Sep 19 '22 07:09

CommonsWare