奇怪的 AlarmManager 行为

Weird AlarmManager behaviour

我有 2 个 BroadcastReceivers 和 2 个意图,我想点击一个按钮,5 米后开始广播 1,10 米后开始广播 2,发生的事情是它们都在我点击后 10 米后开始,我的猜测是,意图不是唯一的,但我为他们每个人设置了不同的 reqeustCode。

按钮的 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 和 _2(他们看起来一样)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);

    }

}

问题: 为什么最近的intent会把之前的intent推到他的开始时间?

我通过打印广播代码执行的时间来确认此行为。请帮助

这样做的原因是,意图不是个人的。当数据相同时(如您的情况),它们将被重用

来自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.

您的 getBroadcast 调用中的 requestCode 字段似乎并不总是唯一的。请参阅关于此问题的第二条评论: What's "requestCode" used for on PendingIntent?

由于 "extra" 内容也不区分它们,有人发现在 Intent 上设置不同的数据有效:

您看到的问题是 repeating alarms now work 的方式。为了延长电池寿命,AlarmManager 现在可以非常自由地重新安排警报,以便将多个警报组合在一起。基本上,如果您需要任何类型的准确计时,您应该忘记使用 setRepeating()。请改用 setExact()。如果您需要重复闹钟,只需在闹钟响起时重新设置即可。