通知通过旧的 Intent Extras
Posted
技术标签:
【中文标题】通知通过旧的 Intent Extras【英文标题】:Notification passes old Intent Extras 【发布时间】:2011-11-14 06:44:20 【问题描述】:我正在通过此代码在 BroadcastReceiver 中创建通知:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
int icon = R.drawable.ic_stat_notification;
CharSequence tickerText = "New Notification";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_VIBRATE;
long[] vibrate = 0,100,200,200,200,200;
notification.vibrate = vibrate;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
CharSequence contentTitle = "Title";
CharSequence contentText = "Text";
Intent notificationIntent = new Intent(context, NotificationActivity.class);
notificationIntent.putExtra(Global.INTENT_EXTRA_FOO_ID, foo_id);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
int mynotification_id = 1;
mNotificationManager.notify(mynotification_id, notification);
当我点击通知时,它会打开 NotificationActivity 并在 Activity 内我可以从 Intent-Bundle 中检索 foo_id(例如 1)
但是,如果触发了另一个通知并且我再次单击它,则活动仍会从 Intent-Bundle 接收“旧”值 (1)。我尝试使用 clear() 清除捆绑包,但效果相同。我认为我的代码有问题..
【问题讨论】:
请告诉我如何从待处理的意图中获取数据 意识到它正在发送旧的临时演员,使我的分类更容易。 【参考方案1】:您正在为待处理的 Intens 发送相同的请求代码。 改变这个:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
收件人:
PendingIntent contentIntent = PendingIntent.getActivity(context, UNIQUE_INT_PER_CALL, notificationIntent, 0);
如果您发送相同的参数,则不会创建意图。它们被重复使用。
【讨论】:
所以 UNIQUE_INT_PER_CALL 是我必须提供的整数?或者这是在某处声明的静态变量? android gotcha #147 - 所以具有 不同 附加功能的Intent
(通过putExtra
)被认为是相同的并且可以重复使用,因为我没有提供唯一的id 到一些待处理的意图调用 - 糟糕的 api
你知道吗,我太粗心了。只是想它怎么能在一个块中保持 0(在我的情况下):(
这对我来说非常有用,只是给其他人的一个提示,很可能您正在使用相同的方法构建通知,因此您只需将新待处理意图的 id 设置为与您将用于通知唯一 ID 的相同!
@IncrediApp, 和 PendingIntent.getBroadcast() 一样吗? ?【参考方案2】:
或者,您可以使用以下代码生成您的 PendingIntent:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
来自PendingIntent.FLAG_UPDATE_CURRENT
的文档:
如果描述的 PendingIntent 已经存在,则保留它,但用这个新 Intent 中的内容替换其额外数据。如果您正在创建仅附加内容发生变化的意图,则可以使用此选项,并且不关心任何收到您之前的 PendingIntent 的实体将能够使用您的新附加内容启动它,即使它们没有明确提供给它。
【讨论】:
谢谢...完美地为这个添加“PendingIntent.FLAG_UPDATE_CURRENT”的标志工作:) 为我工作,使用挂起的意图将状态从设置警报转移到广播接收器。 我只是希望在我向用户发送通知之前知道这些标志的真正作用(!)很高兴这解决了我的问题...【参考方案3】:您传递的是相同的 ID。在这种情况下,像这样从 time 中创建一个唯一的 id:
int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);
然后这样写:
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);
【讨论】:
为什么不使用 new Random().nextInt() @hderanga 在上面的 int 中添加“& 0xfffffff”有什么作用? @AJWSystem.currentTimeMillis()
返回一个 long,而 PendingIntent.getActivity()
的 requestId
参数采用一个 int。 0xffffffff
是位掩码。虽然还有更多内容,但简单的解释是,执行 `long & 0xffffffff' 会给出 long 中的最低 32 位并丢弃最高 32 位,从而基本上得到一个 32 位 int。这比简单地转换为 int 更好,因为它不会弄乱符号位(如果您将大于 int 的 long 转换为 int 符号位将溢出,并且您可能会以负值结束)【参考方案4】:
对于长时间寻找最佳方法的任何人,您需要将 PendingIntent.FLAG_UPDATE_CURRENT 作为最后一个参数传递,如下所示
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
您甚至不需要提供新的唯一 ID。
你需要在下次而不是第一次这样做
【讨论】:
那行不通,我来这里是因为我正在做的。 你需要为下一次而不是第一次这样做,它会起作用。【参考方案5】:对于所有通知,您的请求代码均为 0。更改以下行:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
与:
PendingIntent contentIntent = PendingIntent.getActivity(context, new Random().nextInt(), notificationIntent, 0);
【讨论】:
使用“new Random().nextInt()”而不是“System.currentTimeMillis()”有什么好处吗? 使用 random 可以很容易地意外地重新生成相同的整数值,从而导致很难找到传递旧意图的错误。 @AJW 就我而言。我在完全相同的毫秒内创建了 2 个不同的通知,所以其中一个得到了错误的附加信息。【参考方案6】:只是想添加另一个选项
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
【讨论】:
以上是关于通知通过旧的 Intent Extras的主要内容,如果未能解决你的问题,请参考以下文章