Android daily re-notification at specific time of day with AlarmManager

I need an android app to send notifications to remind users at 8am, 3pm and 8pm every day. Thus, I use the following three lines in the onCreate () of the MainActivity when the app starts. However, when I launch the app, all three notifications come in at once and not at the right time.

    setRepeatedNotification(1,8,0,0); 
    setRepeatedNotification(2,15,0,0); 
    setRepeatedNotification(3,20,0,0);    

      

Why? Here I am attaching the setRepeatedNotification function as well. Thank!

private void setRepeatedNotification(int ID, int hh, int mm, int ss) {
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ID, alarmIntent, 0);

    Calendar calendar = Calendar.getInstance();
   // calendar.set();
    calendar.set(Calendar.HOUR_OF_DAY, hh);
    calendar.set(Calendar.MINUTE, mm);
    calendar.set(Calendar.SECOND, ss);

    // Clear previous everyday pending intent if exists.
    if (null != mEverydayPendingIntent) {
        alarmManager.cancel(mEverydayPendingIntent);
    }
    mEverydayPendingIntent = pendingIntent;
    alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mEverydayPendingIntent);
}

      

+3


source to share


2 answers


I see two potential problems with your setup with AlarmManager. The first occurs when the device goes to sleep.

From AlarmManager documentation:

If the alarm is delayed (for example, for system sleep, for signal types without _WAKEUP), the missed snooze will be delivered as soon as possible. Thereafter, future alarms will be delivered according to the original schedule; they don't drift over time. For example, if you set a recurring alarm for the top of every hour, but the phone slept between 7:45 am and 8:45 am, the alarm will be sent immediately after the phone wakes up, then the next alarm will be sent to the 9:00 am address.

As you can see, if you set an alarm and the device goes to sleep, there AlarmManager.RTC_WAKEUP

may be a long delay without using it depending on how long the device is in sleep. If you have never touched your device and no other alarms have triggered the wake-up, this could cause all of your alarms to add up for the next hour when the device wakes up.




Another potential problem I see is that you are retrieving the calendar instance representing the time right now, but then setting the hour, minute, and second itself. The current day and the current year are automatically filled in from the current time.

Again, from the documentation (emphasis mine):

If the specified trigger time has elapsed, the alarm will be triggered immediately , with the number of alarms depending on how far the trigger time has passed in relation to the repeat interval.

In this case, if your method was called 8 o'clock in the afternoon on a given day, it calendar.getTimeInMillis()

will return a past timestamp for all three alarms, as a result of which they will be triggered immediately from 8:00 to 15:00 and 20:00 has already passed ... In this case, you should first estimate if the current time has passed the alarm interval you are trying to set and add 1 more day for the time you set to make sure the alarm has been set in the future.

+6


source


Here's the updated code:



private void setRepeatedNotification(int ID, int hh, int mm, int ss) {
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    Intent alarmIntent = new Intent(StartActivity.this, AlarmReceiver.class);
    alarmIntent.putExtra("ID",ID);
    Log.d("setRepeatedNotification", "ID:" + ID);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(StartActivity.this, ID, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar calendar = Calendar.getInstance();
    Calendar now = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, hh);
    calendar.set(Calendar.MINUTE, mm);
    calendar.set(Calendar.SECOND, ss);

    //check whether the time is earlier than current time. If so, set it to tomorrow. Otherwise, all alarms for earlier time will fire

    if(calendar.before(now)){
        calendar.add(Calendar.DATE, 1);
    }

    mEverydayPendingIntent = pendingIntent;
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mEverydayPendingIntent);



}

      

+6


source







All Articles