Issue in activity backstack - android

Activity A is the launcher activity. I have a broadcast receiver which receives the incoming message and calls activity B (just a popup to display the message).
This is the code I am using to call B:
intent.setClass(context, popup.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
Whenever activity B is called, A comes behind it (foreground) even if it is in the background. A is not called anywhere in the receiver.
How can I call B without having A displayed behind it?

Activity B needs a different taskAffinity than ActivityA. In your manifest, add this to the ` tag for ActivityB:
android:taskAffinity=""
When you do what you are doing, when Android wants to start ActivityB, it finds an existing task with the same taskAffinity as ActivityB and it brings that task to the foreground (even though you specified that you want a NEW_TASK). It's a feature, not a bug ;-)

Related

How to send app to background after finishing activity which is started from push notification

I have an activity which is called if the app receives a push notification. The activity is started with FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TOP. The activity, let's call it 'A' shows UI and finishes after a while. In this point have a problem with activity stack.
Scenario:
The app is in the background with another activity 'B'
Then the app receives a push notification and starts Activity A.
After related things done, the app finishes Activity A
Then returns to Activity B and stays in the foreground even the app was in the background before the push notification is received.
After debugging, I figured out that the system calls onResume method of Activity B after finishing Activity A.
How can I do the app keep staying in background if the app started from background? Should I change intent flags of the activity A?
In your case you can achieve this in two ways
1- From manifest file with activity tag android:noHistory="true"
2- From code when you are staring the activity set flags like below
Intent mIntent = new Intent(context, Youractivity.class);
mIntent.setFlags(mIntent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(mIntent);
For more information checkout developers link
One other thing you can do is instead of this.finish() in notificationActivity is to use this.finishAffinity();. This will close the app instead coming to foreground.

how to start launcher activity after app goes to background?

I want to always start launcher activity after app goes to the background. I tried android:clearTaskOnLaunch="true" but it not work. How can i do this? For example i have A,B,C,D,E,F activity. A is launcher activity.
now i open app so A activity is called then A>B>C. now i minimize the application. Now i open application from the icon so app is start from C but i want it start from A so how can i do this? some said use onResume intent with Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK. but what if i press back button then onResume is called and my app start with A activity.... so it is not work..any solutions???
You can check the App is in foreground or is in background and when the application goes to the background state at the same time do some logic that when your application comes to foreground it will always show the root activity.
How you can identify application is in which state is well explained here
When you start Activity B, use these flags. That way Activity B and C will always be in a separate stack. That means that when someone starts Activity A from the home screen they will see Activity A always.
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
Intent intent = new Intent(context, B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent);
Also this might help, you can add this flag to your root Activity.
<activity
android:name=".ui.MainActivity"
android:clearTaskOnLaunch="true"/>
This does because device store data about application. For short time data are stored. if you want to start application from rot class. use service with application, so that whenever your application goes in background and pause then choose your action to do that will be easier.

How to put in foreground an Android activity that is in background

I read several similar questions here, but I didn't find a clear reply to my question.
I launch my Android App and I have my main ActivityA in foreground
after some time I push a button (of ActivityA) and I open (and put in foreground, then visible and ontop) ActivityB. I do it simply by the command myContext.startActivity(myIntent);
It means that now ActivityA is in background (onPause()), then not visible.
After some time I push another button of ActivityB with the target to put in foreground (then visible and ontop) again previous ActivityA
What is the correct and best way to do it? According to my understanding (but I'm not sure it's correct.) it shouldn't be by startActivity(), because startActivity() creates another instance of ActivityA (it calls onCreate() ) and then there will be 2 instances of ActivityA running (one in foreground and one in background). What I want to get is a calling of onResume() for ActivityA (and not of onCreate() ).
The second question is: how can I know if ActivityA is still alive in background? Maybe after sometime the system killed it to free resources.
Note: the solution in my case cannot be to use finish() to destroy ActivityA when I open ActivityB, and then to use startActivity() to reopen it, because I need ActivityA alive as much as possible.
Thank you very much in Advance
Fausto
What you need is the FLAG_ACTIVITY_REORDER_TO_FRONT when starting a new activity. This will cause a background activity to be be brought to the foreground if it's running, or create a new instance if it's not running at all.
From inside ActivityB:
Intent intent = new Intent(this, ActivityA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
What is the correct and best way to do it?
Use startActivity(), with an Intent on which you have added Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
it shouldn't be by startActivity(), because startActivity() creates another instance of ActivityA
While that is the default behavior, Intent flags can alter that behavior.
how can I know if ActivityA is still alive in background?
If you did not finish() it, and your process has not been terminated, it exists.
Maybe after sometime the system killed it to free resources.
Android terminates processes to free up system RAM. It does not destroy activities on its own.
because I need Activity A alive as much as possible
To be honest, that suggests that you have other architectural issues. Bear in mind that activities are destroyed and recreated for various reasons, such as configuration changes (e.g., screen rotation). Activities should be very disposable.
You can use following
1. For launching new instance (current state of ActivityA) and get ActivityA on Top of Stack
Intent intent = new Intent(this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
2. For launching old instance and get ActivityA on Top of Stack
Intent intent = new Intent(this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
For more detail please check
Task and Back Task
You can use StartActivityForResult in the place of StartActivity in activity A and on activity B you can setResult when you want to open Activity A again.In that case OnActivityResult() of activity A is called not onCreate().

android - launchMode=singleTask and Notifications?

I know there's been a few posts for what I'm about to ask but I can't find any with the right answer.
From my understanding, if your main activity's (let's call it A) launchMode is set to singleTask, and A has initiated activity B then a click to the home button will destroy the history stack and re-launching the application will take you back to A and not B.
I have launchMode set to singleTask because I have a persistent notification and I don't want to have multiple instances of the main activity to appear whenever the user clicks on the notification.
Is there something I'm missing that would allow me to cater for both?
So I'm asking if there's a way I can ensure that whenever the user wishes to launch the app, from the notification or not, to take him back to the last (current) activity.
If I change launchMode to singleTop it works but I get multiple instances of the main activity whenever I launch it.
Thanks
Andreas
Have you tried setting launchMode to singleTop to all the activities in your app?? Because what i get from your query is that the main activity isn't singleTop, so that might lead to another instance of the main activity being called once the main activity is launched from the activity that was launched from the notification activity.
Or you can specify the launchMode as an attribute to the application tag itself in the manifest.
I use the following code to avoid multiple instances of the activity
Intent intent=new Intent(this,RICO.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
Changing manifest doesn't look appropriate to me
I'm having issues with both the approches.
The notification works flawless only in this condition:
- using the back button in the main activity (with the history containing only the that activity)
- not using the Home button
- not using the notification IF the activity you are calling is on top and active
In any other case, the notification cannot anymore call on the foreground the activity by using "new Intent(...)"
I've found the alchemical combination of manifest options and intent's flags for getting what I needed:
Intent intent= new Intent(this, YaampActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
using these options
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true"
inside the element.
Now I've a notification which spawns the main activity (if that activity is not already in the foreground) and its behavior is correct even if the activity is "closed" by pressing the home button and/or the back one.

Why does starting an activity from a widget cause my main activity to start as well?

When I start an activitiy from a widget I want the back button to go to the home screen but instead it goes to the app's main activity. After toying around I found that if I somehow close the main app activity, this problem doesn't occur. Strange.
I found a solution here that said to call finish(); in my main activity's onPause(). Obviously this is the wrong solution e.g. reorientation of the screen causes an onPause() so the will activity will die whenever the phone is rotated.
This is how I start my activity:
#Override
public void onReceive(Context context, Intent intent) {
[...]
//new Emergency().emDialog(context).show();
Intent myIntent = new Intent(context, EmergencyActivity.class);
// FLAG_ACTIVITY_NEW_TASK is needed because we're not in an activity
// already, without it we crash.
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
You can see the rest of the code at http://code.google.com/p/emergencybutton/source/browse
edit: I tried running the activity differently, but still it doesn't work correctly:
Intent myIntent = new Intent();
myIntent.setClassName("com.emergency.button", "com.emergency.button.EmergencyActivity");
Ok, so I'm not exactly sure what happened here but android:launchMode="singleInstance" in the activity in AndroidManifest.xml fixed it somehow.
<activity android:name=".EmergencyActivity"
android:launchMode="singleInstance"
#Octavian - I should have clarified that I start the activity from an onReceive in an AppWidgetProvider. I'm at the home screen, starting an activity titled B, but somehow both A and B are in the activity stack instead of just B.
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Although I've never used widgets, I believe that when you click the widget you are resuming an existing task. Hence, when you are in that task, you will return to the latest activity in that task (instead of Home).
See this link and choose the proper launch mode for your widget
http://developer.android.com/guide/topics/fundamentals.html#lmodes
The behavior is not strange it is just the way Android works. The activity stack just keeps track of the all the activities. Now when you start an activity A which starts another activity B then your stack looks like (B, A). If you press the back key then activity B is going to get popped off the stack and A is going to be brought to foreground again.
The right solution is to just call finish() right after firing off the Intent.
Sometimes it's not possible to use launchMode singleInstance in application for some reasons.
In this case, you should start your activity and clear activity stack. You can archive this using flags. There is an example:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Categories

Resources