Finishing Activity from another activity [duplicate] - java

This question already has answers here:
close an activity from other activity?
(5 answers)
Closed 9 years ago.
Say I have 3 activities A, B and C. A leads to B which leads to C. I would like to be able to move back and forth between A and B but I want to finish both A and B once C gets started. I understand how to close B when starting C via the intent but how do I also close A when C gets started?

Use this flag when you are opening the C acitivity.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
This will clear all the activities on top of C.

Since A is your root (starting) activity, consider using A as a dispatcher. When you want to launch C and finish all other activities before (under) it, do this:
// Launch ActivityA (our dispatcher)
Intent intent = new Intent(this, ActivityA.class);
// Setting CLEAR_TOP ensures that all other activities on top of ActivityA will be finished
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Add an extra telling ActivityA that it should launch ActivityC
intent.putExtra("startActivityC", true);
startActivity(intent);
in ActivityA.onCreate() do this:
super.onCreate();
Intent intent = getIntent();
if (intent.hasExtra("startActivityC")) {
// Need to start ActivityC from here
startActivity(new Intent(this, ActivityC.class));
// Finish this activity so C is the only one in the task
finish();
// Return so no further code gets executed in onCreate()
return;
}
The idea here is that you launch ActivityA (your dispatcher) using FLAG_ACTIVITY_CLEAR_TOP so that it is the only activity in the task and you tell it what activity you want it to launch. It will then launch that activity and finish itself. This will leave you with only ActivityC in the stack.

Related

Bring activity front if it is running or create new one with backpress

Let me explain detailed; I have notification and this notification opens B activity with two cases.
Cases :
If app is closed. (not running on background)
If app is opened. (on background or front)
Case-1
I click to the notification and it opens the B activity with case-1. When i press back i want to go to the A activity and kill B activity. I dont need B activity anymore. Everything easy from here without using flags. When I'm on B activity and press back two times from here, it goes A activity and then closes the app. My trouble here is, if i open the app from navigation buttons of phone (can't remember the name of this button) app is opening from B activity. That's not what i expected. I want to open A activity. Don't want to see B activity anymore.
Case-2
I click to the notification and it opens the B activity with case-2.When i press back i want to bring A activity to the front, without creating anything new. If i press back on B activity, two times and close the app and then again re-open app from navigation button of phone, want to open app from A activity.
So how can i make this correctly, i tried to use flags (i already read docs) but couldn't get work.
What flags should i use when i open the B activity and onBackPress method of B activity to go A activity as i wanted
This should be achievable by adding
android:launchMode="singleTask"
to the A activity in the Manifest, then you can just open A activity from B activity onBackPressed and you will have A only once in the stack.
If it's not working the way you want, you can create an abstract class that extends Activity and handle the stack in a static object, then A & B must extend this new class
try this
Intent intent = new Intent(context, YourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
try this
android:launchMode="singleTask" in android manifest file
You can achive this by adding FLAG_ACTIVITY_REORDER_TO_FRONT
Intent i = new Intent(context, Activity.class);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);
You May try this isTaskRoot() Which will return B is root
if it is true then launch A
other wise you may finish B
B Activity
#Override
public void onBackPressed() {
if (isTaskRoot()) {
//call A which is not exist
Intent i =new Intent(B.this,A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}else {
//Finish B if A Already Exixt
finish();
}
}
You can call B Activity on Notification Click
if A is present then u can finish B else you can launch A
If set FLAG_ACTIVITY_CLEAR_TOP, the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
Just put this in ActivityB onBackPressed:
Intent i = new Intent(ActivityB.this , ActivityA.calss);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
finish();
How solve case 1:
finish(); on ActivityB BackPressed method make ActivityB finish after open ActivityA. So after opens ActivtyA, ActivityB will shut down.
How solve case 2:
With this combination flag, It will do what you want. It will close all activities in stack and just keep destination activity. If instance of activity exist it will use it and calls OnNewInstance and if not it will creates new one.
If this is the only instance of Activity B being used, you can add the flag noHistory to the manifest for Activity B
android:noHistory="true"
This will stop Activity B being added to the back stack, this is also possible dynamically by using the Intent Flag FLAG_ACTIVITY_NO_HISTORY when calling Activity B.
As for having Activity A start when Activity B is killed #Quentin Menini's answer of having a single task activity set in the manifest will work if that is the only way you wish Activity A to be accessed, or the Intent Flag Intent.FLAG_ACTIVITY_REORDER_TO_FRONT as #Naimish Vinchhi has suggested, will have the desired effect in this instance.
https://developer.android.com/reference/android/content/Intent.html
link to see all possible Intent flags
https://developer.android.com/guide/topics/manifest/activity-element.html
link for all possible manifest activity options

Create new Instance Of activity by Intent every time android?

How to prevent to create every time Instance of Store activity?
When I call startActivity(new Intent(this,StoreActivity.class)), it will create new instance and call OnCreate Method in StoreActivity. I want to call one time Oncreate.
Is this Possible ?
Do this
startActivity(new Intent(
this,StoreActivity.class).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP));
From Android Documentation
public static final int FLAG_ACTIVITY_SINGLE_TOP
If set, the activity will not be launched if it is already running at the top of the history stack.
Constant Value: 536870912 (0x20000000)
Start your activity like this:
Intent storeIntent = new Intent(this, StoreActivity.class);
storeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(storeIntent);
It will call onCreate() only once on first launch of activity, if activity is already running it calls only onNewIntent() instead of create new instance of activity or calling onCreate.
This is not possible since each time you press back button, onBackPressed() method is called which actually destroys your StoreActivity.
If you want this method to not destroy your activity, just remove or comment out super.onBackPressed() line in this method.
In this case your activity will not be destroyed when back button is pressed, but then you will have to use any other logic to bring your MainActivity to top of the stack.
try to finish the first activity after starting the new one,
add this code after the Intent command.
finish();
like that:
startActivity(new Intent(this, newActivity.class));
finish();
check this link
Finish an activity from another activity

