通知通过旧的 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”有什么作用? @AJW System.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的主要内容,如果未能解决你的问题,请参考以下文章

共享意图在 WhatsApp 中显示旧的附加功能

单击 Firebase 通知有效负载的通知时打开自定义 Intent

检查INTENT互联网连接

Android 通知 setContentView

如何创建不可删除的通知?

Notification PendingIntent Intent extras 被另一个通知覆盖