I am using Firebase (FCM) to show Push Notifications to the user and I am running into a weird problem.
The code I have works for the following scenarios (using FirebaseMessagingService):
And here is where it gets interesting:
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.
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).
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.
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.