Android 通知 PendingIntent Extras null

Posted

技术标签:

【中文标题】Android 通知 PendingIntent Extras null【英文标题】:Android Notification PendingIntent Extras null 【发布时间】:2012-11-15 19:02:40 【问题描述】:

我正在尝试将信息从通知发送到调用的活动,而从我的活动中我得到了 null。

通知代码为:

private void showNotification() 
Intent resultIntent = new Intent(this, MainActivity.class);
if (D)
    Log.d(TAG, "Id: " + Id);
resultIntent.putExtra("ineedid", deviceId);

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MeterActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
    PendingIntent.FLAG_UPDATE_CURRENT);
// Bundle tmp = resultIntent.getExtras();
// if (tmp == null) 
// Log.d(TAG, "tmp bundle is null");
//  else 
// long id = tmp.getLong("ineedid", -1);
// Log.d(TAG, "tmp id : " + id);
// 
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
    BLEMessengerService.this)
    .setSmallIcon(R.drawable.ic_action_search)
    .setContentTitle("Event tracker")
    .setContentText("Events received").setOngoing(true)
    .setContentIntent(resultPendingIntent)
    .setWhen(System.currentTimeMillis());

int mId = R.string.service_notification_start_service;
mNM.notify(mId, mBuilder.getNotification());

从主要活动的意图中获取信息的代码;

Bundle extras = getIntent().getExtras();
if (extras != null) 
    long deviceID = getIntent().getLongExtra("ineedid",
        -1);
    if (ID == -1) 
    if (D)
        Log.i(TAG_D, "Wrong Id received.");
    finish();
     else 
    device = dataSource.getDeviceByID(deviceID);
    if (D)
        Log.i(TAG_D, "Get the id.");
    
 else 
    if (D)
    Log.d(TAG_D, "Bundle is null");
    finish();

我在收到通知之前验证过,bundle 不为 null,并且在 extras 中有 id。 虽然,当我试图从意图中获取它时,它已经消失了。帮助。

【问题讨论】:

我也尝试添加“resultIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);”,但是没有用。 您不使用resultPendingIntent.getExtras()的原因是什么? 我只是做了这些行来检查我的 pendingIntent 是否有 Extras,并且我验证了它有我放在那里的内容。 如果您使用 FCM,通常通知由 android 本身处理,因此,您的通知在单击时没有额外内容。更多信息,请参考:***.com/questions/37358462/… 【参考方案1】:

在 PendingIntent 中使用这个标志 PendingIntent.FLAG_UPDATE_CURRENT 它对我有用

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

【讨论】:

有效!谢谢!! 如果您一次只使用一次,您可以使用它。但是,如果您需要多个 PendingIntents 同时有效,并且 FLAG_UPDATE_CURRENT 将只留下最近的有效意图。可能的解决方案是 intent.flag_activity_new_task【参考方案2】:

对我来说,除了设置 Intent.FLAG_ACTIVITY_SINGLE_TOP 之外,我还必须在意图中添加一个独特的操作:

    Intent resultIntent = new Intent(caller, NotificationActivity.class);

    String xId = getNextUniqueId();
    resultIntent.putExtra("x_id", xId);
    resultIntent.setAction(xId);
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

.. 如果没有 setAction(..),我的 NotificationActivity 收到的 Intent 上的 Extras 为空。

这篇文章有助于解释它:https://***.com/a/3128271/2162226

【讨论】:

我的一个意图有一个额外的(布尔值),但另一个缺少。指定任何类型的操作都可以修复它,突然两个附加功能都出现了!谢谢。【参考方案3】:

我刚刚得到答案, 添加行:resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

注意:如果您将其添加为resultIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 它不会工作。

我还尝试了其他标志,例如“FLAG_ACTIVITY_NEW_TASK”和“FLAG_ACTIVITY_RESET_TASK_IF_NEEDED”。在这里都不起作用。

【讨论】:

