是否可以使用相同的 requestCode 和不同的附加项创建多个 PendingIntents? [英] Is it possible to create multiple PendingIntents with the same requestCode and different extras?

查看:23
本文介绍了是否可以使用相同的 requestCode 和不同的附加项创建多个 PendingIntents?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AlarmManager 来安排 1 到 35 个警报之间的任何时间(取决于用户输入).当用户请求安排新的闹钟时,我需要取消当前的闹钟,因此我使用相同的 requestCode 创建所有闹钟,在 final 变量中定义.

I'm using AlarmManager to schedule anywhere between 1 and 35 alarms (depending on user input). When the user requests to schedule new alarms, I need to cancel the current alarms, so I create all of my alarms with the same requestCode, defined in a final variable.

// clear remaining alarms
Intent intentstop = new Intent(this, NDService.class);
PendingIntent senderstop = PendingIntent.getService(this,
            NODIR_REQUESTCODE, intentstop, 0);
am.cancel(senderstop);

// loop through days
if (sched_slider.getBooleanValue())
for (int day = 1; day < 8; day++) {

    if (day == 1 && sun.isChecked())
                scheduleDay(day);
    if (day == 2 && mon.isChecked())
                scheduleDay(day);
    if (day == 3 && tue.isChecked())
                scheduleDay(day);
    if (day == 4 && wed.isChecked())
                scheduleDay(day);
    if (day == 5 && thu.isChecked())
                scheduleDay(day);
    if (day == 6 && fri.isChecked())
                scheduleDay(day);
    if (day == 7 && sat.isChecked())
                scheduleDay(day);
}

...

public void scheduleDay(int dayofweek) {
    Intent toolintent = new Intent(this, NDService.class);
    toolintent.putExtra("TOOL", "this value changes occasionally");
    PendingIntent pi = PendingIntent.getService(this,
                NODIR_REQUESTCODE, toolintent, 0);
    calendar.set(Calendar.DAY_OF_WEEK, dayofweek);
    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    calendar.set(Calendar.SECOND, 0);
    am.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY * 7, pi);
}

这里,如果用户选中了sun(这是一个复选框),它会安排一个闹钟在每周日的hourminute.您可以看到以这种方式创建的每个警报都有相同的 requestCode,但有时每个警报的 TOOL 额外更改.

Here, if the user has sun (which is a CheckBox) checked, it will schedule an alarm to run every Sunday at hour and minute. You can see that every alarm created this way has the same requestCode, but the TOOL extra changes sometimes for each alarm.

但是,在我的测试中,当警报响起并且我的服务运行时,来自 Intent 的额外内容现在 null.这个问题建议使用PendingIntent.FLAG_CANCEL_CURRENT 会解决这个问题,但不会取消其他 PendingIntents 吗?

However, in my testing, when the alarm goes off and my Service runs, the extras from the Intent are now null. This question suggests that using PendingIntent.FLAG_CANCEL_CURRENT will solve this, but wouldn't that cancel the other PendingIntents?

有人可以解释 PendingIntents 是如何工作的,参考创建多个具有相同 requestCode 和不同附加项的内容吗?我应该使用哪些标志(如果有)?

Can someone explain how PendingIntents work, in reference to creating multiple ones with the same requestCode and different extras? What flags (if any) should I be using?

推荐答案

实际上,您不是创建"PendingIntents.您从 Android 框架请求它们.当您从 Android 框架请求 PendingIntent 时,它会检查是否已经存在符合您作为参数传递的条件的 PendingIntent.如果是这样,它不会创建新的 PendingIntent,它只是返回一个指向现有 PendingIntent 的令牌".如果它没有找到匹配的 PendingIntent,它会创建一个,然后给你一个令牌",指向它刚刚创建的那个.您可以设置一些标志来修改此行为,但不是那么多.这里最重要的是要理解Android框架进行匹配的方式.

Actually, you don't "create" PendingIntents. You request them from the Android framework. When you request a PendingIntent from the Android framework, it checks to see if there is already a PendingIntent that matches the criteria you pass as arguments. If so, it does not create a new PendingIntent, it just gives you back a "token" that points to the existing PendingIntent. If it doesn't find a matching PendingIntent, it will create one and then give you back a "token" that points to the one it just created. There are some flags that you can set to modify this behaviour, but not that much. The most important thing to understand here is the way the Android framework does the matching.

为此,它会检查以下参数是否匹配(将现有的 PendingIntent 与您传递的参数进行比较):

