对AlarmManager.setRepeating的多次调用提供了相同的Intent/PendingIntent额外值,但我提供了不同的值

Chr*_*yle 17 android extras alarms android-pendingintent

在写这个问题时解决了,但发布以防万一:

我正在设置这样的多个警报,具有不同的值id:

AlarmManager alarms = (AlarmManager)context.getSystemService(
        Context.ALARM_SERVICE);
Intent i = new Intent(MyReceiver.ACTION_ALARM);  // "com.example.ALARM"
i.putExtra(MyReceiver.EXTRA_ID, id);  // "com.example.ID", 2
PendingIntent p = PendingIntent.getBroadcast(context, 0, i, 0);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, nextMillis, 300000, p);  // 5 mins
Run Code Online (Sandbox Code Playgroud)

......并像这样接收它们:

public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION_ALARM)) {
        // It's time to sound/show an alarm
        final long id = intent.getLongExtra(EXTRA_ID, -1);
Run Code Online (Sandbox Code Playgroud)

警报在适当的时间传递给我的接收器,但通常EXTRA_ID设置为错误的值:它是我在某个时刻使用的值,而不是我想要在那个特定时间传递的值.

Chr*_*yle 24

文档PendingIntent.getBroadcast()说:

返回

返回与给定参数匹配的现有或新PendingIntent.

问题是只有额外的两个Intent似乎与此目的相匹配.所以getBroadcast()EXTRA_ID在我刚创建的Intent周围返回一些随机的旧PendingIntent(使用不同的)而不是新的.修复是提供数据Uri并使其与id不同,如下所示:

Intent i = new Intent(MyReceiver.ACTION_ALARM, Uri.parse("timer:"+id));
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下方法检索ID号:

Long.parseLong(intent.getData().getSchemeSpecificPart());
Run Code Online (Sandbox Code Playgroud)

...或者当然也提供额外的并使用它.


pan*_*wal 7

你也可以使用这个标志 PendingIntent.FLAG_UPDATE_CURRENT

PendingIntent p = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)

这也应该是工作

  • 如果您打算一次只使用一次,那么可以,但是对于设置了多个计时器的警报,您需要多个 PendingIntents 才能同时有效,而 FLAG_UPDATE_CURRENT 会让所有警报都发送一个最新的 Intent。 (2认同)