Search code examples
androidnotificationsandroid-alarms

AlarmsManager triggers whenever it wants


I want to trigger a notification each day at a specific time choosen by the user, like 6' / 7' / 8'.

For this, I created a WakefulBroadcastReceiver, that pass to an IntentService to create the notification.

And this is how I setup my AlarmsManager. timeInHours is an integer passed as parameter, between 6 and 12 :

    Intent i = new Intent(context, StepCountNotifyBroadcast.class);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);

    // Get the next day at timeInHours hours'.
    Calendar cal = Calendar.getInstance();
    cal.setTime(new Date()); // compute start of the day for the timestamp
    cal.set(Calendar.HOUR_OF_DAY, timeInHours);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    cal.set(Calendar.AM_PM, Calendar.AM);

    if (new Date().getTime() > cal.getTime().getTime())
        cal.add(Calendar.DAY_OF_YEAR, 1);

    long nextDay = cal.getTime().getTime();

    // Setup the alarm.
    long timeBetween = AlarmManager.INTERVAL_DAY;      // Each day.
    AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarms.cancel(pi);
    alarms.setRepeating(AlarmManager.RTC_WAKEUP, nextDay, timeBetween, pi);

    Date nextDayAsDate = new Date(nextDay);
    GLog.d("AlarmUtils", "scheduleNotifiation for next date: " + nextDayAsDate.toString());

It works well 50% of the time, but still do crazy things like... Trigger the notification at 2:00 AM ?! I know the system will not trigger the notification at the specific time I want and this is ok. But here we talk about approximately 18 hours later.

In logs, it seems that my IntentService code is effectively running in the middle of the night in some cases. So that's not an issue with the notification itself.

I can switch this line :

    alarms.setRepeating(AlarmManager.RTC_WAKEUP, nextDay, timeBetween, pi);

to another line of code :

    alarms.setExact(AlarmManager.RTC_WAKEUP, nextDay, pi);

But this is not good for the battery life I'm afraid.

Now my questions :

  • Can somebody tell me a reason about the way Android devices works with AlarmsManager ?
  • Do you find another solution than will not drain battery life and be sure the notification will be triggered in maximum 2 or 3 hours later?
  • Do you have any ideas, in this particular case, to debug and do code testing without waiting a day or two to detect issues?

Thanks in advance.


Solution

  • After API Level 23, Doze mode was introduced on the Android System to reduce battery consumption. Go through below link:

    How to make Alarm Manager work when Android 6.0 in Doze mode?