For example, i have a calendar, which allows user to set every day alarm. For this function i took alarm manager's method setRepeating(). But my problem comes when user wants to delete alarm from specific day, but not deleting all alarms. How can i make that? Is alarm manager the only way to set alarms? Any ideas will be appreciated.
Cleverest thing i came up - to set broadcast receiver which will trigger every day at 00:00 and set all alarms by method alarmManager.set(). Deleted alarms will be at database and if today alarm will match to deleted one - broadcast receiver will not set this alarm.
AlarmManager has a method cancel(); and it may help you. But in your case I would have been more confident with going the approach you given as a hind in your question.
you can use .cancel() method of Alarm manager..But remember one thing.You have to give the same id in the pending intent that you supply to the alarm manager to that you had set the alarm with.
PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(),id,intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.cancel(pendingIntent);
the id supplied should be the same that was used to set the alarm.
I hope that will help you..
I would suggest you to save the id for each alarms somewhere and use it to cancel it if you need to.
Related
I'm trying to create a function in my App, which notifies the user at the expiration day of his rented books. I'll work with checkboxes in a listview, as below:
(Dates are for show purposes only)
Now i'm wondering how can i do it the best way. I'm having experiences with AlarmManager and BroadcastReceivers, but I didn't get a clear flowchart yet.
Thats because I need to set an specific alarm to each book and cancel that specific alarm when requested. Also, it needs to reactivate all Alarms when device is restared (by calling BOOT_COMPLETE broadcast).
PS.: Alarms will usually be set to one week after current date.
PS2.: Can I use Calendar to do it? I mean, this way i wouldn't have to reactivate all alarms, or calculate (expirationDate - currentDate) in millis.
Can someone, who has an idea, try to show me the way? Thanks!
I think the key would be to give each and every book its own alarm id as soon as you set the alarm for this book for the first time.
Then you should keep a list of the running alarm ids and timestamps (maybe in SharedPreferences).
With a method like this you can cancel a specific alarm with regards to its alarm id:
public static void cancelAlarm(Context context, int alarmId) {
PendingIntent pi = PendingIntent.getService(context, alarmId,
new Intent(context, YourService.class),
PendingIntent.FLAG_NO_CREATE);
if(pi!=null) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
}
}
When you receive the BOOT broadcast, you can get the list of alarm ids together with timestamps from SharedPreferences and start all the alarms with their respective alarm ids
I have used the below code to set the alarm,
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
activeModeTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
getActiveModeAlarmPendingIntent());
Every time when my app starts in the Home screen activity I am setting the alarm again and again.
I know that all scheduled alarm will be cancelled once the device goes power off. Once the power is on all the alarms will be scheduled again.
But I don't know how to check the alarm has been scheduled already or not every time when the app start.
And also please confirm the below,
Setting again again and again once the app starts will replace the old alarm and will be fired if the time passed already.
How to avoid of this multiple alarm setting by check the alarm scheduled or not programmatically?
Please help me on this.
Create an equivalent PendingIntent which you used with setRepeating() with PendingIntent.FLAG_NO_CREATE flag.
boolean isAlarmActive = (pendingIntent != null);
if (isAlarmActive) {
Log.d("TAG", "Alarm is already active");
}
While using PendingIntent.FLAG_NO_CREATE, if the described PendingIntent does not already exists, it simply return null.
I am writing an application in which user can configure alerts/alarms. At this point, I have everything working expect the one. I am firing off an alarm using
Intent alarmIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, "Some message!");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 1);
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, calendar.get(Calendar.HOUR_OF_DAY));
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, calendar.get(Calendar.MINUTE));
alarmIntent.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
context.startActivity(alarmIntent);
I want to remove this alarm once user has dismissed using the Dismiss button. I can see the alarms being still there in the alarm clock which I set using above code through my application.
Is there some way to get a cursor or something similar on the alarms being there in the alarm clock? This will help me iterate over them and remove the ones I want.
Any help would be appreciated, Thanks in advance.
As it was answered here: there is no supported API to this.
Official documentation says that
If a time of day is specified, and EXTRA_SKIP_UI is true, and the
alarm is not repeating, the implementation should remove this alarm
after it has been dismissed.
But different manufactures implement their own alarm clocks and I'm not sure if someone supporrts this.
I have tried it on JB emulator and looks like it dosen't work. Maybe, on KitKat?
Only this one is ok on JB:
If an identical alarm exists matching all parameters, the implementation
may re-use it instead of creating a new one
So, maybe, better solution is to use youre own alarm, created with AlarmManager or warn user that he has to remove Alarms by hands (to make it more obvious - not use AlarmClock.EXTRA_SKIP_UI).
call method cancel(...) from AlarmManager, using the same PendingIntent you used to set the alarm. Example:
mAlarmPendingIntent = PendingIntent.getActivity(this, requestCode, intent, flags);
this.getAlarmManager().cancel(mAlarmPendingIntent);
this refers to the Activity or the Service from which you are cancelling the alarm
Couple of question on Alarm registration and starting service on trigger.
If an alarm is set at couple of mins ahead of current time and then if phone is made switch off, will the alarm trigger on next phone switch on after the schedule time passed?
How to cancel / update pending intent in service? How to get request code in startCommand() method of service?
Will there be a multiple instances of service created if the alarm is triggered after every 10 seconds?
If "switch off" means full power down and not just "once shortly press power button to turn screen off" the answer is "no"
I think you can't get request code at all. As the documentation on getService states, the requestCode field is "currently not used". You should pass all your data with Intent (third arg of getService).
Will not. See http://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent)
Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method
Store the time of the alarm in SharedPreferences. Then register a receiver for android.intent.action.BOOT_COMPLETED (remembering to add a permission for android.permission.RECEIVE_BOOT_COMPLETED to your manifest), and then in the receiver, which will execute on startup, you can see if the alarm's in SharedPreferences, and if so you can reset it if it hasn't passed yet, or decide what to do if the time has already passed.
See problem with cancel the alarm manager pending intent
No. The service's onCreate will only be called once. Its onStart and onStartCommand will be called each time.
From my own app that I'm developing, if an alarm is set for a time when the phone is turned off, it has been executed on the next phone on/boot. That is without a receiver for BOOT_COMPLETED being present. I am unsure if this is expected behaviour or not, or whether it is consistent over phone variants.
I believe if you wish to have your alarm execute the intent at its specified time, you need to use a getBroadcast PendingIntent with a WakeLock as other variants of PendingIntent do not guarantee that phone will remain awake long-enough before it shuts down again. This is information from another post here by CommonsWare, that I will try to find and link to.
I believe you can remove the pendingintent sent to the alarm manager using, for example, a function like:
public void unregisterEvent(PendingIntent sender) { ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).cancel(sender);
}
where the PendingIntent has been created exactly as the original intent you are trying to remove. You can update it by supplying the correct id along with a new PendingIntent when calling AlarmManager again:
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
This is what I use to create/rebuild the PendingIntent:
PendingIntent.getService(this, uniqueIndexToIntent, theIntentItself, PendingIntent.FLAG_UPDATE_CURRENT);
The flag will update the intent if it already exists, or will create a new one otherwise.
I don't think it will. However, I'd recommend having your Service call stopSelf() once it has finished doing its work, so that battery usage is minimised. No need to have it running if it has nothing to do!
I am adding an event to my schedule
list and alarm has been fixed to that
event. I have to repeat alarm for
every one minute, from the before five
minutes of event ending time. In below
conditions I have to remove or cancel
alarm for particular event.
When I delete event from my schedule.
Event placed in schedules but I don't want alarm for event.
I am following concepts like sqlite database, Alarm manger, Services. I am confusing little bit using Services and pendingIntent. So, please suggest me the right way to approach my requirement.
You need to use the method cancel(...) from AlarmManager, using the same PendingIntent you used to set the alarm. Example:
this.getAlarmManager().cancel(mAlarmPendingIntent);
(this refers to the Activity or the Service from which you are cancelling the alarm).
Here is the link for the API.
Create the PendingIntent as:
mAlarmPendingIntent = PendingIntent.getActivity(this, requestCode, intent, flags);
The API doc for PendingIntent is here.