Joao Sardinha
Joao Sardinha

Reputation: 3423

Weird AlarmManager behaviour

I have 2 BroadcastReceivers and 2 intents, I want to click a button, 5m later start broadcast1 and 10m later start broadcast2, what's happening is they both start 10m after I click, My guess is, the intents are not unique, but I'm setting a diffrent reqeustCode for each of them.

Button's OnClick:

    Bundle bd = new Bundle();
    bd.putInt("mInt", i);

    Intent intent1 = new Intent(getActivity(), Broadcast_1.class);
    intent1.putExtras(bd);
    PendingIntent pendingIntent1 = PendingIntent.getBroadcast(getActivity().getApplicationContext(), i, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager1 = (AlarmManager) getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmManager1.setRepeating(AlarmManager.RTC, System.currentTimeMillis()+1000*60*5, 1000*60*10, pendingIntent1);
    Toast.makeText(getActivity(), "countdown started "+i ,Toast.LENGTH_SHORT).show();

    Intent intent2 = new Intent(getActivity(), Broadcast_1.class);
    intent2.putExtras(bd);
    PendingIntent pendingIntent2 = PendingIntent.getBroadcast(getActivity().getApplicationContext(), i+42212342, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager2 = (AlarmManager) getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmManager2.setRepeating(AlarmManager.RTC, System.currentTimeMillis()+1000*60*10, 1000*60*10, pendingIntent2);

BroadcastReceiver_1 and _2 (they look the same) class:

public class Broadcast_1 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        Calendar c = Calendar.getInstance();
        int seconds = c.get(Calendar.SECOND);
        int minutes = c.get(Calendar.MINUTE);
        ShowTextFragment.setText("Broadcast_1" + " at " + minutes + " : " + seconds);

    }

}

Question: Why does the most recent intent push the previous intents to his starting time?

I confirmed this behaviour by printing the time when the Broadcast's code executes. Please help

Upvotes: 3

Views: 181

Answers (3)

David Wasser
David Wasser

Reputation: 95568

The problem you are seeing is the way that repeating alarms now work. In order to preserve battery life, the AlarmManager now takes great liberties in rescheduling alarms in order to group multiple alarms together. Basically, if you need any sort of accurate timing you should forget about using setRepeating(). Use setExact() instead. If you need a repeating alarm, just reset it when it goes off.

Upvotes: 2

nicobatu
nicobatu

Reputation: 1387

It seems like the requestCode field in your getBroadcast call does not always make it unique. See the second comment on this question: What's "requestCode" used for on PendingIntent?

Since the "extra" contents don't differentiate them either, someone found that setting different data on the Intent worked: https://stackoverflow.com/a/33203752/508608

Upvotes: -1

Erich
Erich

Reputation: 1848

The reason for this is, that the intents are not individual. They are reused when the data is the same (as in your case)

From the doc:

A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.

Upvotes: 0

Related Questions