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

Posted

技术标签:

【中文标题】多次调用 AlarmManager.setRepeating 提供相同的 Intent/PendingIntent 额外值,但我提供了不同的值【英文标题】:Multiple calls to AlarmManager.setRepeating deliver the same Intent/PendingIntent extra values, but I supplied different ones 【发布时间】:2011-02-20 02:50:05 【问题描述】:

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

我正在设置多个这样的警报,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

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

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);

警报会在正确的时间发送到我的接收器,但通常会将 EXTRA_ID 设置为错误的值:这是我在某个时候使用过的值,而不是我希望在那个特定时间发送的值.

【问题讨论】:

【参考方案1】:

PendingIntent.getBroadcast() 的文档说:

退货

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

问题在于,两个仅在附加方面不同的 Intent 似乎与此目的相匹配。所以getBroadcast() 将返回一些随机的旧 PendingIntent(具有不同的EXTRA_ID),而不是围绕我刚刚创建的 Intent 的一个新的。解决方法是提供一个数据 Uri 并使其与 id 不同,如下所示:

Intent i = new Intent(MyReceiver.ACTION_ALARM, Uri.parse("timer:"+id));

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

Long.parseLong(intent.getData().getSchemeSpecificPart());

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

【讨论】:

只是想知道,如果我用 Intent i = new Intent(context, Cls);我有这个混合身份证问题吗?就我而言,不同警报的 Cls 不同。应该没问题吧? 我目前无法找到我之前查看的确切位置以了解有关附加功能的要点,但是是的,对于不同的课程,它是完全不同的 Intent,所以我非常希望它能够工作。 @ChrisBoyle,非常感谢。但就我而言,它不起作用。然而这有效:Intent intent = new Intent(null, Uri.parse(Long.toString(id)), context, AlarmActivity.class);。请注意,我可以使用活动。 添加此行后,我的 AlarmReceiver(广播接收器)根本不起作用。我想在一个时间点设置多个警报。我能得到一些帮助吗?谢谢。【参考方案2】:

你也可以使用标志PendingIntent.FLAG_UPDATE_CURRENT

PendingIntent p = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

这也应该有效

【讨论】:

如果您一次只使用一次,那么可以,但是对于设置了多个计时器的警报,您需要多个 PendingIntents 才能同时有效,并且 FLAG_UPDATE_CURRENT 会留下所有警报发送单个最近的 Intent。【参考方案3】:

您的问题的解决方案是使用 Intent.FLAG_ACTIVITY_NEW_TASK

  p = PendingIntent.getBroadcast(context, 0, i, Intent.FLAG_ACTIVITY_NEW_TASK);

【讨论】:

以上是关于多次调用 AlarmManager.setRepeating 提供相同的 Intent/PendingIntent 额外值,但我提供了不同的值的主要内容,如果未能解决你的问题,请参考以下文章

多次调用getView方法

为啥 LocationManager 会多次调用 startUpdatingLocation?

Android JobScheduler onStartJob 多次调用

numberOfRowsInSection 多次调用但 cellForRowAtIndexPath 从未调用

我多次调用相同的服务(AFNetworking)

useSelector 解构与多次调用