使用通知打开 Android 应用程序getLaunchIntentForPackage 不通过 LauncherActivity [英] Opening Android app using notification & getLaunchIntentForPackage doesn't go through LauncherActivity

查看:109
本文介绍了使用通知打开 Android 应用程序getLaunchIntentForPackage 不通过 LauncherActivity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Firebase (FCM) to show Push Notifications to the user and I am running into a weird problem.

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

The code I have works for the following scenarios (using FirebaseMessagingService):

  • 前台应用 - 在 onReceive() 中接收数据并在应用内显示一个弹出窗口.
  • 后台应用程序 - 在 onReceive() 中接收数据并向用户显示通知.如果单击此按钮,应用程序将返回到前面.在 LauncherActivity 中接收来自此的意图,然后是一个 finish() 调用,该调用将我带到我已经打开的任何活动.
  • 应用完全关闭 - 与后台相同.应用将启动并在 LauncherActivity 中处理 Intent,然后调用 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());
}

我很感激任何想法.谢谢.

I'd appreciate any ideas. Thank you.

推荐答案

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

When you launch an app for the first time, Android remembers the Intent that was used to launch it. Normally, when you launch an app from the HOME screen, this is an Intent that contains ACTION=MAIN and CATEGORY=LAUNCHER. If your app then goes to the background (for whatever reason), and the user later taps the icon on the HOME screen, the same launch Intent is used. Android matches this against the Intent used to launch the app for the first time, and if these match, Android doesn't launch a new Activity, it just brings the task containing the app from the background to the foreground in whatever state it was in when it got moved to the background. Under normal circumstances, this is exactly the behaviour that you want (and that the user expects).

但是,当应用第一次从 Notification 启动时,这可能会搞砸.在您的情况下,这就是您所看到的.您从 Notification 启动应用程序,Android 会记住使用的 Intent(来自 Notification),当您稍后启动应用程序(再次从Notification),android将Notification中的Intent与第一次启动应用时使用的Intent进行匹配,并认为您想将现有应用任务从后台带到前台.

However, when the app is launched for the first time from a Notification, this can mess things up. In your case, this is what you are seeing. You launch the app from a Notification and Android remembers the Intent used (from the Notification), when you later launch the app (again from a Notification), android matches the Intent in the Notification with the Intent used to launch the app for the first time, and thinks you want to bring the existing app task from the background to the foreground.

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

There are several ways to deal with this, depending on the behaviour that you want to have. The best thing to do is probably not to launch your root Activity (the one with ACTION=MAIN and CATEGORY=LAUNCHER) from the Notification. Instead launch a different Activity and have that Activity determine what it should do next (ie: redirect to the root Activity or something else, depending on the state of your app). You should also set the NO_HISTORY and EXCLUDE_FROM_RECENTS flags on the Intent that you put in the Notification. This will ensure that Android won't remember this Intent as the one that launched the app.

这篇关于使用通知打开 Android 应用程序getLaunchIntentForPackage 不通过 LauncherActivity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