Search code examples
androidbroadcastreceiveralarmmanagerandroid-broadcastandroid-broadcastreceiver

Android AlarmManager send Broadcast not on time


I use AlarmManager to set two action on time,

First action set on 10:00:00, and second action set on 10:15:00.

I can get two action broadcast,

and get first action broadcast on 10:00:03 (is OK),

but get second action broadcast on 10:29:15,14 minutes late!

How let AlarmManager can send broadcast on time ??

Set AlarmManager code:

@Override
public void onCreate() {
    setSchedule();
}
private void setSchedule(){
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Calendar offCal = Calendar.getInstance();
    offCal.set(Calendar.HOUR_OF_DAY, 10);
    offCal.set(Calendar.MINUTE, 15);
    offCal.set(Calendar.SECOND, 00);
    Intent offIntent = new Intent(this, AlarmReceiver.class);
    offIntent.setAction(AlarmReceiver.ALUM_SCREEN_OFF);
    PendingIntent offPending = PendingIntent.getBroadcast(this, 1,
            offIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    am.setRepeating(AlarmManager.RTC, offCal.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, offPending);

    Intent onIntent = new Intent(this, AlarmReceiver.class);
    onIntent.setAction(AlarmReceiver.ALUM_SCREEN_ON);
    Calendar onCal = Calendar.getInstance();
    onCal.set(Calendar.HOUR_OF_DAY, 10);
    onCal.set(Calendar.MINUTE, 00);
    onCal.set(Calendar.SECOND, 00);
    PendingIntent onPending = PendingIntent.getBroadcast(this, 2,
            onIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    am.setRepeating(AlarmManager.RTC_WAKEUP, onCal.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, onPending);
}

Receiver code:

public class AlarmReceiver extends BroadcastReceiver {
    public static final String ALUM_SCREEN_ON = "screenOn";
    public static final String ALUM_SCREEN_OFF = "screenOff";
    private static final String TAG = "AlarmReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Log.d(TAG, "get braodcast action:"+intent.getAction());
}

Solution

  • Since KitKat the set and setRepeating APIs are not exact. If you absolutely need the alarm to run at a specific time, use setExact. Consider using setWindow instead if the alarm time is not critical.

    There is no setExactRepeating, so if you need that, you need to use setExact and them re-arm your alarm. But unless your are doing time critical stuff, that's not recommended.