To do this it checks if the following parameters match (comparing the existing PendingIntent with the parameters you have passed):

  • 请求代码必须相同.否则它们不匹配.
  • Intent 中的action"必须相同(或都为 null).否则它们不匹配.
  • Intent 中的数据"必须相同(或都为空).否则它们不匹配.
  • Intent 中的(数据的)类型"必须相同(或都为空).否则它们不匹配.
  • Intent 中的包"和/或组件"必须相同(或都为空).否则它们不匹配.包"和组件"字段是为显式"Intents 设置的.
  • Intent 中的类别"列表必须相同.否则它们不匹配.
  • Request codes must be the same. Otherwise they do not match.
  • The "action" in the Intent must be the same (or both null). Otherwise they do not match.
  • The "data" in the Intent must be the same (or both null). Otherwise they do not match.
  • The "type" (of the data) in the Intent must be the same (or both null). Otherwise they do not match.
  • The "package" and/or "component" in the Intent must be the same (or both null). Otherwise they do not match. "package" and "component" fields are set for "explicit" Intents.
  • The list of "categories" in the Intent must be the same. Otherwise they do not match.

您应该注意到额外"不在上面的列表中.这意味着,如果您请求 PendingIntent,当 Android 框架尝试查找匹配的 PendingIntent 时,不会考虑额外".这是开发人员常犯的错误.

You should notice that "extras" is not in the list above. That means that if you request a PendingIntent the "extras" are not taken into consideration when the Android framework tries to find a matching PendingIntent. This is a common mistake that developers make.

我们现在可以解决您可以添加的附加标志来修改 PendingIntent 请求的行为:

We can now address the additional flags that you can add to modify the behaviour of a PendingIntent request:

FLAG_CANCEL_CURRENT - 当您指定此标志时,如果找到匹配的 PendingIntent,则取消该 PendingIntent(移除、删除、失效)并创建了一个新的.这意味着任何持有指向旧 PendingIntent 的令牌"的应用程序将无法使用它,因为它不再有效.

FLAG_CANCEL_CURRENT - When you specify this flag, if a matching PendingIntent is found, that PendingIntent is cancelled (removed, deleted, invalidated) and a new one is created. This means that any applications that are holding a "token" pointing to the old PendingIntent will not be able to use it, because it is no longer valid.

FLAG_NO_CREATE - 当您指定此标志时,如果找到匹配的 PendingIntent,则返回指向现有 PendingIntent 的令牌"(这是通常的行为).但是,如果没有找到匹配的 PendingIntent,则不会创建新的,并且调用只返回 null.这可用于确定是否存在用于特定参数集的活动 PendingIntent.

FLAG_NO_CREATE - When you specify this flag, if a matching PendingIntent is found, a "token" pointing to the existing PendingIntent is returned (this is the usual behaviour). However, if no matching PendingIntent is found, a new one is not created and the call just returns null. This can be used to determine if there is an active PendingIntent for a specific set of parameters.

FLAG_ONE_SHOT - 当您指定此标志时,创建的 PendingIntent 只能使用一次.这意味着如果你将这个 PendingIntent 的令牌"提供给多个应用程序,在第一次使用 PendingIntent 后,它将被取消(移除、删除、失效)所以未来任何使用它的尝试都会失败.

FLAG_ONE_SHOT - When you specify this flag, the PendingIntent that is created can only be used once. That means that if you give the "token" for this PendingIntent to multiple applications, after the first use of the PendingIntent it will be canceled (removed, deleted, invalidated) so that any future attempt to use it will fail.

FLAG_UPDATE_CURRENT - 当您指定此标志时,如果找到匹配的 PendingIntent,则该 PendingIntent 中的额外"将被替换为您作为参数传递给 getxxx() 方法的 Intent 中的额外".如果没有找到匹配的 PendingIntent,则会创建一个新的(这是正常行为).这可用于更改现有 PendingIntent 上的额外",您已经将令牌"提供给其他应用程序并且不想使现有的 PendingIntent 无效.

FLAG_UPDATE_CURRENT - When you specify this flag, if a matching PendingIntent is found, the "extras" in that PendingIntent will be replaced by the "extras" in the Intent that you pass as a parameter to the getxxx() method. If no matching PendingIntent is found, a new one is created (this is the normal behaviour). This can be used to change the "extras" on an existing PendingIntent where you have already given the "token" to other applications and don't want to invalidate the existing PendingIntent.

让我尝试解决您的具体问题:

Let me try to address your specific problem:

如果请求代码、操作、数据、类型和包/组件参数相同,则系统中不能有多个活动的 PendingIntent.因此,您要求最多 35 个活动 PendingIntent 都具有相同的请求代码、操作、数据、类型和包/组件参数,但具有不同的额外",这是不可能的.

You cannot have more than one active PendingIntent in the system if the request code, action, data, type and package/component parameters are the same. So your requirement to be able to have up to 35 active PendingIntents all with the same request code, action, data, type and package/component parameters, but with different "extras", is not possible.

我建议您使用 35 个不同的请求代码,或者为您的 Intent 创建 35 个不同的唯一操作"参数.

I would suggest that you either use 35 different request codes, or create 35 different unique "action" parameters for your Intent.

这篇关于是否可以使用相同的 requestCode 和不同的附加项创建多个 PendingIntents?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