【问题标题】:Opening Android app using notification & getLaunchIntentForPackage doesn't go through LauncherActivity使用通知和 getLaunchIntentForPackage 打开 Android 应用程序不会通过 LauncherActivity
【发布时间】:2020-09-14 08:21:27
【问题描述】:

我正在使用 Firebase (FCM) 向用户显示推送通知,但遇到了一个奇怪的问题。

我的代码适用于以下场景(使用 FirebaseMessagingService):

  • 前台应用 - 在 onReceive() 中接收数据并在应用内显示一个弹出窗口。
  • 后台应用程序 - 在 onReceive() 中接收数据并向用户显示通知。如果单击此按钮,应用程序将被带回前面。 在 LauncherActivity 中接收到此意图,然后调用 finish() 将我带到我已经打开的任何活动。
  • 应用程序完全关闭 - 与背景相同。应用将被启动,并且 Intent 将在 LauncherActivity 中处理,然后再调用 finish()。

这就是有趣的地方:

  • 应用程序完全关闭 -> 通过通知打开它(在 LauncherActivity 中收到意图) -> 将应用程序置于后台并发送另一个通知 -> 当单击此通知时,LauncherActivity 将被完全忽略(不再调用 onCreate),我直接参加我已经进行的任何活动。这里的意图没有额外内容或类别。 为什么在这种特定情况下会绕过 LauncherActivity?请记住,如果应用最初是正常启动的(而不是通过点击通知),这可以正常工作
Intent mainIntent = getPackageManager().getLaunchIntentForPackage(getPackageName()); 
if (mainIntent != null) {
    mainIntent.addCategory(NOTIFICATION_CATEGORY);
    mainIntent.putExtra(.........);
}
PendingIntent pendingMainIntent = PendingIntent.getActivity(this, SERVICE_NOTIFICATION_ID, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, context.getString(R.string.default_notification_channel_id));
notificationBuilder.setContentIntent(pendingMainIntent);
//.....icon, color, pririty, autoCancel, setDefaults, setWhen, setShowWhen, contentText, setStyle

NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
            getString(R.string.default_notification_channel_id),
            getString(R.string.default_notification_channel),
            NotificationManager.IMPORTANCE_HIGH
        );
        notificationManager.createNotificationChannel(channel);
        notificationBuilder.setChannelId(getString(R.string.default_notification_channel_id));
    }
    notificationManager.notify(SERVICE_NOTIFICATION_ID, notificationBuilder.build());
}

我会很感激任何想法。谢谢。

【问题讨论】:

    标签: java android android-notifications android-pendingintent launch


    【解决方案1】:

    当您首次启动应用程序时,Android 会记住用于启动该应用程序的 Intent。通常,当您从主屏幕启动应用程序时,这是一个 Intent,其中包含 ACTION=MAIN 和 CATEGORY=LAUNCHER。如果您的应用程序随后进入后台(无论出于何种原因),并且用户稍后点击主屏幕上的图标,则使用相同的启动 Intent。 Android 将其与第一次启动应用程序时使用的 Intent 匹配,如果匹配,Android 不会启动新的 Activity,它只是将包含应用程序的任务从后台带到前台说明它在移到后台时所处的位置。在正常情况下,这正是您想要的(以及用户期望的)行为。

    但是,当应用程序第一次从Notification 启动时,这可能会搞砸。就您而言,这就是您所看到的。您从Notification 启动应用程序并且Android 记住使用的Intent(来自Notification),当您稍后启动应用程序时(再次从Notification),android 匹配@987654332 中的Intent @ 与Intent 用于首次启动应用程序,并认为您想将现有应用程序任务从后台带到前台。

    有几种方法可以解决这个问题,具体取决于您想要的行为。最好的办法可能是不要从Notification 启动您的根Activity(具有ACTION=MAIN 和CATEGORY=LAUNCHER 的那个)。而是启动一个不同的Activity 并让Activity 确定下一步应该做什么(即:重定向到根Activity 或其他内容,具体取决于您的应用程序的状态)。您还应该在您放入NotificationIntent 上设置NO_HISTORYEXCLUDE_FROM_RECENTS 标志。这将确保 Android 不会记住这个 Intent 是启动应用程序的人。

    【讨论】:

    • 我使用了一个单独的活动,我从 FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_NO_HISTORY、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 开始。这将启动应用程序或根据需要将其置于最前面。从这个活动中,我完成或启动应用程序启动器(如果应用程序已死)。如果我通过启动器从此活动启动应用程序,下次单击通知时,问题再次出现,这一次完全绕过单独的活动,我在任何地方都没有任何意图数据。
    • 请编辑您的问题并在那里发布您的最新清单。我无法关注您的评论。
    • 想通了。我会尽快发布代码。您对系统如何匹配 Intent 的解释非常有帮助。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 2014-10-29
    • 2023-03-11
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多