Background
Let's take the next sceneraio:
the user uses an app X which has multiple activities (like the gmail app).
after navigating the app X a bit, he goes to your app.
in your app, you need to start this X app using an intent, to go to a specific activity within it.
now the user goes to this specific activity on the app X.
the user presses the back button, hoping to go back to your app instead of staying on the app X.
another similar scenario:
the user navigates on your app between activities.
your app went to the background (using the home button, for example).
your app shows a notification that once clicked, it will open a specific activity of your app.
the user clicks on the notification and goes to the specific activity of your app.
the user presses the back button, hoping to return to the app that was shown before clicking on the notification, instead of going to the previous activity on your app that was shown the last time it left it.
It seems that the last step on both scenarios isn't the default behavior.
This is why I've searched what is the best combination of flags for this purpose.
The problem
It seems that the only flag that can achieve the behavior i've described is Intent.FLAG_ACTIVITY_MULTIPLE_TASK (together with Intent.FLAG_ACTIVITY_NEW_TASK).
According to the android API, however, this flag isn't recommended for normal use:
Do not use this flag unless you are implementing your own top-level
application launcher.
...
Because the default system does not include
graphical task management, you should not use this flag unless you
provide some way for a user to return back to the tasks you have
launched.
This information seems as confusing as the rest of the descriptions about intents.
There are other intents flags that I've seen, like Intent.FLAG_ACTIVITY_CLEAR_TASK that achieve a similar result, but they have weird behaviors and/or they use high API
The question
Is it safe to use this flag? Are there any good alternatives to it?
What is the danger of using this flag and what is the meaning of the description on the API of using it?
In your first scenario, if your app needs to start an activity of another app, it can just start this activity within the same task as your application. There is no reason to use any special Intent flags for this (you don't need FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_MULTIPLE_TASK). In step 5 of your scenario, the user will return to your application (because BACK just takes him to the previous activity in the current task). This is the standard, default behaviour.
In your second scenario, my first response is "that isn't the standard behaviour". That means that users probably won't expect to be able to go back to the task that they were doing prior to clicking on the notification. However, if you really want to implement this, then I would suggest that you create a special Activity that is launched from the notification and this special Activity should have a different taskAffinity than the rest of the Activities in your application. In this case, when the special Activity is launched from the notification, it will not bring your application's task to the foreground. It will just create a new task containing just the special Activity. When the special Activity is showing, the user can press the BACK key and this will return him to the task that he was working on prior to clicking on your notification.
In general you should NOT use FLAG_ACTIVITY_MULTIPLE_TASK. The main reason is that if you have several tasks containing your application (or parts of it), it is pretty much impossible for the user to return to a specific one. There is no way to provide different launch icons or different application names (for the different tasks)(, so that the user will see multiple tasks in the "recent tasks" list, but will not be able to tell which one is which. You will have a hard time cleaning up what you are doing and you will just make more problems than you can deal with. There are about a million side effects of using this flag and for general applicaitons there is just no need to do it.
Related
Note: I haven't coded anything but looking for a structure/keywords or ideas how it can be achieved.
Use Case:
I have an activity which basically shows some display/data/or does some operation etc when opened manually from button click, notification click etc. Now I want to display the same stuff when a particular condition is satisfied [like my geo location matches that I force to be my home or user home].
1. without user clicking any notification,
2. without opening the activity,
3. without clicking buttons, and
4. without opening the app.
So in short, I want my app to be launched when I am home or reach a geo fence, is it achievable?
I am aware of Pending Intents, but seems they need the activity to be opened once and register the intent, let me know if this is the only way to go.
Kindly help!
when a particular condition is satisfied
This is not possible in general. For example, Android has nothing built-in with the ability to do something automatically based upon when your neighbor's cousin's daughter posts something on Stack Overflow. Even though that is a particular condition that could be satisfied, Android does not know your neighbor, nor your neighbor's relatives, nor the neighbor's cousin's children, nor the online actions of your neighbor's cousin's daughter.
There are specific things that Android can handle that offer the ability to give you control for related conditions, such as AlarmManager for getting control at certain points in time, or JobScheduler for getting control periodically when the environment is proper (e.g., we have connectivity and are on a charger).
Your question uses a geofence as an example. The Play Services SDK offers geofence APIs that you can use, that can give you control when the user enters a particular region.
I want my app to be launched when I am home or reach a geo fence, is it achievable?
You are welcome to call those geofence APIs, providing a PendingIntent that points to a WakefulBroadcastReceiver, which in turn points to an IntentService, where you can go do something.
If by "my app is launched", you mean bring up one of your activities, while that is technically possible using an activity PendingIntent, you may make your users very unhappy for interrupting what they are doing (e.g., collecting Pokémon). Please consider using a Notification instead.
I am aware of Pending Intents, but seems they need the activity to be opened once and register the intent
Nothing of your app will ever run until the user manually runs your app (e.g., taps on your home screen launcher icon) or until something else uses an explicit Intent to start one of your components. At that point, you can call the geofence APIs, assuming that you somehow know where the user's home is.
Most likely, you need the user to spend time in the activity simply to collect the data from the user about where they want the geofences to be established.
I have 2 different applications A and B and I want to create a special animation from B to A, that is when A is opened after B was visible. This means that I need to somehow know the previous app after which my app was opened. I can have different scenarios of going from B to A - using Recent Apps (multitasking) button, using Back button, using Home button (application A is a custom home screen). Are there any ideas how to do this? Some functions in ActivityManager might help, but they have comments in documentation saying not to use them for implementing logic and control flow.
Not sure if this will work across different applications, but how about getCallingActivity() or getCallingPackage()?
If that doesn't work, could you pass along some 'extra' data in the bundle when you launch the intent that indicates the launching application?
I managed to figure out how to implement this, its working for me.
I used this answer, but replaced the ActivityManager.getRunningTasks() with ActivityManager.getRecentTasks() supplying RECENT_WITH_EXCLUDED | RECENT_IGNORE_UNAVAILABLE, and took the component name from baseIntent member of the result. The info at index 1 is the one that was running before the current app was opened, irrelevant of the fact how you get back to your app - back button, home button, recents button or opened from another app.
NOTE: This works when your app is started, like in onResume() but doesn't work when your app is closed (when called in onPause()) because the new task is not yet loaded into the activity manager. So if you need to also know to which app are you going then it might be a bit more complex.
NOTE2: Although the documentation tells not to use the API above for any kind of logic and control flow, I saw that the multitasking/recent app's code is doing exactly the same, so in my opinion it should not be as risky as they write it docs.
NOTE3: Don't forget to follow all the steps in the answer I mentioned above, like adding needed permissions, otherwise you will get exceptions. Being part of the system in my case makes it much easier for me.
I'm working on large project, so there is some logic for saving application state, and then opening correct activity(fragment) when it comes from background.
But anyway, I've found that if user navigates through my app and then minimize it - android opens it from background in different ways in following cases:
User taps on app icon (behavior: user see home activity, doesn't matter where he was, when application was minimized)
User select app from android "recent apps" (behavior: user see exactly what he saw, when the application was minimized)
So, what is the difference between launching application from background by this two ways? I always thought, that it is the same mechanism, but, obviously, I was wrong.
Thanks for any answers
You should pay atention on the folowing docs Activity and Tasks. In short words: if user start app from recents you will receive onRestart before onStart (without onCreate it means that your app was just "suspended"). You able to save screen state using onSaveInstanceState(). But in general starting from icon and from recents - different application behaviors and you should provide proper code for this ways.
UPD
As described below root cause of unexpected behaviour was additional lunchmode attribute.
From what I experience as an Android user, both are same.
The difference we usually see is how we close the app
Press back button until app close / finish()
On this state no matter how we open the apps it will go to the main screen
Press Home button
On this state depend on the app. If the app does not handle any Activity the app will same with the first state. But if the app handle something like when onPause() the Activity then finish() the apps, then whatever you open with app icon or recent apps will provide the same result.
Correct me if I am wrong
I'm having a bit of an issue with interaction beween my app and other apps on my phone, but I'm starting to think that maybe it's working as designed? Anyway, here's the problem.
My App, call it App A is a photo-manipulation app. So a user goes in, plays around to make changes and then uses the Share button to pass it on (SEND Intent). The photo is sent to another app, chosen from the Share menu, call it App B. This stand-alone app has its own menus, completely different look and feel, etc. The user does his thing in this app for a bit, then hits the home button and goes his way to do something else.
Sometime later, he decides he wants to run my app again. He goes into the launcher, hits the icon for App A (my app), and up pops App B. Very confusing. If he happens to remember that last time he ran App A, he used the share button to get into App B, maybe he'll think to use the back button, to get back into App A. If he doesn't remember, all he knows is that he is trying to use App A, but Android is giving him App B.
(I have one app on my phone that takes over the back button for its own use so you more-or-less get stuck in App B with no way out. Ugh. You hit the icon for App A and always end up in App B)
Is there any solution to this, or is it working as designed? None of my onCreate, OnResume, onStart, etc. methods get called when this is second-open is occurring, so I can't trap it. And realistically, I can see the desire for this behavior when timelines are short - i.e. hit the home button, quickly use some other tool, and then go back to what you were doing. But with a timeline any longer than a minute or two, it gets very confusing.
Anybody else dealing with this problem? Is there a basic Android architectural issue here? Is the SEND intent being mis-used by being accepted by stand-alone apps instead of small utilities?
I think you may use Intent flag 'FLAG_ACTIVITY_NO_HISTORY'. It means starting intent never goes into activity stack.
Hi I have application with more than 20 activities.I want to close my app when Home button is pressed.
There is no notion of "close my app" in Android. Android will get rid of your activities, followed by your process, after some period of inactivity by the user.
You could use the launchMode and clearTaskOnLaunch flags on your root activity from your AndroidManifest.xml:
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
When you again start your app, all activities will be killed.
You don't want to do System.exit() -- that's not how the Android Activity Lifecycle normally works (read this also).
What you should do is move the App to the background with moveTaskToBack(). Android will then keep your app running in the background, and kill it if it's unused and something needs its resources later.
If you want it to close all of the open Activities when your App is no longer visible, you can set noHist = "True" for all of the child activities (leave the main activity with noHist = "False", though). This will make it where instead of reopening your application on the last Activity they were on, it will open it on the "main" activity (i.e. it will be as if they just restarted the app).
Anyhow, read through the following answers for more information: Close application and launch home screen on Android
I have the same problem. Im writing a banking app and am required, by contract, to log off the user (or exit) when the app is put into background. There are obvious security concerns there.
There are a couple of ways Im looking to do this:
1. Intercept home button (and back button for the root activity) key press events to call logoff and/or finish()
2. In the onStop() method, for every activity, detect whether the activity is being stopped due to a new activity being show - if not, assume app is being put to background so logoff and/or finish()
The first may not work if a notification is brought to the front then the user clicks home (I havent investigated yet). Or maybe there are other ways for an app to be put into the background without pressing these buttons
The second way sounds messy & difficult to maintain
Id welcome any other ideas
Drapes
I know android has been designed this way, but it seems naive to think that apps wouldnt want an applicationOnStop event
Hi guys what I understood is that u need to know when app goes in background and how to detect it and if I am wrong plz correct me----
The user can go in background if ur app does not provide any way by pressing Back key or Home Key.
You need to use methods "dispatchKeyEvent(KeyEvent event)" to get home key event or back key event and after getting the event you can execute your task.
you can even restrict user from pressing any key but u can not control the home key.