Weird AlarmManager behaviour

白昼怎懂夜的黑 提交于 2019-12-18 07:02:24

问题


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


回答1:


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.




回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/37577296/weird-alarmmanager-behaviour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!