Preserve activity stack when notification is clicked - android

Using just the default way of displaying GCM notifications (and not using onMessageReceived() and GcmListenerService), is it possible to have the activity stack remain as it was and just bring the app to the foreground when a notification is touched? I'd like to get the same behavior as when the app icon is touched. Currently a new activity is launched each time a notification is touched.
Edit:
Here's the situation in detail. I've read that documentation but I'm still not able to get the desired behavior. Let's say my stack looks like this:
Activity B
Activity A
Activity B is currently on top and active. When the user pressed the circle button and then the app icon again, the same stack gets activated (resumed).
Now when touching on a notification in this situation I get this:
Activity A
Activity B
Activity A
But I'd like to just preserve this:
Activity B
Activity A
I've tried all launchMode variants but had no success.

It has more to do with the way your activity is set up. For example, you can make your activity a singleTop activity in your manifest:
<activity
...
android:launchMode="singleTop"
...
/>
This way when there's a new Intent for this activity, Android OS will not make a new instance of your activity, but rather pull up the existing instance and pass the new Intent through the onNewIntent(Intent) function (to make it work, you should override that method in your activity).
There are more ways to do this, check out documentation (the "Using the manifest file" section) to see what's the best fit for your scenario.

Related

Start new activity or bring up old one according to intent extra

