Search code examples
javaandroidservicealarmmanager

Setting an alarm from inside another alarm using AlarmManager class not getting fired correctly


The below code is from my MainActivity onCreate() method where I set an alarm to run a service ScheduleAlarm immediately and only once. sPrefs is the SharedPreference object that takes care of setting this alarm only once. The service ScheduleAlarm is an IntentService which is getting fired perfectly.

if(sPrefs.getBoolean("SettingAlarmForFirstTime",true)) {
        //Creating alarm for showing notifications.
        Calendar calendar = Calendar.getInstance();
        //calendar.setTimeInMillis(System.currentTimeMillis());
        //calendar.set(Calendar.HOUR_OF_DAY, 8);

        Intent intent = new Intent(MainActivity.this, ScheduleAlarms.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);//Use AlarmManager.INTERVAL_DAY instead of int number here.
        editor.putBoolean("SettingAlarmForFirstTime", false);
        editor.commit();
    }

Now this is my ScheduleAlarms service class. When this service is started onHandleIntent() method is called from where I am calling setWeeklyAlarms() method. Now my problem is from inside this method I want to set 7 alarms for a complete week based on timings that I will obtain from an API server call. Right now I am unable to even execute a single alarm perfectly. The alarm that i am setting is set to start after 3 secs delay which will call another service named NotificationService but the alarms gets fired immediately instead of waiting for 3 secs. Please analyze and tell me why this is happening.

public class ScheduleAlarms extends IntentService {
private boolean notificationsEnabled = true;
private String notificationTimings = "";

public ScheduleAlarms() {
    super("ScheduleAlarms");
}

@Override
protected void onHandleIntent(Intent intent) {
    setWeeklyAlarm();
}

private void setWeeklyAlarm() {
    Intent i = new Intent(ScheduleAlarms.this, NotificationService.class);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getService(ScheduleAlarms.this, 10001, i, 0);
    AlarmManager alarmManager = (AlarmManager) ScheduleAlarms.this.getSystemService(Context.ALARM_SERVICE);

/* Setting this alarmManager to fire up the alarm after 3 mins delay, but this alarm is getting fired immediately*/

    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 3*60*1000, pendingIntent);


}

}


Solution

  • Change the following line:

    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 3*60*1000, pendingIntent);
    

    to:

    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis() + 3 * 60 * 1000, 3 * 60 * 1000, pendingIntent);
    

    The alarm is fired up immediately, because

    AlarmManager.ELAPSED_REALTIME_WAKEUP + 0, ...

    So, the first time, it is fired up after 0 seconds. To change this, you need to add some time here.

    AlarmManager.ELAPSED_REALTIME_WAKEUP + time
    

    And, also it should be repeating, so you need to use setRepeating.

    Note : 3 * 60 * 1000 == 3 minutes, not 3 seconds