I am setting an alarm for my reminder app:
PendingIntent sender = PendingIntent.getBroadcast(AddToDoList.this,
Integer.parseInt(DBHelperClass.getMaxPrimaryId()), intent, 0);
i am using a unique value (primary ID) to set an alarm. When i want to edit the alarm i am using the same key. But what i see is that both the alarms go off! original as well as edited one.
how do i cancel the old alarm ?
Also these alarms are not working once i switchOff & then again switchOn my device .
how do i cancel the old alarm ?
Call cancel() with your original PendingIntent.
Also these alarms are not working once
i switchOff & then again switchOn my
device .
Alarms do not persist after a reboot. You will need to reschedule the alarms, possibly by a BroadcastReceiver that gets control at boot time.
You should consider changing the way you make Intents unique - requestCode is not officially defined. Try keeping Intent's data different for example.
About persisting the alarm trough reboots, I'm not sure but maybe RTC_WAKEUP flag is the closest you can get.
Related
I am currently developing an android application where I need to setup persistent alarms that will fire on a specific date and time and show a notification. It works well but the system clears all alarms upon rebooting.
From other questions I know that if I create a BroadcastReceiver forBOOT_COMPLETED I can rearm canceled alarms. My question is: What information about those alarms I need to keep in order to rearm them when needed?
Some people say that I need to persist all the Intent extras and the fire datetime in order to recreate the PendingIntent upon rebooting.
Others say that if I only persist the requestCode for the PendingIntent, after reboot I can use this code to get the canceled PendingIntent and rearm the alarm, because when the device reboots the PendingIntent's are just canceled instead of deleted.
Which one is right way to do it?
PendingIntents will not persist after reboot, so to be safe just restart your alarms in the BroadcastReceiver with all the intent extras that you make when you first initialized the alarm, and keep the requestcode the same.
I'm making an application in which I have implemented a reminder using AlarmManager. Now, if the user wants to cancel this alarm, how can I do the same?
Also, once the application has asked for alarm services(using alarm manager) and set an alarm, then can we get the details of the alarm we set?
http://developer.android.com/reference/android/app/AlarmManager.html
Yes, you can cancel the alarm. Make sure you're using the same PendingIntent you used when creating the alarm.
What details are you looking for? Perhaps its best to store these using SharedPreferences.
I need to do a background check in my app, basically polling various URLs for new stuff. So I've read this is done with the AlarmManager.
The thing is, I don't need the user to be notified as soon as new stuff arrives. Let's say I'm checking every hour, I'm perfectly fine with not doing any check while the phone is sleeping, and resuming the checks when the phone is used. That way the user eventually gets the notification, but the drain is minimal.
So I've tried with setInExactRepeating. I'm starting it at boot time, but also at app startup (mostly for the session after install, and to make sure it's running even if the app gets "force killed"). How do I prevent all these checks to add up? (A new check should only be run if none is running, or the previous one needs to be stopped).
I've found setInexact Repeating coupled with ELAPSED_REALTIME (or RTC) works quite well to achieve very minimal battery drain. Using the flag FLAG_UPDATE_CURRENT on an existing pendingintent (same intent and id) will simply refresh the current alarm schedule if it already exists. Alternatively, add the code suggested by Ralgha to check and see if you already created the pending intent and set the alarm, and then if not, set the pending intent and alarm schedule. Both methods will likely have the same impact on battery (negligible). What will cause significant drain is doing something on a frequent schedule. The fact that you only want to update every hour and not when the screen is off, your app will use barely any battery (assuming it is done with it's processing relatively quickly and cleans up after itself nicely)
http://developer.android.com/reference/android/app/AlarmManager.html#ELAPSED_REALTIME
ELAPSED_REALTIME
This alarm does not wake the device up; if it goes off while the device is asleep, it will not be delivered until the next time the device wakes up.
http://developer.android.com/reference/android/app/AlarmManager.html#setInexactRepeating%28int,%20long,%20long,%20android.app.PendingIntent%29
setInexactRepeating
These alarms are more power-efficient than the strict recurrences supplied by setRepeating(int, long, long, PendingIntent), since the system can adjust alarms' phase to cause them to fire simultaneously, avoiding waking the device from sleep more than necessary.
http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_UPDATE_CURRENT
FLAG_UPDATE_CURRENT
...if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.
You can check to see if the alarm is already set before you set it, and you can also use a flag so the alarm won't be delivered until the device is awake.
if ( PendingIntent.getBroadcast( context, 0, updateIntent, PendingIntent.FLAG_NO_CREATE ) == null )
{
pendingIntent = PendingIntent.getBroadcast( context, 0, updateIntent, 0 );
getSystemService( ALARM_SERVICE ).setInexactRepeating( AlarmManager.RTC, System.currentTimeMillis(), AlarmManager.INTERVAL_HOUR, pendingIntent );
}
Is there any way to use AlarmManager to activate an alarm for a specific period of time? I have start-time and end-time values stored in the database. I want to start an alarm at start-time that will make the device silent and alarm should end at end-time when the device volume will be normal again.
One way is set alarm at start-time & then set another alarm at end-time. But the problem is the time period may overlap that will need additional logic to be implemented if I go with 2 different alarms(one at start-time, another at end-time). Is there any procedure in Android to cope with this situation? Or implementing logic is the only way to overcome this issue?
Why not just in your Intent for the PendingIntent pass an extra like "endTime" long type for the time you want to end the alarm. (im assuming its repetitive) then in your broadcast receiver get that extra, compare to System.currentTimeMillis() and if it is less then current time cancel the alarm and exit?
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
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.