使用Notification和getLaunchIntentForPackage打开Android应用不会通过LauncherActivity进行操作

问题描述

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

我拥有的代码适用于以下情况(使用FirebaseMessagingService):

  • 前景中的应用程序-在onReceive()中接收数据并显示应用程序内部的弹出窗口。
  • 后台应用-在onReceive()中接收数据并向用户显示通知。如果单击此按钮,则该应用程序将返回到前面。 在LauncherActivity中收到了此意图,然后执行finish()调用,使我可以进行任何我已经打开的活动。
  • 应用程序完全关闭-与背景相同。在调用应用程序的finish()之前,将启动应用程序并在LauncherActivity中处理意图。

这是有趣的地方:

  • 应用程序完全关闭->通过通知打开(在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());
}

我将不胜感激。谢谢。

解决方法

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

但是,从Notification首次启动该应用程序时,这可能会使事情变得混乱。就您而言,这就是您所看到的。您从Notification启动应用程序,而Android会记住使用的Intent(来自Notification),稍后再启动应用程序(再次从Notification启动)时,Android Intent中的NotificationIntent用于首次启动应用程序,并且认为您要将现有的应用程序任务从后台移到前台。

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...