I have implemend the up button according to Google recommandations found here:
http://developer.android.com/training/implementing-navigation/ancestral.html
Like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// This is called when the Home (Up) button is pressed
// in the Action Bar.
case android.R.id.home:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The big problem with this code is that the MainActivity is started from a new instance. I would like to open the previous Instance of MainActivity without restarting it.
As this ACtivity is quite heavy, I do not want to create a new one every time the user press on the up button.
I tried to remove the flag FLAG_ACTIVITY_NEW_TASK and played a lot with all imaginable flags, but I did not succeed to create a button that would bring back the MainACtivity in previous state.
Any help would be highly appreciated.
What you're looking for is the flag:
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
Which will do what you want - if the activity already exists in the task and stack, then it will be brought to the front, otherwise it will be recreated.
Bear in mind that if the Activity has been destroyed by the GC, then it'll be recreated anyway, and some UI components may be reset depending on where you've got intialisation code (I don't think that onCreate() is called, but onResume() definitely will be
Related
I have following code in an activity SCORE:
#Override
public void onBackPressed() {
Intent i = new Intent(Score.this, MainActivity.class);
startActivity(i);
}
Basically when user hits back i want them to go back to main activity. In main i have button when hit it exits the app something like this:
case R.id.exitButton:
finish();
break;
So when i start app and hit exit button it works fine it exits the app. But when i am at score page and hit back and than hit exit button app does not exit it goes back to score page. Can anyone please tell what am i doing wrong?
You starting the MainActivity from Score. Score is not being finished so the Score activity is still active and on the navigation stack.
try to do the following:
#Override
public void onBackPressed() {
Intent i = new Intent(Score.this, MainActivity.class);
startActivity(i);
finish();//Finishing the score activity is needed
}
As stated in above comment it is not normal to have an exit button, but you are free to implement this if you want and or needed. For more information about the back stack have a look at the following android documentation.
http://developer.android.com/guide/components/tasks-and-back-stack.html
also there are various methods to to go back to an active activity have a look at Intent flags. Such as FLAG_ACTIVITY_CLEAR_TOP at the following documentation page:
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
i think the problem is you use the finsh() method to finish the activity.
may be you can use method like below:
case R.id.exitButton:
System.exit(0);
break;
hope that helps you.
For going to the main-activity after clicking back from score you want to add the following..
#Override
public void onBackPressed() {
finish();
}
And for exit from that app after clicking exit button add the following.
case R.id.exit:
System.exit(0);
break;
Hope this helps you..
The question is simple: Is there an intent FLAG that works exactly like pressing the back button? (making the activity slide from the left)
I need an intent to work exactly as moveTaskToBack(true) (if previous activity is in task stack).
I have tried calling Activity A (Main) with FLAG_ACTIVITY_CLEAR_TOP, but it doesn't get it "from the stack". I think it's creating a new instance, cause if I press back, I get the (on purpose unfinished) Activity B.
Note: I DON'T want to finish Activity B cause I need to go forward to it in some cases, without loosing the already loaded data.
You might want to call Activity B with FLAG_ACTIVITY_CLEAR_TOP if you want that to be on top of the stack and have A off of the stack.
If you never want Activity A to remain on the stack you can put in your manifest:
<activity
android:name=".ActivityA"
android:noHistory="true">
To go up to Activity A from your menu:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, ActivityA.class);
return(true);
}
return(super.onOptionsItemSelected(item));
}
If you are using you have to put:
android:launchMode="singleTask"
in manifest for your Activity B.
Hope this helps.
Having real issue understanding how to sort my issue out.
On the Home screen I have 2 buttons
When the user clicks the first button it starts a new Activity. What I am looking for is if the user clicks back the app returns to the home screen. If the user clicks the first button again it starts a new activity.
If the user clicks the second button it returns to the activity that was last started by clicking button 1
What I am having issue with is how to save the state of the activity when the user clicks back
Also how to call that activity when the second button is pressed
Thanks for your Time
UPDATE
I have gone down part of this but still having issues. If I put some of the code I am using perhaps someone can point where I gone wrong.
Code for calling the new activity from main menu
Intent intent = new Intent(MainMenu.this, NewClass.class);
intent.putExtra("value1", value1);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Within the new class I have added the following :
#Override
public void onBackPressed() {
//super.onBackPressed();
Intent intent = new Intent(RoundScoring.this, MainMenu.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
Toast.makeText(this, "Back Button Pressed", Toast.LENGTH_LONG).show();
}
I do not have either a onrestoreinstancestate or onresumne in this class. only a oncreate. Do I have to add something like this to bring back the instance
On the second button on the main menu I have added this
Intent intentContiune = new Intent(MainMenu.this, NewClass.class);
intentContiune.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intentContiune);
Thanks
Try this:
Home Screen Left Button:
Open the new activity with an intent flag, FLAG_ACTIVITY_NEW_TASK
Activity:
Override onBackClick() on the started activity to call the home screen with an Intent instead of finishing it. Use the flag FLAG_ACTIVITY_REORDER_TO_FRONT
Save activity state overriding OnSaveInstanceState
Home Screen Right Button:
Call the activity with the flag FLAG_ACTIVITY_SINGLE_TOP
More info about flags:
http://blog.akquinet.de/2010/04/15/android-activites-and-tasks-series-intent-flags/
One solution may involve passing bundles around that include the state of your activity. Using startActivityForResult(), you can return a bundle with the activity's state. When the user clicks your second button, pass in that bundle and have the activity set itself up with respect to the contents of the bundle. If the bundle doesn't contain the information you're looking for, then use the default values as if you were just starting it.
For more information:
Android: Capturing the return of an activity
When a user presses the back button on an intent, the application should quit. How can I ensure the application quits when the back button is pressed?
In my Home Activity I override the "onBackPressed" to:
#Override
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
so if the user is in the home activity and press back, he goes to the home screen.
I took the code from Going to home screen Programmatically
Immediately after you start a new activity, using startActivity, make sure you call finish() so that the current activity is not stacked behind the new one.
EDIT
With regards to your comment:
What you're suggesting is not particularly how the android app flow usually works, and how the users expect it to work. What you can do if you really want to, is to make sure that every startActivity leading up to that activity, is a startActivityForResult and has an onActivityResult listener that checks for an exit code, and bubbles that back. You can read more about that here. Basically, use setResult before finishing an activity, to set an exit code of your choice, and if your parent activity receives that exit code, you set it in that activity, and finish that one, etc...
A better user experience:
/**
* Back button listener.
* Will close the application if the back button pressed twice.
*/
#Override
public void onBackPressed()
{
if(backButtonCount >= 1)
{
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
else
{
Toast.makeText(this, "Press the back button once again to close the application.", Toast.LENGTH_SHORT).show();
backButtonCount++;
}
}
The app will only exit if there are no activities in the back stack. SO add this line in your manifest android:noHistory="true" to all the activities that you dont want to be back stacked.And then to close the app call the finish() in the OnBackPressed
<activity android:name=".activities.DemoActivity"
android:screenOrientation="portrait"
**android:noHistory="true"**
/>
Why wouldn't the user just hit the home button? Then they can exit your app from any of your activities, not just a specific one.
If you are worried about your application continuing to do something in the background. Make sure to stop it in the relevant onPause and onStop commands (which will get triggered when the user presses Home).
If your issue is that you want the next time the user clicks on your app for it to start back at the beginning, I recommend putting some kind of menu item or UI button on the screen that takes the user back to the starting activity of your app. Like the twitter bird in the official twitter app, etc.
Use onBackPressedmethod
#Override
public void onBackPressed() {
finish();
super.onBackPressed();
}
This will solve your issue.
First of all, Android does not recommend you to do that within the back button, but rather using the lifecycle methods provided. The back button should not destroy the Activity.
Activities are being added to the stack, accessible from the Overview (square button since they introduced the Material design in 5.0) when the back button is pressed on the last remaining Activity from the UI stack. If the user wants to close down your app, they should swipe it off (close it) from the Overview menu.
Your app is responsible to stop any background tasks and jobs you don't want to run, on onPause(), onStop() and onDestroy() lifecycle methods. Please read more about the lifecycles and their proper implementation here: http://developer.android.com/training/basics/activity-lifecycle/stopping.html
But to answer your question, you can do hacks to implement the exact behaviour you want, but as I said, it is not recommended:
#Override
public void onBackPressed() {
// make sure you have this outcommented
// super.onBackPressed();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
To exit from an Android app, just simply use.
in your Main Activity, or you can use Android manifest file to set
android:noHistory="true"
finish your current_activity using method finish() onBack method of your current_activity
and then add below lines in onDestroy of the current_activity for Removing Force close
#Override
public void onDestroy()
{
android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
}
I modified #Vlad_Spays answer so that the back button acts normally unless it's the last item in the stack, then it prompts the user before exiting the app.
#Override
public void onBackPressed(){
if (isTaskRoot()){
if (backButtonCount >= 1){
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}else{
Toast.makeText(this, "Press the back button once again to close the application.", Toast.LENGTH_SHORT).show();
backButtonCount++;
}
}else{
super.onBackPressed();
}
}
you can simply use this
startActivity(new Intent(this, Splash.class));
moveTaskToBack(true);
The startActivity(new Intent(this, Splash.class)); is the first class that will be lauched when the application starts
moveTaskToBack(true); will minimize your application
Add this code in the activity from where you want to exit from the app on pressing back button:
#Override
public void onBackPressed() {
super.onBackPressed();
exitFromApp();
}
private void exitFromApp() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
My app shows a signup activity the first time the user runs the app, looks like:
ActivitySplashScreen (welcome to game, sign up for an account?)
ActivitySplashScreenSignUp (great, fill in this info)
ActivityGameMain (main game screen)
so the activities launch each other in exactly that order, when the user clicks through a button on each screen.
When the user goes from activity #2 to #3, is it possible to wipe #1 and #2 off the history stack completely? I'd like it so that if the user is at #3, and hits the back button, they just go to the homescreen, instead of back to the splash screen.
I think I can accomplish this with tasks (ie. start a new task on #3) but wanted to see if there was simpler method,
Thanks
You can achieve this by setting the android:noHistory attribute to "true" in the relevant <activity> entries in your AndroidManifest.xml file. For example:
<activity
android:name=".AnyActivity"
android:noHistory="true" />
You can use forwarding to remove the previous activity from the activity stack while launching the next one. There's an example of this in the APIDemos, but basically all you're doing is calling finish() immediately after calling startActivity().
Yes, have a look at Intent.FLAG_ACTIVITY_NO_HISTORY.
This is likely not the ideal way to do it. If someone has a better way, I will be looking forward to implementing it. Here's how I accomplished this specific task with pre-version-11 sdk.
in each class you want to go away when it's clear time, you need to do this:
... interesting code stuff ...
Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
startActivityForResult(i, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == R.string.unwind_stack_result_id) {
this.setResult(R.string.unwind_stack_result_id);
this.finish();
}
}
then the one that needs to set off the chain of pops from the stack needs to just call this when you want to initiate it:
NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();
Then the activities aren't on the stack!
Remember folks, that you can start an activity, and then begin cleaning up behind it, execution does not follow a single (the ui) thread.
One way that works pre API 11 is to start ActivityGameMain first, then in the onCreate of that Activity start your ActivitySplashScreen activity. The ActivityGameMain won't appear as you call startActivity too soon for the splash.
Then you can clear the stack when starting ActivityGameMain by setting these flags on the Intent:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
You also must add this to ActivitySplashScreen:
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
So that pressing back on that activity doesn't go back to your ActivityGameMain.
I assume you don't want the splash screen to be gone back to either, to achieve this I suggest setting it to noHistory in your AndroidManifest.xml. Then put the goBackPressed code in your ActivitySplashScreenSignUp class instead.
However I have found a few ways to break this. Start another app from a notification while ActivitySplashScreenSignUp is shown and the back history is not reset.
The only real way around this is in API 11:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
I use this way.
Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);
I know I'm late on this (it's been two years since the question was asked) but I accomplished this by intercepting the back button press. Rather than checking for specific activities, I just look at the count and if it's less than 3 it simply sends the app to the back (pausing the app and returning the user to whatever was running before launch). I check for less than three because I only have one intro screen. Also, I check the count because my app allows the user to navigate back to the home screen through the menu, so this allows them to back up through other screens like normal if there are activities other than the intro screen on the stack.
//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
#Override
public void onBackPressed() {
//Check the activity stack and see if it's more than two deep (initial screen and home screen)
//If it's more than two deep, then let the app proccess the press
ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
int activityCount = tasks.get(0).numActivities;
if (activityCount < 3)
{
moveTaskToBack(true);
}
else
{
super.onBackPressed();
}
}
In the manifest you can add:
android:noHistory="true"
<activity
android:name=".ActivityName"
android:noHistory="true" />
You can also call
finish()
immediately after calling startActivity(..)
Just set noHistory="true" in Manifest file.
It makes activity being removed from the backstack.
It is crazy that no one has mentioned this elegant solution. This should be the accepted answer.
SplashActivity -> AuthActivity -> DashActivity
if (!sessionManager.isLoggedIn()) {
Intent intent = new Intent(context, AuthActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(intent);
finish();
} else {
Intent intent = new Intent(context, DashActivity.class);
context.startActivity(intent);
finish();
}
The key here is to use intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); for the intermediary Activity. Once that middle link is broken, the DashActivity will the first and last in the stack.
android:noHistory="true" is a bad solution, as it causes problems when relying on the Activity as a callback e.g onActivityResult. This is the recommended solution and should be accepted.
It's too late but hope it helps. Most of the answers are not pointing into the right direction. There are two simple flags for such thing.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
From Android docs:
public static final int FLAG_ACTIVITY_CLEAR_TASK
Added in API level 11
If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the
activity to be cleared before the activity is started. That is, the
activity becomes the new root of an otherwise empty task, and any old
activities are finished. This can only be used in conjunction with
FLAG_ACTIVITY_NEW_TASK.
Just call this.finish() before startActivity(intent) like this-
Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
this.finish();
startActivity(intent);
Removing a activity from a History is done By setting the flag before the activity You Don't want
A->B->C->D
Suppose A,B,C and D are 4 Activities if you want to clear B and C then
set flag
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
In the activity A and B
Here is the code bit
Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
super.finishAndRemoveTask();
}
else {
super.finish();
}
Here I have listed few ways to accomplish this task:
Go to the manifest.xml- and put android:noHistory="true", to remove the activity from the stack.
While switching from present activity to some other activity, in intent set flag as (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK). It is demonstrated in the example below.
Intent intent = new Intent(CurrentActivity.this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent);here
Note :Putting the intent flags can cause blank screen for sometime (while switching activity).
Try this:
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
it is API Level 1, check the link.