Scenario:
I have an app, let's call it app A.
A opens an activity of App B, using Intent.ACTION_VIEW,
and then calls finish().
Problem: App A is still found in recent apps even though I finished its last activity. However, it's window looks black.
Question: Is it possible to detect when the "Complete action using -app-" screen is finished so I can programmatically close my app or how can I properly make sure the app is gone after going to App B?
There are several things here:
The list of recents is NOT a list of recent apps, it is a list of recent tasks. If you launch another Activity, then that Activity (even if it is from a different App) usually ends up in the same task as the Activity that started it.
If you don't want your app to show up in the list of recent tasks, then you should set android:excludeFromRecents="true" on the root Activity in the manifest of your app.
You can also launch App B in another task, by adding Intent.FLAG_ACTIVITY_NEW_TASK to the Intent you use to start App B. This will cause App B to run in a different task than your app A.
I've no idea why, when you return to the task started by App A, the screen is black.
Related
I have an app that acts as sortofa bridge between two other apps, A and B, both of which are mostly black boxes. The user almost always stays in app A but sometimes needs to do something that my app or app B know how to handle. App A supports external actions via URL so I have a custom scheme://host defined for my app.
If the user does an action that my app handles, I get launched via the URL then do my thing then call finish() and the user's back in app A where they started (edit: same activity and etc) - perfect.
If the user does an action that app B handles, my app needs to be in the middle so it can do some translation. App A launches me, I format the message for app B and launch it. When it's done and comes back to my app, I call finish() and.. end up back in app B. Understandable I guess but I really want to end up in app A.
So the question is, how to I tell Android to put A back on top/in front without changing it? I can find the URL for app A via getReferrer() but when I put that into an Intent, it acts like I'm restarting app A instead of just going back to where it was. The doc for Intent.FLAG_ACTIVITY_NEW_TASK looked promising but it still acts like a new instance of the app.
It seems like this should totally be possible but I'm not seeing it. Java/api25.
The problem is that App B is not ending, returning control to your app. App B is launching your app, putting your app on top of it. When your app finishes, your app goes away revealing the still running App B underneath.
So basically App B has bad behaviour (at least, behaviour that is inappropriate for what you are trying to do).
To solve the problem you can either fix App B, or you can do the following:
Instead of just calling finish(), when you want to return to App A just launch it the same way that Android launches an app when the user presses on the app icon:
Intent intent = getPackageManager.getLaunchIntentForPackage("package.name.of.app.A");
startActivity(intent);
finish();
This will bring App A to the front in whatever state it was in when it was put in the background (ie: doesn't actually launch any new Activity). If App A isn't running, it will launch the root Activity of App A, as if the user pressed the app's icon on the HOME screen.
I'm assuming that both App A and App B are running in separate tasks. If that isn't the case, I'll need you to provide more information about which activities are running in which tasks.
Following procedure:
Start my application, Stack: [HomeActivity]
Going to Facebook, using a deep link to get into Activity X
Pressing back button results in getting back to HomeActivity instead of Facebook
Expected
Start my application, Stack: [HomeActivity]
Going to Facebook, using a deep link to get into Activity X
Pressing back button results in getting back to Facebook App
I get the expected behavior when my application is not started at all beforehand. I see that other apps like Instagram does managed to get this working properly. So even if your application is running in the background it takes you back to the activity which issued the deep-link intent.
My activity has launchMode="singleTop", onBackPressed() is not overriden, so it calls the super class implementation.
What am I missing here to get this right?
I debugged it and onBackPressed() eventually calls finish(), yet it gets me back to my application instead of Facebook.
Add
android:taskAffinity=""
to the <activity> tag for your "deep-linked Activity" in the manifest.
What is happening is that Facebook is launching your "deep linked Activity" with Intent.FLAG_ACTIVITY_NEW_TASK (you should be able to verify this by checking the content of the Intent in your Activity in onCreate() or onNewIntent().
If your app is already running, Android brings your existing task to the foreground and launches the "deep-linked Activity" on top of that task. When you then press BACK, it just finishes your "deep linked Activity" and drops you into your existing task.
Android does this because all of your activities share the same taskAffinity, so when it needs to create a new task for your app, it will first try to find an existing task with the same affinity.
If you set the taskAffinity of your "deep linked Activity" so that it is empty, this should prevent Android from looking for an existing task to launch the Activity into. It will just create a new task and launch your "deep linked Activity" into that new task. Then, when you press BACK, your Activity is finished, and the task will become empty, so the task will be finished and it will drop you back into the previous task in the task stack (which should be Facebook, since your app was launched from there).
The reason is that the launch of Facebook starts a new task. Back always navigates up the activity stack within a task.
If you have control over the intent which launches Facebook, there are flags which control the task the activity is launched within. The default is to launch within the same task.
I suspect that Intent.FLAG_ACTIVITY_NEW_TASK is being added intentionally by the system -- so this may be by design (working as intended).
PS: This presentation will teach you all you ever need to know about android activities and tasks: http://www.slideshare.net/RanNachmany/manipulating-android-tasks-and-back-stack
1.install an apk from app installer
2.then just click "OPEN" to launch it at once
3.after the app launched and then press HOME key
4.find the app from app list and click its icon to launch again
5.then the app will be launched with a new instance.
And if you repeat 3~5 several times, it will repeat create a new instance. if you press "BACK" key now, you will see the app is still there for the same times you launched.
But if you just click "DONE" at step 2 and then launch the app from app list, everything will be OK then.
Why?
The app installer (as well as many Android IDEs) use different intent flags than the regular app launcher does, which means that the launcher's intent doesn't properly match with the Activity's existing intent and it ends up creating a new activity on top of the stack.
I think this question is similar to what you're asking about:
Activity stack ordering problem when launching application from Android app installer and from Home screen
Can anyone tell me what the difference is between opening an app from the applications screen and opening it from that recently used apps list that pops up when you long-press the home button?
I didn't even know that recently used list existed until a friend managed to break my app by launching it from there. He tried twice and got the same force quit, but when he launched it from the applications screen it opened fine.
The error log told me that a nullPointerException occurred in the getCount method on my ArrayAdaptor for my ListView.
Anyway I just wondered if there was a difference that I need to know about and adapt my code to deal with?
AFAIK, If your application is completely shutted down, launch from applications screen and recently used apps list should have no difference, both refresh start your application and open your application's MainActivity (by stack-push your application's MainActivity into a newly created task)
However, as Android is multi-task OS, your application can be put into background in standby mode i.e. open your application then short-press home button, this is not same as press back button. If you haven't override these key pressed in your application, press back button several times with pop all your activities off from activity stack and finally kill your application, whereas press home button will bring System's HomeActivity into foreground hence flip your application (AKA. task with activity stack) into background.
Things becomes more interesting here, depend on which value your configure your activity's android:launchMode in AndroidManifest.xml, if you use standard or singleTop:
1. launch app from recently used apps list always bring your standby activity back to foreground, i.e. re-order activity stack.
2. launch app from applications screen will create a new instance of your MainActivity and open it, i.e. push a newly created MainActivity into activity stack, so now you have two instances in your application's activity stack
If you use singleTask or singleInstance:
2. launch app from applications screen will use the standby MainActivity (if exist) in your application's activity stack and re-open it, i.e. re-order activity stack.
Checkout Tasks and Back Stack to see how different configurations may affect your application's activity stack behaviour.
I believe there should be no difference. These are the lifecycle methods I typically see when pressing the home button from an activity, on android 2.3.4
onPause
onStop
then when I use either the icon or previous applications to navigate back, I see
onRestart
onStart
onResume
Now, in some cases the system will tell your activity to finish while you are away (or immediately when you return if an orientation change occurred). Then you will see onDestroy, and the following when you navigate back
onCreate
onStart
onResume
I don't think there is anything mysterious going on here. According to the Activity documentation, there are only four states that a process can be in, and both of these fall under background activity.
There shouldn't be any difference in how the activity is launched from history, apart from the fact that the launching Intent will have the FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY set.
Here's an easy way to think about it. All of your activities are launched form Intents. Holding down the home button allows you to open that activity using the last intent that launched it. This can give you some unexpected results however. For instance, if you are able to launch your activity from something special like a widget.
I have two activities, but they are in different packages.
Now I call an Intent in the first activity to launch the second activity. This is working. Also I can get back with finish().
But now I kill the the app with advanced android task killer. The app disapears in the list
If I was on the second activity and then go to advanced task killer to kill the app and after that I start the App again, it launches the App on the second activity.
I have never seens such a behavior.
Also if I fire an Intent on the second screen in order to get back to the first activity and then call there System.exit() the App jumps on the second screen.