What flag must I set for an intent so if the activity is visible with same extra it does not bring up a new one.
My app is somehow like google play. There are different app that are show in AppActivity by sending the app id as an Extra. User can download app and when download is finished, a complete notification is shown which on press brings up the corresponding activity page.
Currently by pressing notification it start a new activity which is correct for when AppActivity is not visible or showing another app. But it also start a new AppActivity even if the AppActivity is visible for same app.
PendingIntent.getActivity(ServiceDownload.this, id,
new Intent(ServiceDownload.this, AppActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
.putExtra(Constants.EXTRA_ID, id), 0);
Use Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP while starting your activity and define it single top at your manifest file.
If activity is somewhere in the stack, it will be brought to top(onNewIntent method will be invoked) and all activities above it, will be destroyed. If it is not in the stack it will be created (onCreate method will be invoked)
Edit: You have to handle onNewIntent to get bundle and update your current activity with new values.
Note: Also remember, system may destroy your activity and your both onCreate and onNewIntent methods can be invoked. Design your activity considering this.
Edit2: If you want to have many app details and user can navigate back with pressing back button. And also one detail for one app. Then you should use fragments. Add fragments by tag of your application id/name (something unique) and while showing an app detail search if any detail page exists with findFragmentByTag method. If it exists remove it and add it to top of the stack.

Could someone please explain FLAG_ACTIVITY_PREVIOUS_IS_TOP

I have an Android app with multiple activities. The main activity communicates over a network and can launch or dismiss various other activities depending on commands it receives over the network. When an Activity is dismissed I don't want to finish() it, just move it down the stack so it's no longer the top activity. What I really need is a FLAG_ACTIVITY_REORDER_TO_BOTTOM but there is no such thing.
There's an intent flag called FLAG_ACTIVITY_PREVIOUS_IS_TOP and the name implies something like that but I don't understand the description:
"If set and this intent is being used to launch a new activity from an
existing one, the current activity will not be counted as the top
activity for deciding whether the new intent should be delivered to
the top instead of starting a new one. The previous activity will be
used as the top, with the assumption being that the current activity
will finish itself immediately"
Could someone please decode that for me, and if it's not what I want IS there some way to tell an activity to submerge itself below the previous one?
This isn't possible. The activities are stacked and you cant put one back under the other. It sounds like you may want to create a class that extends Android’s android.app.Application.
I found this tutorial online and it looks good. Good luck.
Extending Android's android.app.Application tutorial
You cannot move an activity below a certain activity into the android back Stack. The only way to move a activity in back stack is to open another activity on top of it. You can move an activity on top by creating a single instance of activity using FLAG 'singleTop' in this way your activity will be moved to the top of another activity and only a single instance of activity will be there in stack.
More information about activity back stack and Flags is available here.
Go through this information and all your doubts will get cleared about back stack.

how to know if Activity resumed by shortcut or by another top activity

The main activity creates a shortcut to homescreen, all goes good but it needs to know an extra value when it starts by shortcut. So I used this while creating shortcut
intent.putExtra(EXTRA_ID, "Some string info here");
And onResume retrieve value like this
if (getIntent().hasExtra(EXTRA_ID))
ShowToast(getIntent().getExtras().getString(EXTRA_ID));
Everything works fine, lets take some examples
Activity never launched, Home screen shortcut pressed and A toast appears, Nice.
Activity is in background, Home screen shortcut pressed and A toast appears, Nice.
Activity is in use, another activity is launched, when back, toast appears, Not nice.
Activity is in background with no extra, Shortcut pressed, Nothing appears.
In 3rd example, it does what it suppose to do. But how do I know if activity is resumed/launched by shortcut ?
You set an extra in launcher Intent, and want to get the extra when this activity is opened in any state.
The problem you meet:
Activity is in background with no extra, Shortcut pressed, Nothing
appears.
This is because that your activity is started already, the launcher intent just use the existing task as the front task, and its extra data is lost in such situation.
To solve this, you need 2 steps:
Add android:launchMode="singleTask" to this activity in your manifest.
Put the extra data handling codes in both onCreate() and onNewIntent(), not in onResume().
How are you removing the extra EXTRA_ID? You should do it like:
In onResume():
if (getIntent().hasExtra(EXTRA_ID)) {
ShowToast(getIntent().getExtras().getString(EXTRA_ID));
getIntent().removeExtra(EXTRA_ID);
}

Android custom layout(alert) in service (similar to messenger)

My question is simply how can i do a dialog pop up from other application.
I search around and many answer is NO.
However, the messenger like Whaxxapp is exactly doing this. It can pop up an instantly reply while i am playing game, taking picture and etc. (like pausing)
And i had do some research and works,
i am able to create a service which start from my activity (activity A).
And the service is registered a contentobserver, when the observer onchange is fired, it can launch an activity(pendingactivity B) and the activity B which i had set the theme transparent and look like a dialog popup. however, it will also change the background back to my activity A and with the popup as well.
What i want to do is not go back to my activity A and just pop up (or launch the pending activity B) when i receive an onchange. (same as Whaxxapp pop up message with interaction)
Thanks so much.
You should start Activity B to new task. So when you press back activity A won't be shown. Add Intent.FLAG_ACTIVITY_NEW_TASK flag to Activity B intent.
I'm guessing, but I think the Whatsapp "Popup" is actually an Activity styled to look like a Dialog.
You can do this changing an Activity's theme to:
<activity android:theme="#android:style/Theme.Dialog" />
You can then add Button's, etc, just like a normal Activity to add interaction.

Destroying the Activity stack

I'm building an app that requires a user to have logged in and obtained a user id. This id is a member variable of my extended Application class.
I'd like the application to recognize when/if this variable gets wiped out and, if so, throw up my log in screen and destroy the Activity stack behind it.
Here's what I think I'm going to do:
Extend Activity and ListActivity (currently the only two types of Activities I am using). In the onResume() handler, check to see if the user id is set. If not, throw up the log in screen and destroy the rest of the Activity stack behind it. All of my Activities will derive from these new extended Activities.
My issue here is that I don't know how to destroy the Activity stack behind a particular Activity. Any ideas?
One idea is to have a broadcast receive listening for a particular message that tells Activities to kill themselves, but I'm hoping Android already has something in place for a situation like this.
Update:
Also, is there a way to clear the entire Activity stack? I'd like to override the onBackPressed() handler on an Activity and have the Activity stack blown out so the user gets taken back to the Android home screen.
Other choice will be using the noHistory parameter in the AndroidManifest.xml to accomplish this.
so your Activity should not be placed in the history stack
<activity android:name=".MyActivity"
android:noHistory="true" />
I agree with danh32, setting the FLAG_ACTIVITY_CLEAR_TOP on the intent to bring the Login Activity on top of the stack will destroy all activities behind the new activity (hence, the Login Activity). This will leave one activity on the stack.
Intent myIntent = new Intent(view.getContext(), DisplayMenu.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
finish();
I use this option to allow users to get back to a main screen from a long path through a lot of activities.

Categories

Resources