I have an activity which is declared in my manifest with android:noHistory="true", and 90% of the time, this is the desired functionality. This particular activity doesn't need to be saved in the application's history, and the application's UI flow is greatly complicated when it is in the history and needs to be manually removed by calling finish() every time the activity would otherwise be added to the stack.
The problem is, that this activity has the ability for the user to send an email, which is of course accomplished by creating an Intent with the ACTION_SEND property. When the user presses the "back" button from this activity, the next one to be shown in the stack is actually the one underneath my activity. Is there any way that I can force Android to add my activity in the history stack before presenting the ACTION_SEND intent?
I look forward to be proven wrong but I believe that the history stack is updated when the activity is created. At first I would suggest the rather hackish solution of launching a "proxy" intent that would be pushed onto the stack which could then call the e-mail intent and would be smart enough to launch the proper intent on the way back.
I'll update my answer if I find something in my notes.
Related
My app main launcher is the LoginActivity which, in most of the cases, at the end start MainActivity from where all actions in my app can be launched
This is the "normal" scenario
however, when someone lauches the app from share context, or notification the LoginActivity redirects him straight to the activity responsible for handling that specific scenario...
this way when the user presses "back" on cellphone the activity stack goes back to login, instead of main
How can i tell login activity to put two activities on stack in order to create this "fake" back history
Take a look at https://developer.android.com/reference/android/support/v4/app/TaskStackBuilder . It will help you create the back stack you are looking for.
I have a login activity. After login, the Main activity is started, which uses fragments for user navigation. I want a button in the nav drawer of my main activity which will completely close the app
Now, I have seen many many threads on this and have tried implementing their solutions. For example:
I have tried finishAffinity() in my Main activity, which should close the current activity as well as all parent activities
I have tried using finish() on the Login activity as soon as I bring up the Main Activity, and then calling finish() again when the user clicks the button
The highest voted answer for this question: Close application and remove from recent apps/, also does not seem work. First, android:autoRemoveFromRecents="true" requires API > 21, but even if I set the minimum SDK version to 21, the app still remains in the list
Finally, I have tried using an Intent when the user clicks the quit button and navigating back to the Login activity, and setting flags with an exit extra, and then finishing the Login activity (i.e. exit android application programmatically)
None of these are working. They will all close the Main Activity, and maybe even close the Login activity. But if the user clicks the app list/current apps/open apps key (the square soft key on most phones), the app is still visible there. When the app is clicked in that list it will take me back to the Login activity screen (I'm unsure if this is starting the app from fresh, or whether its just taking me to the previous Login screen which didn't close)
Out of desperation I have even tried System.exit(0), which I know is bad, but even that doesn't remove the app from the app list
So, how do I programmatically completely quit an app and remove all traces of it being open?
EDIT: I was too hasty in claiming one of the answers below didnt work (see italics above). The answer does remove the app correctly
I think this is the solution you're looking for.
You might consider having another activity named ExitActivity which will be called when you try to exit from your application. The trick here is, the ExitActivity will have android:autoRemoveFromRecents set to true in the manifest file, so that your instance will be cleared automatically from the recents.
Based on my research:
There is no way to force quite an application in android. You can only pause an activity. The discretion to quit an app lies totally with android framework which it does on checking the memory and resource utilization of apps. I could not find the official link for now, but I had read it earlier.
manage it by the OS. bring up the home screen.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I have an Android app with a stack of activities. One of the activities in the stack (let's call it LoginSettings) needs to sign into an OAuth service. I've given it a button that launches a web browser via an Intent. LoginSettings can't use the singleTask or singleInstance launch modes, because it needs to stay on top of the stack of its predecessor activities. That is, if the user presses back from LoginSettings, the prior activity in the stack needs to show up, and if the user relaunches my app later, it can't relaunch showing the previous activity in the stack. Breaking the stack in the middle like singleTask does is no use.
I've used the web browser and the trick with a custom callback URL and intent filter, but because I can't use singleTask, I can't get the result into the same instance of LoginSettings: it always creates a new activity, even if the launchMode is singleTop. The desired behaviour is that after the user logs in, the browser window goes away and the user sees LoginSettings, still with the rest of the stack behind it.
I want to use the browser rather than a WebView to authenticate: first, because it shows the user they're genuinely accessing the target website, rather than giving my app their password; second, because the user probably has saved their password in the browser anyway (or may already be logged in).
I eventually found a useful trick. When LoginSettings starts the browser, it makes sure to add the FLAG_ACTIVITY_NEW_TASK flag to the Intent that launches the browser. (This probably won't make any difference, as browsers are singleTask anyway, but it's best to be sure.) Instead of giving LoginSettings the intent filter for my custom URL, I created a new activity. This new activity appears as a dialog, and doesn't have allowTaskReparenting in the manifest. It shows a progress bar and message while an AsyncTask goes and trades in the verifier for the auth token. When the AsyncTask completes, it calls moveTaskToBack(true) and then finishes. This moves the task containing (only) the browser and the dialog to the back, revealing the previous task, which contains my stack of activities leading to LoginSettings.
In my app, both LoginSettings and this new dialog use an OOB mechanism to talk to the class that actually manages and stores the auth credentials, so LoginSettings.onResume checks with the backend whether the user is now logged in, and replaces the login button if so. As an alternative, you could use a broadcast to communicate the login event, but don't forget that LoginSettings would be in the stopped state when the broadcast happens.
In theory, this could go wrong if the browser adds the FLAG_ACTIVITY_NEW_TASK flag to the Intent it starts the custom callback URL with, but I've tested with Firefox and Chrome, and it works perfectly with them. Also, in theory, the task containing LoginSettings could be destroyed while it's in the background. This is a problem with solutions based on singleTask too: you need to be prepared for the callback URL to arrive via onCreate instead of onNewIntent if this happens. But with my solution, since the dialog completes the login and saves the credentials, when the user arrives back in LoginSettings, they'll be logged in even if the activity was recreated from scratch.
I'm working on C2DM notification for an Android Application and I'd like to open my application when user click on the notification. There is no problem for that, this is pretty easy.
The problem is that when the application is launching (after clicking on the notification), if some activity was previously opened, the launched activity seems to be added to the actual activity stack, what is a problem regarding to the complexity of my application (there is a lot of activity, some with static fields).
To solve the problem, 2 solutions would be OK:
1) Do not call a specific activity but just ask to my application to open (like when I click on the application icon on the home screen: Open the first activity if the application was closed or just bring the application to the front if was opened (but was in background)).
2) Clear all the activity stack and launch a specific activity.
But I didn't succeed to do one of both solution. Even using intent flag (like http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP).
Can somebody help me to solve this problem?
Thanks
PS: Sorry for my poor English, I'm from Belgium :-)
It's not what you asked to do but you can add the attribute android:launchMode="singleTask" to the activity you will be calling out of this notification and it won't create a new activity if one this instance already exists.
You could possibly also use the ActivityManager.killBackgroundProcesses(String packageName) to remove background processes but I have never tried this and it isn't advised or use the ChriZzZ suggestion and manage your activities a bit tighter.
Sounds like you are searching for FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
If set, this marks a point in the task's activity stack that should be cleared when the task is reset. That is, the next time the task is brought to the foreground with FLAG_ACTIVITY_RESET_TASK_IF_NEEDED (typically as a result of the user re-launching it from home)
When I launch a notification from the "second page" of my app and then close (hide) the app by going to my home screen, I can get directly back to the second page by clicking the notification. However, pressing back from this point should, I think, take me back to page one, but it instead closes the app as if it's on the first page. Am I missing a flag of some type?
Thanks
When you start activities they stack on top of each other giving you a history stack, when you start an activity directly there is no history.
Not sure if there is a super easy way to do this but people have rolled their own but it really seems like their should be a better way to do this ...