I'm developing notifications in my app, and I'm having some issue with the pending intent that is driving me crazy.
Normal flow: My app has the launcher activity (Activity A, singleTop) which shows a Splash and then launches Activity B (singleTop too).
Notification:
When app is in background, I show a notification on the notification bar, which opens the launcher activity of my app when clicked, through a PendingIntent. This PendingIntent addresses to Activity A (singleTop). But in this scenario, instead of open Activity A, it brings to foreground the Activity B, but without calling onNewIntent() (onResume() is being called instead), so I can't retrieve the extras of the notification Intent and show the information, because this Activity B.getIntent() retrieves the old intent which opened the activity the first time.
Can any of you bring me some light on this issue, please?
This is how I set up the PendingIntent:
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TYPE, "Notification");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_MESSAGE, "Message");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TITLE, "title");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Edited:
Following the answer given by #Woodi_333, the code for creating the pending intent is as follow.
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TYPE, "Notification");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_MESSAGE, "Message");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TITLE, "title");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Some code would help but I can take a guess at what is causing this.
So it sounds like the Activity Stack before clicking the PendingIntent is A,B. When opening the PendingIntent, it closes B because of FLAG_ACTIVITY_CLEAR_TOP but leaves activity A alone so it remains running.
So onNewIntent won't run because A is still running, and the FLAG_ACTIVITY_SINGLE_TOP flag won't cause it to run as when the intent is fired, it is not on the top of the history stack.
You might want to combine it with FLAG_ACTIVITY_NEW_TASK as suggested in Documentation for FLAG_ACTIVITY_CLEAR_TOP
I'd also recommend looking at the flags you defined in the manifest to see if they are interfering with the flags of the Pending Intent, or add them to the activities so every time you launch them, they are obeying the same rules.
Related
I'd like to start multiple activities when press on Notification. I didn't find any docs about how to set multiple intents in a single PendingIntent.
One solution could be to start next activity in the first one's onCreate() and so forth, but I don't like this, maybe there is something else.
Finally, I got the answer for this - it's pretty trivial, just using method getActivities() to the PendingIntent like so:
Intent myIntent1= new Intent(ctx, MyActivity1.class);
myIntent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
Intent myIntent2= new Intent(ctx, MyActivity2.class);
Intent[] intents = new Intent[]{myIntent1, myIntent2};
PendingIntent pendingIntent = PendingIntent.getActivities(ctx, pid, intents, PendingIntent.FLAG_ONE_SHOT);
I can't find a way to pass extras from widget to Activity properly.
I wan't to open activity on button click with some extras passed.
Intent intent = new Intent(context, CreateOperationsActivity.class);
intent.putExtra("someKey", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, Constants.RequestCodes.CREATE_OPERATIONS, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.add_expense_button, pendingIntent);
Activity is opened, but there is no extra in the Intent.
The only way I was able to pass that extra was seting PendingIntent flag to PendingIntent.FLAG_ONE_SHOT but then widget button works only wonce, clicking it further takes no action.
How to do that so the extra is intercepted by Activity and the button works each time?
You're probably missing setAction() for your Intent ;) See this one for a better explanation: https://stackoverflow.com/a/3128271/515423
I use this code, inside a notification, so when the user taps the notification the MainActivity starts:
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
If the user exits the app with the back button and taps a notification then main activity starts but if the user exit the app with the home button a new MainActivity starts over the first one. How can I detect if the MainActivity is loaded?
Thkx
You should add flags to your Intent to specify this behavior. Something like FLAG_ACTIVITY_CLEAR_TOP may be what you're looking for. This will finish any Activities on top of MainActivity (if any) and bring any existing instance to the foreground. If no instance is available, one will be created. Depending on your launchMode, you'll either get a callback to onNewIntent() (receiving the new Intent you provided) or the activity will be recreated with the new Intent.
Intent mainIntent = new Intent(this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent.getActivity(this, 0, mainIntent, 0);
I'm a bit confused with pending intents in the notification builder. I've got a MainActivity activity and a MessageList activity. I have a service to show a notification when a new message in found, and I want it to be that if the user presses the notification it opens to the MessageList activity but when they press back they will return to the activity they were in.
Essentially I want to add MessageList activity to the top of the activity stack when they press the notification without modifying the current activity stack.
Thank you
Okay, so I got it to work with some old code I wrote a while back. This does what I wanted -
Intent notificationIntent = new Intent(this, AlertListActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
mBuilder.setContentIntent(contentIntent);
I've a service which starts a notification with startForeground(), I want the notification to launch an activity on click.
The acitivty I want to launch defined as android:launchMode="singleTask" and usually runs before the service starts.
Here is my pending intent creation code :
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
When I click on the notification I get the following warning :
startActivity called from non-Activity context;
forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent........
I've also tried getting the activity with this instead of getApplicationContext() but got the same warning.
How should I make this right ?
Don't use Intent.FLAG_ACTIVITY_NEW_TASK for PendingIntent.getActivity. Better use FLAG_ONE_SHOT.
And try to use Context of Activity instead getApplicationContext().