我也在尝试同样的事情。文档中有什么线索为什么需要这个标志?它只是说“如果设置,如果它已经在历史堆栈的顶部运行,则不会启动该活动。”【参考方案4】:

当一个活动被启动(当它第一次启动时)或重新启动(当它被带到堆栈的顶部时)getIntent().getExtra() 不会给出null。但是,当活动出现在堆栈顶部时,使用PendingIntent 启动该活动不会重新启动活动(onCreate() 不会被调用)而是onResume()会被调用。而getIntent().getExtra() 将返回与启动活动的意图相关联的值(即null)。要更新意图,请执行以下步骤:

1)。在您的意图中设置FLAG_ACTIVITY_SINGLE_TOPFLAG_ACTIVITY_CLEAR_TOP 标志。

resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

2)。在调用getIntent().getExtra() 的活动中覆盖onNewIntent()。该方法被FLAG_ACTIVITY_SINGLE_TOP调用

@Override
protected void onNewIntent(Intent intent) 
    super.onNewIntent(intent);
    setIntent(intent);

欲了解更多信息:See this doc

【讨论】:

清晰正确的解释,这应该是公认的答案 太棒了!这是正确的答案,并附带一个免费的直接解释。 ? 我想添加更多信息:在我的情况下,我遇到了一个额外的问题:第一次调用后意图仍然存在,这意味着在后续应用程序恢复时,编程的行为会重复,因为 Intent 仍然相同。为了避免这种情况,我在正确的战略位置添加了onResume getIntent().removeExtra("the_no-more-desired_extra")【参考方案5】:

当我遇到同样的问题时,我正在使用 Unity 的本地通知插件 -> 我启动了应用程序,安排了本地通知,将应用程序发送到后台,出现本地通知,当我点击它时,应用程序是恢复和getIntent().getExtras()null

就我而言,问题在于我试图以错误的意图获取额外内容。尝试使用简单的 toString 打印意图,在创建时刻和获得它时,以确保收到的内容是您所期望的。

还可以查看onNewIntent 方法。

【讨论】:

【参考方案6】:

如果您使用隐式意图来构建 PendingIntent,您可能会遇到这个问题。

解决问题的先前方法。

val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse("deeplink or applink here")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
intent.putExtra("key", Parcelable)
PendingIntent.getActivity(context, abs(Random.nextInt()), intent, PendingIntent.FLAG_UPDATE_CURRENT)

基于隐式 Intent 尝试了上面列出的多种方法对我不起作用。


这是解决我的问题的方法。 将 Intent 从隐式更改为显式。

// only diff
val intent = Intent(context, YourIntentDestinationActivity::class.java)
// only diff
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse("deeplink or applink here")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
intent.putExtra("key", Parcelable)
PendingIntent.getActivity(context, abs(Random.nextInt()), intent, PendingIntent.FLAG_UPDATE_CURRENT)

希望这对你有用。

【讨论】:

【参考方案7】:

对我来说,我的三星设备不断从意图中删除额外内容,有时甚至使应用程序崩溃。尝试了所有组合,但这种行为的实际原因不是明确地将 PendingIntent.FLAG_IMMUTABLE 标志添加到待处理的意图。

虽然,this is a requirement for Android 12 and above.

val pendingIntent = PendingIntent.getActivity(
                                this, 0,
                                getIntent(),
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
                            )

【讨论】:

以上是关于Android 通知 PendingIntent Extras null的主要内容,如果未能解决你的问题,请参考以下文章

Android中的前台通知启动新的活动(通过pendingIntent)而不是现有的

Android:如果将 Activity 带回屏幕上,通知中的 PendingIntent 不会触发 onCreate()

带有“null”PendingIntent 的通知

Android jetpack Navigation deepLink 创建通知并通过PendingIntent跳转到指定页面的Framgent

PendingInent 创建的 Android 任务无法再次使用 pendingIntent 启动另一个活动

Android - 清除任务标志不适用于 PendingIntent