Search code examples
androidalarmmanagerandroid-pendingintent

Multiple Alarms, Few Works and Few does not


stuck around into a problem with

AlarmManager

I developed a method which adds two alarms into an AlarmManager Array. My method given below runs on a button click and adds as many as 10 alarms in the AlarmManager Array two per click.

My method code is given below.

public void stupidAlarm()
{

    stupidPendingIntentOne  = PendingIntent.getBroadcast(context, listItemClickedPosition, stupidIntentOne, PendingIntent.FLAG_UPDATE_CURRENT);
    stupidPendingIntentTwo  = PendingIntent.getBroadcast(context, listItemClickedPosition+5, stupidIntentTwo, PendingIntent.FLAG_UPDATE_CURRENT);


    stupidAlarm[listItemClickedPosition]= (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    stupidAlarm[listItemClickedPosition+5]= (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    alarmOneTime    = settings.getString(AlarmOneTime, null);
    alarmTwoTime    = settings.getString(AlarmTwoTime, null);

    try
    {
        OneHr   = Integer.parseInt(muteTime.substring(0, 2));
        OneMin = Integer.parseInt(muteTime.substring(2, 4));
        TwoHr   = Integer.parseInt(ringerTime.substring(0, 2));
        TwoMin = Integer.parseInt(ringerTime.substring(2, 4));
    }
    catch(Exception ex)
    {
        Toast.makeText(context, ex.getMessage(), Toast.LENGTH_SHORT).show();
    }

    stupidCalOne.set(2015, Calendar.MAY, 2);
    stupidCalOne.set(Calendar.HOUR_OF_DAY, OneHr);
    stupidCalOne.set(Calendar.MINUTE, OneMin);
    stupidCalOne.set(Calendar.SECOND, 0);
    stupidCalOne.set(Calendar.MILLISECOND, 0);

    stupidCalTwo.set(2015, Calendar.MAY, 2);
    stupidCalTwo.set(Calendar.HOUR_OF_DAY, TwoHr);
    stupidCalTwo.set(Calendar.MINUTE, TwoMin);
    stupidCalTwo.set(Calendar.SECOND, 0);
    stupidCalTwo.set(Calendar.MILLISECOND, 0);



    stupidAlarm[listItemClickedPosition].set(AlarmManager.RTC_WAKEUP, stupidCalOne.getTimeInMillis(), stupidPendingIntentOne);
    stupidAlarm[listItemClickedPosition+5].set(AlarmManager.RTC_WAKEUP, stupidCalTwo.getTimeInMillis(), stupidPendingIntentTwo);
}

But the problem is out of 10 Alarms created some works and some does not! following information may be helpful in this context

  1. AlarmOne 1047Hrs works
  2. AlarmTwo 1048Hrs works
  3. AlarmThree 1049Hrs does not work
  4. AlarmFour 1050Hrs works twice
  5. AlarmFive 1051Hrs does not work
  6. AlarmSix 1052Hrs does not work
  7. AlarmSeven 1053Hrs works thrice
  8. AlarmEight 1054Hrs works
  9. AlarmNine 1055Hrs does not work
  10. AlarmTen 1056Hrs works twice

My declaration of Calendar, Intent, PendingIntent and AlarmManagerArray

//for stupid alarm
public Calendar stupidCalOne;
public Calendar stupidCalTwo;
public Intent stupidIntentOne;
public Intent stupidIntentTwo;
public PendingIntent stupidPendingIntentOne;
public PendingIntent stupidPendingIntentTwo;
public AlarmManager[] stupidAlarm;

My assignments in onCreate method

//for stupid alarm
    stupidCalOne        = new GregorianCalendar();
    stupidCalTwo        = new GregorianCalendar();
    stupidIntentOne     = new Intent(context, OneAlarmReceiver.class);
    stupidIntentTwo     = new Intent(context, TwoAlarmReceiver.class);
    stupidAlarm         = new AlarmManager[10];

Any help will be highly appreciated, thanks in advance


Solution

  • The OS is allowed to batch Alarms.

    The docs for AlarmManager.set state:

    Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to "batch" alarms together across the entire system, minimizing the number of times the device needs to "wake up" and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.

    And that is why some times are skipped and then fire a minute later along with another alarm.

    I suspect the further apart they are, the less likely the system would be to batch them, but you still can't guarantee alarm time with this.

    It goes on:

    With the new batching policy, delivery ordering guarantees are not as strong as they were previously. If the application sets multiple alarms, it is possible that these alarms' actual delivery ordering may not match the order of their requested delivery times. If your application has strong ordering requirements there are other APIs that you can use to get the necessary behavior; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).

    So use setWindow or setExact. but note with setExact:

    Note: only alarms for which there is a strong demand for exact-time delivery (such as an alarm clock ringing at the requested time) should be scheduled as exact. Applications are strongly discouraged from using exact alarms unnecessarily as they reduce the OS's ability to minimize battery use.