I use AlarmManager to display a notification for an event at the event date and time. But how can I update the time the AlarmManager sends the PendingIndent to my app, when an event is updated?
When an event is created the following code is called:
public void setOneTimeAlarm() {
Intent intent = new Intent(this, TimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day-1);
c.set(Calendar.HOUR_OF_DAY, 18);
c.set(Calendar.MINUTE, 00);
long date = c.getTimeInMillis();
mAlarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
}
The indent called is TimerReciver:
@Override
public void onReceive(Context context, Intent intent) {
Log.v("TimerReceiver", "onReceive called!");
Intent notificationIntent = new Intent(context, ListTests.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,
123, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = context.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
long[] pattern = {0,300};
builder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
.setTicker(res.getString(R.string.app_name))
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setVibrate(pattern)
.setContentTitle(res.getString(R.string.notification_title))
.setContentText(res.getString(R.string.notification_text));
Notification n = builder.build();
nm.notify(789, n);
}
IntentService + WakefulBroadcastReceiver + AlarmManager are deprecated with API 26 (Android 8.0 Oreo).
Open your phone's Clock app . At the bottom, tap Alarm. On the alarm you want, tap the Down arrow . Cancel: To cancel an alarm scheduled to go off in the next 2 hours, tap Dismiss.
Alarms only. Unlike WorkManager, AlarmManager wakes a device from Doze mode. It is therefore not efficient in terms of power and resource management. Only use it for precise alarms or notifications such as calendar events — not background work.
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.
I found the solution.. I turns out that the second argument to getBroadcast(Context context, int requestCode, Intent intent, int flags)
makes the difference, even when the documentation says
requestCode Private request code for the sender (currently not used).
When a request id is used for each event, the alarm is updated and alarms are created for each event.
The reason is that with two different request codes, the filterEquals(Intent)
will be false. Documentation of AlarmManager set(...)
says:
If the time occurs in the past, the alarm will be triggered immediately. If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by
filterEquals(Intent))
, then it will be removed and replaced by this one.
I also changed PendingIntent.FLAG_ONE_SHOT
to PendingIndent.FLAG_CANCEL_CURRENT
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With