使用通知和 getLaunchIntentForPackage 打开 Android 应用未通过 LauncherActivity
Opening Android app using notification & getLaunchIntentForPackage doesn't go through LauncherActivity
我正在使用 Firebase (FCM) 向用户显示推送通知,我 运行 遇到了一个奇怪的问题。
我的代码适用于以下场景(使用 FirebaseMessagingService):
- 前台应用 - 在 onReceive() 中接收数据并在应用内显示弹出窗口。
- 后台应用程序 - 在 onReceive() 中接收数据并向用户显示通知。如果单击此应用程序,该应用程序将返回到前面。 在 LauncherActivity 中接收到此意图,然后调用 finish() 将我带到任何 activity 我已经打开的地方。
- 应用程序完全关闭 - 与后台相同。在调用 finish() 之前,将启动应用程序并在 LauncherActivity 中处理意图。
这里是有趣的地方:
- 应用程序完全关闭 -> 通过通知打开它(在 LauncherActivity 中接收到意图) -> 将应用程序置于后台并发送另一个通知 -> 当这个通知被点击时,LauncherActivity 被完全忽略(不再调用 onCreate)我会直接被带到 activity 我已经拥有的任何东西。此处的意图没有额外内容或类别。
为什么在这种特定情况下会绕过 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
。通常,当您从主屏幕启动应用程序时,这是一个包含 ACTION=MAIN 和 CATEGORY=LAUNCHER 的 Intent
。如果您的应用随后进入后台(无论出于何种原因),并且用户稍后点击主屏幕上的图标,则使用相同的启动 Intent
。 Android 将其与用于首次启动应用程序的 Intent
匹配,如果这些匹配,Android 不会启动新的 Activity
,它只会带来包含应用程序从后台到前台的任务,无论它在移动到后台时处于什么状态。在正常情况下,这正是您想要的(也是用户期望的)行为。
但是,当应用程序首次从 Notification
启动时,这可能会造成混乱。就您而言,这就是您所看到的。您从 Notification
启动应用程序并且 Android 记住使用的 Intent
(来自 Notification
),当您稍后启动应用程序时(再次从 Notification
), android 将 Notification
中的 Intent
与用于首次启动应用程序的 Intent
相匹配,并认为您想从背景到前景。
有几种方法可以处理这个问题,具体取决于您想要的行为。最好的办法可能是不要从 Notification
启动根目录 Activity
(ACTION=MAIN 和 CATEGORY=LAUNCHER)。而是启动一个不同的 Activity
并让 Activity
确定下一步应该做什么(即:重定向到根目录 Activity
或其他内容,具体取决于您的应用程序的状态)。您还应该在放入 Notification
的 Intent
上设置 NO_HISTORY
和 EXCLUDE_FROM_RECENTS
标志。这将确保 Android 不会记住此 Intent
作为启动应用程序的那个。
我正在使用 Firebase (FCM) 向用户显示推送通知,我 运行 遇到了一个奇怪的问题。
我的代码适用于以下场景(使用 FirebaseMessagingService):
- 前台应用 - 在 onReceive() 中接收数据并在应用内显示弹出窗口。
- 后台应用程序 - 在 onReceive() 中接收数据并向用户显示通知。如果单击此应用程序,该应用程序将返回到前面。 在 LauncherActivity 中接收到此意图,然后调用 finish() 将我带到任何 activity 我已经打开的地方。
- 应用程序完全关闭 - 与后台相同。在调用 finish() 之前,将启动应用程序并在 LauncherActivity 中处理意图。
这里是有趣的地方:
- 应用程序完全关闭 -> 通过通知打开它(在 LauncherActivity 中接收到意图) -> 将应用程序置于后台并发送另一个通知 -> 当这个通知被点击时,LauncherActivity 被完全忽略(不再调用 onCreate)我会直接被带到 activity 我已经拥有的任何东西。此处的意图没有额外内容或类别。 为什么在这种特定情况下会绕过 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
。通常,当您从主屏幕启动应用程序时,这是一个包含 ACTION=MAIN 和 CATEGORY=LAUNCHER 的 Intent
。如果您的应用随后进入后台(无论出于何种原因),并且用户稍后点击主屏幕上的图标,则使用相同的启动 Intent
。 Android 将其与用于首次启动应用程序的 Intent
匹配,如果这些匹配,Android 不会启动新的 Activity
,它只会带来包含应用程序从后台到前台的任务,无论它在移动到后台时处于什么状态。在正常情况下,这正是您想要的(也是用户期望的)行为。
但是,当应用程序首次从 Notification
启动时,这可能会造成混乱。就您而言,这就是您所看到的。您从 Notification
启动应用程序并且 Android 记住使用的 Intent
(来自 Notification
),当您稍后启动应用程序时(再次从 Notification
), android 将 Notification
中的 Intent
与用于首次启动应用程序的 Intent
相匹配,并认为您想从背景到前景。
有几种方法可以处理这个问题,具体取决于您想要的行为。最好的办法可能是不要从 Notification
启动根目录 Activity
(ACTION=MAIN 和 CATEGORY=LAUNCHER)。而是启动一个不同的 Activity
并让 Activity
确定下一步应该做什么(即:重定向到根目录 Activity
或其他内容,具体取决于您的应用程序的状态)。您还应该在放入 Notification
的 Intent
上设置 NO_HISTORY
和 EXCLUDE_FROM_RECENTS
标志。这将确保 Android 不会记住此 Intent
作为启动应用程序的那个。