notification intent opens the apps main activity in background if its paused - android

I have a notification service running that will create a notification for the user and if the user clicks the notification it opens an activity to display the message, the method I am using to create the notification is :
public void createNotificationMsg(String name,String doing, boolean persistent){
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
0, new Intent(getApplicationContext(), MessageNotificationActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP).putExtra("message", doing),
PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder notificationBuilder =
(NotificationCompat.Builder) new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.my_logo_96)
.setContentTitle(name)
.setContentText(doing)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.DEFAULT_ALL)
.setContentIntent(pendingIntent)
.setPriority(Notification.PRIORITY_HIGH)
.setColor(Color.parseColor("#1aadce"));
if (persistent){
notificationBuilder.setOngoing(true);
}
else {
notificationBuilder.setOngoing(false);
}
NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(getApplicationContext());
Notification notification = notificationBuilder.build();
notificationManager.notify(0, notification);
}
the MessageNotificationActivity is using the "android:style/Theme.Dialog" to make it look like a dialog now the thing is that when I click on the notification everything goes well and the activity is opened like a dialog with nothing in the background but if the app is paused and is in background when I click the notification it brings the apps Main activity to the front and then opens the MessageNotiicationActivity on top of it. How can I make the notification not bring the main activity to front and only intent to the specefied activity?

The reason this happens is that your dialog-themed Activity has the same "task affinity" as the other activities in your app, so when you click on the notification, Android looks for an appropriate task in which to launch the dialog-themed Activity. If your app is in the background, Android will see it as a task with the same "task affinity" as the dialog-themed Activity and bring that task to the foreground and launch the dialog-themed Activity into that task.
To prevent this from happening, you need to add android:taskAffinity="" to the <activity> declaration in the manifest for your dialog-themed Activity. This tells Android to launch the dialog-themed Activity into a new task, and not into your app's task.

Try adding the flag Intent.FLAG_ACTIVITY_CLEAR_TASK to your intent. This will clear any other activities in the task.

Related

Refresh activity from notification, without recreating it

i am trying to implement notifications in my android application.
when the user clicks on the notification i run the activity if it isn't already running .. but if the activity is already running i don't want to recreate it, i just want to refresh the data by intercepting the intent from the onNewIntent function.
the problem is that every time I click on the notification, the activity is recreated, and the onNewIntent function is not called.
the problem occurs when I create the notification from a service.
but when I create the notification from the same activity that I am going to run, everything works fine.
I searched the internet and tried all the solutions I found, but it still doesn't work
I tried several combinations of intent flags, but nothing works
this is my code
val intent : Intent = Intent(this, HomeActivity::class.java)
finalIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
val pendingIntentFlags : Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
}
else
{
PendingIntent.FLAG_UPDATE_CURRENT
}
val pendingIntent : PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(finalIntent)
getPendingIntent(0, pendingIntentFlags)
}
val notification = NotificationCompat.Builder(context, type.channelId)
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(Notification.CATEGORY_SERVICE)
.setDefaults(Notification.DEFAULT_ALL)
.setAllowSystemGeneratedContextualActions(true)
.setOnlyAlertOnce(true)
.setAutoCancel(true)
.setLocalOnly(true)
.setOngoing(false)
.setSilent(false)
.setSmallIcon(R.drawable.icon_notification)
.setContentIntent(pendingIntent)
.build()
notificationManager?.notify(NOTIFICATION_ID, notification)
Let your notification send a broadcast.
In your activity you should register a dynamic broadcast receiver.
This will allow you to refresh the content in the activity without reloading it.
For the case that the activity is not running, you should define a broadcast receiver in the manifest which starts the activity.
when your activity starts, disable the broadcast receiver and re-enable it when your activity stops.
You can just set launch mode attribute to singleInstance in the manifest on your activity and start it with FLAG_ACTIVITY_NEW_TASK only.

Android: How to show/skip the Splash Screen as needed when opening an app through a notification?

