sadelbrid
sadelbrid

Reputation: 531

Alarm doesn't fire presicely and sometimes not at all

I'm trying to make an alarm that fires at a user-selected time. I notice however that the alarm never goes off right on the selected minute. I.e. if the user selects 8:30 from the TimePicker dialog, the alarm usually fires somewhere within the 8:30 minute and sometimes it fires over a minute late. Also, sometimes the alarm doesn't fire at all. The goal is to update the current alarm so that it isn't always creating new ones. I'm new to the Android alarm service so I was hoping someone could take a look. Here's some code:

This method is called in my onCreate

private void initAlarmService() {
    calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());

    ComponentName receiver = new ComponentName(getContext(), AlarmReceiver.class);
    pm = getContext().getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);


    alarmIntent = new Intent(getContext(), AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(getContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    manager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
}

And this method is called when a time is selected:

private void setTime(int hour, int minute) {
    if(sharedPreferences.contains("ALARM_PREF")){
        manager.cancel(pendingIntent);
    }

    sharedPreferences.edit().putString("ALARM_PREF", ""+hour + ":" +minute).apply();

    //set date object time to picker value
    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    calendar.set(Calendar.SECOND, 0);

    //interval = 1000 * 60 * 60 * 24
    manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTime().getTime(), interval, pendingIntent);

    //This just outputs to a textview
    SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
    time = sdf.format(calendar.getTime().getTime());
    alarmText.setText(time);
    calendar.setTimeInMillis(System.currentTimeMillis());
}

Upvotes: 0

Views: 167

Answers (1)

Marcin Koziński
Marcin Koziński

Reputation: 11074

If the behaviour you're describing is seen on an API 19+ device, this note from AlarmManager documentation might explain why:

Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.

In your case you'll need to switch to using setExact(). Unfortunately there is no setExactRepeating(), so you'll have to manually set it again when you receive first alarm.

Upvotes: 1

Related Questions