【问题标题】:Notification passes old Intent Extras通知通过旧的 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() 清除捆绑包,但效果相同。我认为我的代码有问题..

【问题讨论】:

  • 请告诉我如何从待处理的意图中获取数据
  • 意识到它正在发送旧的临时演员,使我的分类更容易。

标签: android android-notifications android-pendingintent android-notification-bar


【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    相关资源
    最近更新 更多