So I have a basic notification application. Here's the current configuration details:
GCMIntentService
NotificationActivity
:
---->ViewMessageActivity
:
---->ViewUserDetailsActivity
GCMIntentService is configured to do the following: Upon receiving a notification, a pending intent with PendingIntent.FLAG_ONE_SHOT is created and the intent adds the Intent.FLAG_ACTIVITY_NEW_TASK flag.
Currently, I have my NotificationActivity defined in my manifest as android:launchMode="singleInstance". If I set it to android:launchMode="singleTop", when the user clicks the notification a few things can happen depending on Android Version (or so my two devices show)
In Android < 2.3, If I'm in another activity (say ViewMessageActivity) and I press the notification from the shade, nothing happens (I don't receive anything from onNewIntent)
In Android 4.2 (Not sure about other versions), If I'm in another activity (say ViewMessageActivity) and I press the notification from the shade, nothing happens (I don't receive anything from onNewIntent) AND the notification disappears from the shade
If I'm in NotificationActivity everything works great regardless of version
So this led me to set it to singleInstance instead of singleTop. Now when the user presses the notification and the user is in a different activity (say ViewMessageActivity), the notifications intent is handled appropriately HOWEVER, my NotificationActivity tries to create a new instance of ViewMessageActivity for the message clicked in the notification shade and it does not create a new activity. Instead, shows my already opened instance. I've tried adding flags such as Intent.FLAG_ACTIVITY_NEW_TASK but neither my onCreate or onNewIntent methods are called in my ViewMessageActivity.
Ideally, this is what I would like to happen: When the user has navigated to another activity (say ViewMessageActivity) from the main activity (NotificationActivity) and the user presses a notification from the notification shade, I would like the NotificationActivity to be flagged to update its ListView view onNewIntent which will create another ViewMessageActivity instance. Note: I have no launchMode option set for any other activity.
Any suggestions?
Vince
Related
Using Firebase Cloud Messaging, when the app is in the background and a message has arrived, the message goes to the system tray. When the user than clicks on the notification, the app gets launched and the launcher activity gets the message data in the Intent.
In my case, this notification is about some new results, so when pressed, I want to start a ResultsActivity.
In order to make this happen I do this in the OnStart of the LauncherActivity
:
Intent intent = getIntent();
String searchId = intent.getStringExtra("search_id");
if(searchId != null){
Intent resultsIntent = new Intent(LauncherActivity.this, ResultsActivity.class);
resultsIntent.putExtra(ResultsActivity.SEARCH_ID_EXTRA, searchId);
startActivity(resultsIntent);
}
This all works great.
The problem is now when clicking on the "up" arrow on the app bar, the app does not go to the parent activity that is defined in the manifest (which is not the launcher activity) but to the launcher activity. This is not surprising since the ResultActivity is started from the LauncherActivity, but this is not the wanted behavior. The wanted behavior is for the back arrow to send to the parent activity, which happens to be MainActivity.
I know there is the TaskStackBuilder for that kind of stuff, but I don't know how I can apply that pattern to my case here where I start the activity "normally" from another activity and not from some Notification Builder.
Is TaskStackBuilder the right solution here? If so, how can I change the code above to use it? if not, what is the right solution for this?
What I ended up doing is on the server side, with the firebase cloud messaging admin, instead of including a firebase_admin.messaging.Notification object in the firebase_admin.messaging.Message object I am then sending, I just put the notification title and text in the Message's data, and then build a notification by myself normally in MyFirebaseMessagingService. Since I'm now building the notification by myself I can add the TaskStackBuilder normally.
I guess this doesn't really answer the question of how to add a back stack when not using Notification.Builder, but it's probably a better solution anyway.
Any one can tell me how could i get inbuild notification listner in android. What all i want is if user put password on screen and if then some notification arrives. and if user click on notification, I want password field should be reset.
See http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CreateNotification to create a local notification.
In the intent you use for the notification add an extra bit of data that you define (e.g. "ClearPassword" as a boolean of true).
In your activity, check for extras and your specific extra and if it is set then you can clear the field.
Why don't you just clear the password field in the onPause method of the activity? If the user clicks on the notification, the pending intent will launch a new activity (most in the cases from another application). When your activity is no longer the foreground activity, its onPause method will be called.
I've created a receiver to receive and display push notifications - when the user presses on the push notification it opens a deep-link within my application. The problem is that when the user presses "back" he doesn't exit back to the home screen, but rather he goes to whatever screens for my application were open before on the application backstack - even if the application was minimized before he pressed on the notification.
The behavior that I need is for the user to be on the home screen, for him to open the notifications panel, press on my notification, go into the deep link page in my app, and when he presses the back button - I want him to exit all the way out to the home screen again. I don't want him in any way interacting with the backstack for the main application.
I've tried numerous combinations of flags for the pendingIntent in the push notification. Everything from FLAG_ACTIVITY_TASK_ON_HOME to FLAG_ACTIVITY_NEW_TASK to FLAG_ACTIVITY_SINGLE_TOP, etc. No combination seems to give me what I want - in every single case, opening the deep link with the app minimized will always return me to the next page in the history of the app when I press the back button. How can I solve this?
Example code:
Intent notificationIntent = new Intent(this, DeepLink.class);
notificationIntent.setData(Uri.parse(url));
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(getBaseContext(), 1, notificationIntent, 0);
Solved. The deeplink class was starting an intent for each deeplink and these required that I set the flags NEW_TASK and CLEAR_TASK for each one. After that - everything worked.
I have an odd issue with my application.
I start the application and the activity shows ok.
I then press the home key so that the activity goes into the background. I can see the onPause() method being called.
The application's service then creates a notification which shows on the status bar.
I then click on the notification and the activity is shown and I see that the onResume() method is called.
I then press the home key and the activity goes into the background. I can see the onPause() method being called.
If I now start the application by clicking on the applications icon I see that a new instance of the activity is created rather than using the paused instance.
If I press the home key again the new activity goes into the background.
Starting the application by clicking on the applications icon I see another new instance of the activity is created.
Pressing the back button at the point destroys each activity in return.
What I want to happen is that a single instance of the activity be used.
Any ideas?
Just use the same intent filters as android uses when launches the app:
final Intent notificationIntent = new Intent(context, MessageListActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
As the intent you created to open your activity from notification bar is the same as android used for launching your app, the previously opened activity will be shown instead of creating a new one.
You should look at the different launch modes for Android activities. this should help. Launch modes can be set in the androidmanifest.xml file. I think your solution would be to use the 'singleTop' launch mode.
Say that the user has started my App and then switched off to use the Browser (so we have 2 sets of Tasks running). After a while, something happens to my app that requires the user's attention, so it posts a notification to notify the user. Is there a way to bring my App's task (and the Activity on top of the stack) out from the background when user clicks on my notification?
In your notification you call an intent to start your app, if you ensure it has the following flags then it will be brought to front rather than creating another instance:
Intent contentIntent = new Intent(this, ABC.class);
contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | INTENT.FLAG_ACTIVITY_SINGLE_TOP);
A notification usually comes with a PendingIntent (Notification.contentIntent). Set this intent to your app to start an activity of your app.
There is only one Activity that is currently active - as soon as you switch to a different screen, the system will pause your activity (onPause, and very likely onDestroy), so you'll need to use an intent to bring resume your activity and bring it to the main screen.