In Android Alarm Manager, how can we schedule multiple alarms which are non-repeating and do not have fixed intervals to repeat? I cannot use ‘setRepeating’ function as the alarms don’t have any repeating pattern.
I have the alarm times stored in Sqlite database table and the activity should pick the date and time from this table and set the alarms.
If we setup different alarms in a loop, then it retains only the last one.
I read from the post: How can create more than one alarm?
It tells to attach the unique Id to the intent and then setting up individual alarm events. But it didn’t work for me.
Is there something we need to add in Manifest file to take care of this unique id?
The code in the activity ‘RegularSchedule’ is and it creates only one alarm event:
while (notifCursor.moveToNext()) {
Intent intent = new Intent(RegularSchedule.this,
RepeatingAlarm.class);
// The cursor returns first column as unique ID
intent.setData(Uri.parse("timer:" + notifCursor.getInt(0)));
PendingIntent sender = PendingIntent.getBroadcast(
RegularSchedule.this, 0, intent, 0);
// Setting time in milliseconds taken from database table
cal.setTimeInMillis(notifCursor.getLong(1));
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}
Please let me know if further details or code snippets are required.
Manifest file (here RepeatingAlarm extends BroadcastReceiver):
<receiver android:name=".user_alerts.RepeatingAlarm" android:process=":remote" />
<activity android:name=".user_alerts.RegularSchedule"
android:label="@string/reg_schedule_title" android:theme="@android:style/Theme.Light">
</activity>
RepeatingAlarm:
public class RepeatingAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
.......
// The PendingIntent to launch our activity if the user selects this notification
Intent notificationIntent = new Intent (context, DisplayReminder.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults |= Notification.DEFAULT_LIGHTS;
mNotificationManager.notify(2425, notification);
This is what worked for me. I’m sharing the solution so that others can benefit and find quick solution to this problem.
I welcome any other inputs to throw more light on the technicality of the solution and why certain things work and others don’t 🙂
(1) First of all, Manifest file:
Make sure that you have receiver for your class having BroadcastReceiver.
Please note that the class is part of main package. If it is in some sub-package, please move to the main package. The main package is what you define in ‘manifest’ tag.
‘intent-filter’ is used to define ‘action’ and ‘data’. You can put the Activity class here which is going to be called from your pending intent. But I found that if you define ‘action’ in manifest, it doesn’t display dynamic values on the activity. It just shows static values. Quite strange. If you get in same issue, don’t put ‘action’ in manifest, rather put it in BroadcastReceiver class as part of pending intent.
‘data’ tag is what you are going to put dynamic URI of unique intents while scheduling different alarms using AlarmManager. Please refer next steps for more details.
(2) Activity Class in which you are going to use AlarmManager to schedule alarms:
I’m using the database to store my alarm time values and then scheduling using those values. My cursor fetches the unique _ID from the table and alarm time (in seconds since 1/1/1970). See that the URI put here is same as what you have in manifest file.
If you don’t see alarms even after doing this, check the timezone which emulator takes. Sometimes, we schedule for Local Timezone, but emulator schedules for GMT timezone. If you look at toast message, that will help you figure out this problem.
(3) Last one is BroadcastReceiver class. Please note that to open database, you will require to use the ‘context’:
Note that if you want to create separate notification, the request id can be passed as unique when calling notify().
Finally, you can create DisplayReminder class which you want to call when user clicks on notification.