(Note: My app's targetSdk and compileSdk are set to 29, so I can't take advantage of the new SplashScreen API)
I have a very simple app with two activities:
SplashActivity - Default activity opened with the launcher icon. Shows a splash screen, loads some stuff, and when complete, calls startActivity() to start the Main Activity and then calls finish() to finish itself.
Main Activity - It just posts a notification. When pressing that notification, the app should be brought to the foreground.
What do I mean by "the app should be brought to the foreground"? To be clear:
If MainActivity already exists (either in the background or foreground), open that same instance.
If MainActivity was destroyed (the user previously pressed Back), then open the SplashActivity. The splash activity will redirect you itself to MainActivity.
In fact, this is exactly the default behavior of the launcher icon.
However, I can't get my app to behave this way when the notification is pressed. Either it's always opening the SplashScreen, or it's always opening the MainActivity directly and skipping the Splash Screen.
Ideally, I would like to do this:
Intent intent;
if (MainActivity already exists) {
// Bring that instance of MainActivity to the foreground
intent = new Intent(this, MainActivity.class);
} else {
// No UI activity exists for the app. Start from the Splash Screen.
intent = new Intent(this, SplashActivity.class);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
...
// later
notificationBuilder.setContentIntent(pendingIntent);
But I'm pretty sure I shouldn't be checking for the existence of MainActivity myself. I should be using a combination of Intent Flags and activity launch modes.
in the manifest you should add the following to your main activity
android:launchMode="singleTask"
then my notification looks as follows
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context, MainActivity.NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(text)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text));
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
Intent goToAppIntent = context.getPackageManager()
.getLaunchIntentForPackage(context.getPackageName())
.setPackage(null)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
PendingIntent piGoToApp = PendingIntent.getActivity(context, 0, goToAppIntent, 0);
mBuilder.addAction(0,"go to app",piGoToApp);
mBuilder.setContentIntent(piGoToApp);
let me know if it helps

Firebase FCM send notification OnMessageReceived PendingIntent show current activity

I have an app with several activities. I am implenting Firecbase FCM and it all works pretty well except in handling which activity to go to when the user clicks on the notification icon when it is received.
As I'm not sure how/when the FirebaseMessagingService is instantiated I cannot set it up with access to any of my objects. The only thingI have been able to do is to store the current Activity in the App as
public static Activity CurrentActivity { get; set; }
I then set the above in the OnCreate() of each activity, then in FirebaseMessagingService .OnMessageReceived() I setup my pending intent as below:
Intent intent = new Intent(this, App.CurrentActivity.GetType());
intent.AddFlags(ActivityFlags.SingleTop);
var pendingIntent = PendingIntent.GetActivity(this, App.NOTIFICATION_ID, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, App.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.ic_notification)
.SetContentTitle("FCM Message")
.SetContentText("test")
.SetAutoCancel(true) //dismisses the notification on click
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(App.NOTIFICATION_ID, notificationBuilder.Build());
This works in so far so when the user clicks on the Notification it goes to the correct activity.
The problem is if a notification is recevied when the user is in Activity A but doesn't click on it and moves to Activity B and then clicks on the notification. My Pending Intent will be Activity A. However after the Notification is shown, Activity A is then displayed.
I was thinking if it is possible in OnMessageReceived() to detect is the app is in foreground or background then if in foreground I could just do and intent to display an Alert Dialog of the message and if in background then my original code would work fine.
Does anyone have any idea if this is possible and how?
I have managed to sort this out so thought I would post an update for anyone else who has a similar problem.
In my FirebaseMessagingService.OnMessageReceived() I created a PendingIntent to a standard activity called NotificationActivity.
public override void OnMessageReceived(RemoteMessage message)
From message I extracted the body and title and passed to NotificationActivity
NotificationActivity.OnCreate() will then just display an AlertDialog and on the OK click I closed the activity using this.Finish()
This works perfectly when the user receives a notification when in the app. The user can click on the notification and it will show the AlertDialog. On close it just resumes on whatever was the current activity.

Open Activity from Notification click when app is killed?

I am implementing calling functionality in my application with Twilio SDK. I am showing notification as soon as call starts, so the user can hang up the call from the notification bar. The problem is if user kills my application forcefully, I am not able to open the same calling activity from notification tray as my application is killed.
1: How can I detect if my app gets killed.
2: How Google play music notification works ( on click of notification
it open the song detail activity - even though the application is
killed).
3: How can I retain the same objects initialized at the time of
creating the activity to disconnect the call.
Try this
Intent intent = new Intent(context, NotificationActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle("title")
.setContentText("Test notification")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(contentIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH);
hope this help

Android Notification Click - don't backstack activity

I have a service in background which gives a notification.
I want the next thing:
If I click the notification and the app is not opened open the XActivity.
If the app is opened and the XActivity is created, go there and don't recreate the activity (because if this happen, on back key i will see the same activity again).
My notification code
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("New posts!")
.setContentText("New funny posts had just arrived! Click here to see them!");
mBuilder.setAutoCancel(true);
Intent resultIntent = new Intent(context, XActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
I start the service from the XActivity. (just a activity name example)
Thank you.
i had the same problem, what i did was , i added this line android:launchMode="singleTop" to my activity in manifest, and it worked.
Problem for duplicate activity in your case is because of standard structure design of Activity in Android. For creating only single instance of activity (no duplication) you need to give launchMode property to your activity in your manifest file. You can use singleTop property for this behaviour. You can read more in provided link.
In Addition, for new data access you can use onNewIntent() for new intent coming to this activity and set intent using setIntent() and continue working with new data.
Hope this helps.
Thanks.

Categories

Resources