How does AlarmManager.AlarmClockInfo's PendingIntent work? - android

I am trying to use AlarmManager.AlarmClockInfo to set an alarm.
The constructor to this takes the time and a PendingIntent which is described in the docs as:
an intent that can be used to show or edit details of the alarm clock.
and then setAlarmClock( ) also takes in a pending intent which is described in the docs as:
Action to perform when the alarm goes off
I understand the use of the PendingIntent by setAlarmClock( ), however, how is the PendingIntent used by AlarmClockInfo and how do I use it to edit the details of the alarm clock?

however, how is the PendingIntent used by AlarmClockInfo and how do I use it to edit the details of the alarm clock?
Quoting myself from this book:
The biggest issue with setAlarmClock() is that it is visible to the
user:
The user will see the alarm clock icon in their status bar, as if
they had set an alarm with their device's built-in alarm clock app
The user will see the time of the alarm when they fully slide open
their notification shade
Tapping on the alarm time in the notification shade will invoke
the PendingIntent that you put into the AlarmClockInfo object
So, given this code...:
static void scheduleAlarms(Context ctxt) {
AlarmManager mgr=
(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(ctxt, PollReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(ctxt, 0, i, 0);
Intent i2=new Intent(ctxt, EventDemoActivity.class);
PendingIntent pi2=PendingIntent.getActivity(ctxt, 0, i2, 0);
AlarmManager.AlarmClockInfo ac=
new AlarmManager.AlarmClockInfo(System.currentTimeMillis()+PERIOD,
pi2);
mgr.setAlarmClock(ac, pi);
}
(from this sample project)
...when the user taps on the time in the notification shade, EventDemoActivity will appear. The idea is that you should supply an activity here that allows the user to cancel or reschedule this alarm.

Related

Android widget change alarm interval

I have created a configure activity for my widget, where the user can choose from various update frequencies.. Until now I started the alarm in the OnEnabled() method, like this:
Intent intent = new Intent(CLOCK_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 1000 * 60,
pendingIntent);
The settings are saved in shared preferences with a unique name (widgetId) and in this OnEnabled() method I can't retrieve the settings here because I can't get the widgetId yet.
There's an another problem, the user can change the frequency anytime, but this method is called just once, at the beginning. So I think I need to start the alarm in OnUpdate(), but I don't know how to do it, I don't want to make multiple instances of an alarm accidentally so I would like to ask for some advice.
To answer your second problem, calling setRepeating multiple times will not create multiple alarm as far as you provide same PendingIntent and same request code along with PendingIntent.FLAG_UPDATE_CURRENT flag. I would also suggest to use setInexactRepeating instead of setRepeating. So you can use the same code in OnUpdate() too with new frequency. Go through docs of FLAG_UPDATE_CURRENT and setInexactRepeating for more detials.

how can i delete one alarm not all alarms?

i developed an android app to fire notification by alarm manager .
Now I want to cancel one alarm that fire a notification i saw this code but it deletes all alarms
how can i delete one alarm i want
Intent intent = new Intent(this, AlarmReceive.class);
PendingIntent sender = PendingIntent.getBroadcast(this,
0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
// this line for cancellation
alarmManager.cancel(sender);
The doc of cancel says:
Remove any alarms with a matching Intent. Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.
So, if you want to be able to delete a specific intent you must be able to differentiate all the intent you are launching.
If your intent is an explicit one, I suggest adding an Action after its creation.
In this way the filterEquals will take that into account and delete only the relevant one.
Something like:
Intent intentYouWantToCancel = new Intent(this, AlarmReceive.class);
intentYouWantToCancel.setAction("aRelevantString");
when you set the alarmmanager as well as when you want to delete it.

Delete AlarmManager Alarm ONLY for a Deleted Alarm

My app will have several alarms set simultaneously. Unfortunately, each alarm is being set with the same PendingIntent object. Here's the code I'm using to set the alarm:
//Use AlarmManager to trigger the notification/alarm.
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
//PendingIntent to launch activity when the alarm triggers.
Intent i = new Intent("com.testapp.DisplayNotification");
//Assign the reminder's primary key as the notification ID.
i.putExtra("Reminder_Name", editRemindMeTo.getText().toString());
i.putExtra("Reminder_Primary_Key", reminderPrimaryKey);
PendingIntent displayIntent = PendingIntent.getActivity(
getBaseContext(), 0, i, 0);
//Set the alarm to trigger.
alarmManager.set(AlarmManager.RTC_WAKEUP,
c.getTimeInMillis(), displayIntent);
I know that I can delete an alarm by using the following code:
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyPendingIntentService.class);
PendingIntent displayIntent = PendingIntent.getService(context, 0, i, 0);
alarmManager.cancel(displyIntent);
However, using this code will delete ALL my alarms (correct me if I'm wrong here). Is there a way to delete just the alarm that a user has deleted from the database? The alarm should be deleted from my app right after the user deletes an alarm entry in my app's database. I'm guessing that using different PendingIntent names would be the way to go, but I have no idea how to do this for each new alarm that a user creates. Thoughts on how to do this? Thanks!
See the same problem i faced here previously...
So the solution is to pass unique pending intent to the alarm service.. So here i how it can be done
PendingIntent pIntent = PendingIntent.getBroadcast(context, (int) alarm_id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
here in the pending intent i have passed unique request id to the pending intent. Which you have to remember while cancelling the alarm.
So in my case what i have done to generate the unique id is put it in the database i have retrieved the id of the tables row and passed to the pending Intent.
So if you want to cancel the particular alarm you have to remember the same request id of the pending intent with the use of the same table entry...
I am sure it will work..
Use a different requestCode when registering each alarm. This is the second parameter of PendingIntent.getActivity/Service().
From the Android Documentation, cancel() will cancel all alarms with same pendingIntent. So the only way out is to create different pendingIntents. OR you could resort to scheduling repeating alarms as well, in this way you could use the same pendingIntents.

Best way to set multiple alarms when some are of repeating in nature in Android

I'm building a reminders application where one time, weekly, monthly reminders and we notify the user of the reminder on due date and time. Reminders can be updated any time by the user to update the reminding time or delete the reminder altogether. I have thought of two ways I can solve the particular problem.
Whenever user sets a reminder, schedule an alarm accordingly with an unique Id and update or delete it in case user updates or deletes the alarm.
Since I store the reminding time in DB, better approach would be to schedule an alarm for the nearest reminder. And have the Service which is triggered by the alarm schedule a new alarm for the next nearest reminder.
2nd approach seems clean approach but how do we tackle the case where the Service triggered by alarm gets killed by the system before it schedules a new alarm for the next reminder?
Edit
Looks like if the system kills a Service for memory, it will re-create the Service. Does it mean it is safe to rely on the Service to schedule alarm every time it is run?
Edit 2
I've realized that Android kills any alarms whenever the device is restarted. This makes approach 2 a better solution. I've implemented it for now.
The pending intent needs to be created exactly in the same way for canceling the already set alarm. You can cancel previous alarm when you set a new alarm, if you want to have a single alarm activated at some time.
For setting alarm use:
Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, now.getTimeInMillis(), pendingIntent);
For canceling the alarm use:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent);

use Alarm Manager to set alarm in Android

In my Android application I would like to set alarm at a particular time with some message for time entered by user.
How can I set alarm using broadcast receiver? Is it possible to pop up a message on the specified time other than the default message?
AlarmManager alr = (AlarmManager) this.getSystemService(ALARM_SERVICE);
Intent intent = new Intent("YourAction");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0/** som unique id*/, intent, 0);
alr.set(AlarmManager.ELAPSED_REALTIME, 0/** here is a delay*/, pendingIntent);
after that you should create a BroadcastReceiver, that will get intent with action = "YourAction". From that receiver you can start an activity which will shoiw you the dialog with your custom messages. See this answer to see how to setup the BroadcastReceiver.

Categories

Resources