Force quit of Android App using System.exit(0) doesn't work

when I try to quit my Android application by overwriting the function for the back-button of Android devices and "System.exit(0)", this doesn't work.
I have an activity named "LoginActivity" and an activity named "OverviewActivity".
When I start an intent in OverviewActivity to switch to LoginActivity, this works.
Intent changeViewIntent = new Intent(OverviewActivity.this,
LoginActivity.class);
startActivity(changeViewIntent);
Now I am in LoginActivity and there is the overwritten method:
#Override
public void onBackPressed() {
System.exit(0);
}
But when I press the back-key (e.g. in the device simulator) the screen is blank for a millisecond and then it goes back to the OverviewActivity.
Why is this happening? I just want to force the close when the back-key is pressed.
History disabling for the OverviewActivity in the manifest is no option, because there are several ways to access the OverviewActivity from other activities.
Maybe there is an idea? Android 4 is minimium requirement, so it doesn't have to work on lower versions..
Thanks!
The Exit is possible by deleting the whole activity-call-history and starting the Home-Activity of the Home-Scrren.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
What you can do is
In your OverviewActivity:
Intent changeViewIntent = new Intent(OverviewActivity.this,
LoginActivity.class);
startActivity(changeViewIntent);
OverviewActivity.this.finish();
after starting the intent you terminate the overview activity
and in LoginActivity
#Override
public void onBackPressed() {
LoginActivity.this.finish();
}
This way your app will exit.
The difference between finish() and System.exit(0)
The VM stops further execution and program will be exit.
Now, in your case the first activity comes back due to activity stack.
So when you move from one activity to another using Intent, do the finish() of current activity like this.
If you want to force quit you can use
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
getParent().finish();
But you should not use System.exit especially if your activity uses other recourses in the background e.g. Internet, Video, etc.

How could I start the startActivity() before startActivityForResult()

