I'm having an app in which I need to set some local notifications with the data I have. I am able to get the local notifications for the hard coded time value using AlarmManager, PendingIntent and BroadcastReciever.
Now my question is I need to set up the local notifications/reminders from a start date to end date and it can be 1-4 times per day(i.e Frequenecy can be 1-4 with 4 different times).
Say
Start Date : June 3 2019
END Date : June 30 2019
Frequency : 2 times a day at 9:00 AM(Time1) and 6.00PM(Time2)
Starting from June 3rd I should get Local Notifications every day at 9.00 AM and 6.00 PM till June 30th.
Updated Issue Last pending Notification is getting showed every time when I run the app i.e if I have one notification scheduled for 5.30 PM today and if I run the app at 6.00 PM my app is showing the 5.30 PM notification.Similarly if I have my last notification scheduled yesterday at some 7.00 PM say, it is getting showed today when I run the app. How to cancel or clear that notification.
*Main Activity method
scheduleNotificationsMethod() {
AlarmManager alarmManager = (AlarmManager) mCtx.getSystemService(ALARM_SERVICE);
if(treatment.getSCHEDULE().equalsIgnoreCase("Daily")) {
String[] times = {treatment.getTIME1(), treatment.getTIME2(), treatment.getTIME3(), treatment.getTIME4()};
for(String time : times) {
if(time != null && time != "") {
Calendar calendar = Calendar.getInstance();
calendar.setTime(fromISO8601UTC(time));
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
date1 = createDate(hours, minutes);
time1 = date1.getTime();
intent.putExtra(MEDICINE_TIME, toISO8601UTC(fromISO8601UTC(time)));
intent.putExtra(END_DATE, treatment.getEndDate());
String reqCode1 = treatment.getID()+""+treatment.getMedicineName()+""+hours+""+minutes;
int req1 = reqCode1.hashCode();
intent.putExtra(REQUEST_CODE, req1);
pendingIntent1 = PendingIntent.getBroadcast(mCtx, req1, intent, 0);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, time1, AlarmManager.INTERVAL_DAY, pendingIntent1);
}
}
}
}
Notification Receiver Class
public class NotificationReciever extends BroadcastReceiver {
private final String CHANNEL_ID = "personal_notifications";
public static String NOTIFICATION_MESSAGE = "notificationMessage";
private Context context;
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("Utils Inside NotificationReciever onReceive");
String message = intent.getStringExtra(NOTIFICATION_MESSAGE);
this.context = context;
context.sendBroadcast(new Intent("SHOW_ALERT_CARD"));
String action = "It's time to take your medicine!";
String endDate = intent.getStringExtra("END_DATE");
String msg = intent.getStringExtra("MEDICINE_TIME");
int requestCode = intent.getIntExtra("REQUEST_CODE", 0);
Intent resultIntent = new Intent(context, MainActivity.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 100, resultIntent, 0);
buildNotification(context, pendingIntent, msg);
public void buildNotification(Context context, PendingIntent pendingIntent, String msg) {
System.out.println("Utils Inside callTheMethod");
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
int color = 0xffffaa00;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
builder.setSmallIcon(R.drawable.ic_dosage_c);
builder.setContentIntent(pendingIntent);
builder.setContentTitle("It's time to take your medicine!");
builder.setAutoCancel(true);
builder.setContentText(msg);
builder.setSound(soundUri);
builder.setLights(Color.RED, 1000, 1000);
builder.setColor(color);
Notification notification = builder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(102938, notification);
}
}
You can set as many alarms as you like. The trick here is to make sure that they are considered "unique" by the AlarmManager
. To make them "unique" you can use one of the following methods:
requestCode
parameter in the call to PendingIntent.getBroadcast()
Intent
you pass to PendingIntent.getBroadcast()
There is no way to set an alarm to repeat on a daily basis for a certain number of days. However, you can set an alarm to repeat every day and when the alarm triggers, check in your BroadcastReceiver
if the alarm has triggered for the last time, and if so, cancel it so that it doesn't trigger any more in the future. To do this, you will need to remember the day that it "expires", which you can do by either storing that information in a database or SharedPreferences
, or by adding this information as an "extra" to the Intent
which is passed to the BroadcastReceiver
.
NOTE: Android has many rules about scheduling alarms to try to optimize battery life. If your alarm doesn't need to trigger at an exact time, Android will modify the schedule to a more optimal time. There are ways to get the alarm to trigger at an exact time, but you cannot reliably set a repeating exact time alarm. If you need exact time, schedule the alarm once and when it triggers, schedule the next one. Read about the way AlarmManager
works and how to best schedule your alarms on https://developer.android.com/training/scheduling/alarms