When I execute the code the startActivity() is called only after the startActivityForResult() is over. How can I start the startActivity() first? I tried with threads but I didn't succeeded.
// Splash Correct
Intent correct = new Intent("com.quizcontest.alex.SPLASHCORRECT");
startActivity(correct);
Bundle b = new Bundle();
Intent i = new Intent(StartPlaying.this, CorrectAnswer.class);
b.putInt("p1Key", player1Score);
b.putInt("p2Key", player2Score);
b.putInt("rKey", round);
i.putExtras(b);
startActivityForResult(i, 0);
startActivity does not block. It causes something to happen in a new thread, so it will immediately execute the lines that happen after it.
It seems like you are trying to show a splash screen. See this other question related to spash screens: Android SplashScreen or this example for displaying a splash screen using a dialog: http://blog.iangclifton.com/2011/01/01/android-splash-screens-done-right/
If the behavior you want is to start activity 1, and then start activity 2, the correct behavior is to start activity 1 for result. Then onActivityResult will be called when activity 1 has completed. At this point you can start activity 2.

Finish all previous activities

My application has the following flow screens :
Home->screen 1->screen 2->screen 3->screen 4->screen 5
Now I have a common log out button in each screens
(Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)
I want that when user clicks on the log out button(from any screen), all the screens will be finished and a new screen Log in will open .
I have tried nearly all FLAG_ACTIVITY to achieve this.
I also go through some answers in stackoverflow, but not being able to solve the problem.
My application is on Android 1.6 so not being able to use FLAG_ACTIVITY_CLEAR_TASK
Is there any way to solve the issue ?
Use:
Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
This will clear all the activities on top of home.
Assuming you are finishing the login screen when the user logs in and home is created and afterward all the screens from 1 to 5 on top of that one. The code I posted will return you to home screen finishing all the other activities. You can add an extra in the intent and read that in the home screen activity and finish it also (maybe launch login screen again from there or something).
I am not sure but you can also try going to login with this flag. I don't know how the activities will be ordered in that case. So don't know if it will clear the ones below the screen you are on including the one you are currently on but it's definitely the way to go.
You may try Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. It will totally clears all previous activity(s) and start new activity.
Before launching your new Activity, simply add the following code:
finishAffinity();
Or if you want it to work in previous versions of Android:
ActivityCompat.finishAffinity(this);
When the user wishes to exit all open activities, they should press a button which loads the first Activity that runs when your application starts, clear all the other activities, then have the last remaining activity finish. Have the following code run when the user presses the exit button. In my case, LoginActivity is the first activity in my program to run.
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
The above code clears all the activities except for LoginActivity. Then put the following code inside the LoginActivity's onCreate(...), to listen for when LoginActivity is recreated and the 'EXIT' signal was passed:
if (getIntent().getBooleanExtra("EXIT", false)) {
finish();
}
Why is making an exit button in Android so hard?
Android tries hard to discourage you from having an "exit" button in your application, because they want the user to never care about whether or not the programs they use are running in the background or not.
The Android OS developers want your program to be able to survive an unexpected shutdown and power off of the phone, and when the user restarts the program, they pick up right where they left off. So the user can receive a phone call while they use your application, and open maps which requires your application to be freed for more resources.
When the user resumes your application, they pick up right where they left off with no interruption. This exit button is usurping power from the activity manager, potentially causing problems with the automatically managed android program life cycle.
I guess I am late but there is simple and short answer.
There is a finishAffinity() method in Activity that will finish the current activity and all parent activities, but it works only in Android 4.1 or higher.
For API 16+, use
finishAffinity();
For below 16, use
ActivityCompat.finishAffinity(YourActivity.this);
Hope it helps!
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
This Will work for all Android versions. Where IntentCompat the class added in Android Support library.
Use the following for activity
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
remove CLEAR_TASK flag for fragment use.
I hope this may use for some people.
On a side note, good to know
This answer works (https://stackoverflow.com/a/13468685/7034327)
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();
whereas this doesn't work
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
.setFlags() replaces any previous flags and doesn't append any new flags while .addFlags() does.
So this will also work
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
From developer.android.com:
public void finishAffinity ()
Added in API level 16
Finish this activity as well as all activities immediately below it in the current task that have the same affinity. This is typically used when an application can be launched on to another task (such as from an ACTION_VIEW of a content type it understands) and the user has used the up navigation to switch out of the current task and in to its own task. In this case, if the user has navigated down into any other activities of the second application, all of those should be removed from the original task as part of the task switch.
Note that this finish does not allow you to deliver results to the previous activity, and an exception will be thrown if you are trying to do so.
If your application has minimum sdk version 16 then you can use finishAffinity()
Finish this activity as well as all activities immediately below it in the current task that have the same affinity.
This is work for me In Top Payment screen remove all back-stack activits,
#Override
public void onBackPressed() {
finishAffinity();
startActivity(new Intent(PaymentDoneActivity.this,Home.class));
}
http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29
In my case I use finishAffinity() function in last activity like:
finishAffinity()
startHomeActivity()
Hope it'll be useful.
A solution I implemented for this (I think I found it on Stack Overflow somewhere, but I don't remember, so thanks to whoever did that in the first place):
From any of your activities do this:
// Clear your session, remove preferences, etc.
Intent intent = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Then in your LoginActivity, overwrite onKeyDown:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
For logout button on last screen of app, use this code on logout button listener to finish all open previous activities, and your problem is solved.
{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();
i have same problem
you can use IntentCompat , like this :
import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
this code work for me .
Android api 17
instead of using finish() just use finishAffinity();
Log in->Home->screen 1->screen 2->screen 3->screen 4->screen 5
on screen 4 (or any other) -> StartActivity(Log in) with FLAG_ACTIVITY_CLEAR_TOP
for API >= 15 to API 23
simple solution.
Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(nextScreen);
ActivityCompat.finishAffinity(currentActivity.this);
If you are using startActivityForResult() in your previous activities, just override OnActivityResult() and call the finish(); method inside it in all activities.. This will do the job...
When user click on the logout button then write the following code:
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And also when after login if you call new activity do not use finish();
I guess I am late but there is simple and short answer. There is a finishAffinity() method in Activity that will finish the current activity and all parent activities, but it works only in Android 4.1 or higher.
For API 16+, use
finishAffinity();
For below 16, use
ActivityCompat.finishAffinity(YourActivity.this);
Hope it helps!
shareedit
answered May 27 '18 at 8:03
Akshay Taru
Simply, when you go from the login screen, not when finishing the login screen.
And then in all forward activities, use this for logout:
final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
It works perfectly.
If you log in the user in screen 1 and from there you go to the other screens, use
Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
I found this way, it'll clear all history and exit
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
System.exit(0);
I found this solution to work on every device despite API level (even for < 11)
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);
Best way to close all the previous activities and clear the memory
finishAffinity()
System.exit(0);
I have tried the flags on my end and still haven't worked. I have an application with a very similar design and I have a possible solution in terms of logic. I have built my Login and Logout using shared preferences.
If I logout, data in my shared preferences is destroyed/deleted.
From any of my activities such as Home.java I check whether shared preferences has data and in this case it won't because I destroyed it when I logged out from one of the screens. Therefore logic destroys/finishes that activity and takes me back to the Login activity. You can replicate this logic in all your other activities.
However remember to perform this check inside onPostResume() because this is what is called when you go back to Home.java
Code Sample Below:
#Override
protected void onPostResume() {
SharedPreferences pref = this.getSharedPreferences("user_details", Context.MODE_PRIVATE);
if (pref.getAll().isEmpty()){
//Shared Preferences has no data.
//The data has been deleted
Intent intent = new Intent(getApplicationContext(), Login.class);
startActivity(intent);
finish();
//Finish destroys that activity which in our case is the Home.java
}
super.onPostResume();
}
In Kotlin this way:
in Another Activity (with some classes), under Imports
var activity:Activity?=null
get() = field
set(value) {
field = value
}
Then, under onCreate
activity=this
in MainActivity now:
activity?.finish()

Categories

Resources