Android - Close all activities (FLAG_ACTIVITY_CLEAR_TOP/clearTaskOnLaunch didn't help) - java

I have "MainMenuActivity" in my application, from which I want to log out. After pressing the back button, this activity should start "Logout activity", which does some logout stuff and then finishes the application.
Method called onBackPressed() from MainMenuActivity:
public static void logoutAction(final AbstractActivity activity) {
Builder dialog = new AlertDialog.Builder(activity);
dialog.setPositiveButton(R.string.dialog_btn_yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent();
i.setClass(activity, iess.student.login.LogoutActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(i);
activity.finish();
}
});
dialog.show();
}
Then, "LogoutActivity" executes AsyncTask, which at the end of its work calls finish() on LogoutActivity.
My problem is, that if other activities were launched before MainMenuActivity, i.e. A -> B -> MainMenuActivity, then after pressing back button Logout activity does its work, finishes, but instead of closing the application, activity B comes to front. I tried to launch MainMenuActivity from activity B with FLAG_ACTIVITY_CLEAR_TOP and then call finish() on B, but in that case A came to front. I also tried to set:
<activity android:name="abc.def.LogoutActivity" android:clearTaskOnLaunch="true"></activity>
But the result was the same as before. Could you please help me what should I do?
OK, so I finally managed it. After creating an activity, I register it in static ArrayList<Activity>. After "LogoutActivity" does its work; it just calls finish() on each Activity registered in ArrayList. It works, but I guess it's not really nice. But I haven't figured out how to do this with FLAG_ACTIVITY_CLEAR_TOP.

As #sandrstar says in the comment:
from API 11 you can use FLAG_ACTIVITY_CLEAR_TASK
It works very well for me, as it removes all Activities, not just the ones on top.

Related

How to exit an app when Back Button is pressed

This is a small question but I'm finding very hard to solve this. I have multiple activities. For example A B and C. When app is launched A is opened and on click of button will redirect me to activity B and then from B on click of another button will take me to C. On Back pressed will now bring me back to B and again on Back button is pressed will take me to A which is main Activity.
Now if I press back button, instead the app should exit...it creates loop between B and A and never exit the app.
I already used the following method
Method 1:
use of this.finishonBackPressed which didn't help
Method 2:
use android:nohistory = true in manifest
But If I do so then from C activity it will directly take me to A which I don't want.
Method 2.
Use of
Intent intent = new Intent(Intent.ACTION_MAIN);
//to clear all old opened activities
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
when I use this then everytime this opens up in my device
Please anyone help.
This is my code in Mainactivity now
#Override
public void onBackPressed() {
finish();
super.onBackPressed();
}
But also it don't work and it creates loop between A and B Activity.
Your code (in MainActivity) is incorrect , put finish() after super.onBackPressed()
it must be :
#Override
public void onBackPressed() {
super.onBackPressed();
finishAffinity(); // or finish();
}

Have to press the back button twice to get to previous activity?

I am simply trying to click back and navigate to my previous activity. My flow is this: I go to news_feed activity -> Comments activity -> User Profile activity -> click back (Go to Comments activity) -> click back (This does nothing for some reason) -> Click back (Go back to news_feed activity). I'm not sure why I have to click back twice when I try to go from Comments activity back to news_feed activity. If I go from news_feed activity -> Comments -> press back (Go to news_feed activity) this works perfectly. Here is my code:
news_feed.java:
#Override
public void onBackPressed() {
super.onBackPressed();
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}
Comments.java:
#Override
public void onBackPressed() {
super.onBackPressed();
this.finish();
}
UserProfile.java:
#Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent(UserProfile.this, Comments.class);
Bundle bundle = new Bundle();
bundle.putString("postId", postId);
bundle.putString("posterUserId", posterUserId);
bundle.putString("posterName", posterName);
bundle.putString("postStatus", postStatus);
bundle.putString("postTimeStamp", postTimeStamp);
bundle.putString("postTitle", postTitle);
intent.putExtras(bundle);
startActivity(intent);
finish();
}
I don't think navigating to these activities would change anything, but I can include the intents that I used to navigate to these activities also if necessary. Otherwise I just included the onBackPressed code that I had for these activities. Any ideas why this might cause a problem? Any help would be appreciated. Thanks.
In your UserProfile class, in onBackPressed() method, you are starting the Comments class again. Why do you have to do this?
What is happening is, you are starting a new Comments activity onBackPressed() of the USerProfile class, so there are two instances of Comments Activity. So you feel you are pressing back btn twice.
If you have to pass data back to Comments from UserProfile class, then make use of setResult() method.
This will be of help
How to pass data from 2nd activity to 1st activity when pressed back? - android
Sending data back to the Main Activity in android
I you want to send back the result to previous activity the start activity by using
startActivityForResult()
insead of
startActivity()
and don't override
onBackPressed()
You can try something like this:
private boolean clicked;
#Override
public void onBackPressed() {
if (!clicked) { // if it was not clicked before, change the value of clicked to true and do nothing directly return, if clicked again, then it will be finish the activity.
clicked=true;
return;
}
super.onBackPressed();
}
And if you are going to use the time, then you can do like this:
private long lastClicked;
#Override
public void onBackPressed() {
if (System.currentTimeMillis() - lastClicked < 1000) { // within one second
super.onBackPressed();
}
lastClicked = System.currentTimeMillis();
}
You don't need to override onBackPressed() if all you're going to do is call startActivity() and finish() in the current activity. The Android backstack will handle both of those for you. Moreover, in your UserProfile.java you are passing data to previous activity. For this, you should use startActvityForResult() in the Comments activity (i.e the previous activity) instead of startActivity().
To learn more about startActvityForResult() visit: https://developer.android.com/training/basics/intents/result.html
public void onBackPressed() {
if (this.lastBackPressTime < System.currentTimeMillis() - 2000) {
this.lastBackPressTime = System.currentTimeMillis();
} else {
//super.onBackPressed(); for exit
//INTENT HERE TO YOUR SECOND ACTIVITY like below
Intent intent=new Intent(A.this,B.class);
startActivirty(intent);
}
}
Create a global variable
private long lastBackPressTime = 0;
Hope this will help you,Let me know..

On physical back button pressed how to go to device's home screen? [duplicate]

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);
}

Waiting for a response from AlertDialog or Theme.Dialog Activity with onBackPressed()

I have looked at quite a few posts on here and haven't been able to get anything to work. I am trying to have either an AlertDialog or an Activity class (set to a Theme.Dialog style) prompt users to see if they want to exit a side Activity and go back to the Home activity. Everything I have tried just doesn't seem to work.
[NOTE: All of the following examples were tried as the first lines in...]
#Override public void onBackPressed(){}
I have tried -
Intent setIntent = new Intent(Intent.ACTION_MAIN);
setIntent.addCategory(Intent.CATEGORY_HOME);
setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(setIntent);
which closes both the current Activity and the Home menu Activity (the next Activity in the stack), while -
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Session.closing = true;
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Session.closing = false;
}
});
AlertDialog alert = builder.create();
alert.show();
closes the current Activity and creates a pop-up over the Home activity. This is the outcome of most of the other things I have tried, like...
super.onBackPressed();
startActivity(new Intent(this, CloseActivityView.class));
Are there any tricks to getting onBackPressed from dumping your current child Activity?
First of all, don't call super.onBackPressed(); - this will call finish() and your current activity will be removed.
Secondly, this:
Intent setIntent = new Intent(Intent.ACTION_MAIN);
setIntent.addCategory(Intent.CATEGORY_HOME);
creates an intent that launches the Home screen. (See the Intent docs)
What you could do is put something like this in your onBackPressed override:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
startActivity(new Intent(this, HomeActivity.class));
finish();
}
})
.setNegativeButton("No", null); // I think passing null here is OK.
AlertDialog alert = builder.create();
alert.show();
Then specify your HomeActivity as launchMode="singleTask" in your manifest, as detailed in the Tasks and Back Stack docs. You could do the same thing by specifying the FLAG_ACTIVITY_NEW_TASK flag on the Intent for navigating to your HomeActivity.
If you want to show a confirmation dialog on back button press then override the onBackPressed and show the AlertDialog. If user confirms then call dialog.dismiss() to dismiss the dialog and then if you want to exit the app and go to the home screen then finish this activity and start the homescreen intent and the code you have tried for this is right. or if you want to go back to an activity within your app then you can start that activity with FLAG_ACTIVITY_CLEAR_TOP. Don't call super.onBackPressed() in your overriden version unless you want to finish the current Activity.
Okay. Three things to say:
if your home activity contents are not changed after navigating away from it, and doing some operations, then, i recommend that when you are navigating awway from homw screen, don't call finish(). Let the home screen be in the activity stack. So when the child activity has to navigate back to home activity, it just needs to finish its own activity, and Home screen will appear after that.
Your code is somewhat perfect. All you have to do is finish the activity when yes button is pressed on AlertDialog
And on Homescreen, inside onBackPressed() or whatever you prefer, just show the AlertDialog (that you have shown above), and you can code for Yes and No buttons

Android - After closing an activity, when I run the app again, two activities run at the same time. How can I avoid it?

So I've got an activity in my android app, that runs on start.
This activity is just a page with a start button.
When I press the start button, it calls another activity and closes itself:
Intent i = new Intent(this, Dictating.class);
startActivity(i);
finish();
The other Activity is using Text-to-speech to dictate some words.
Now I've got something weird happening:
1) I listen to the dictating.
2) I press back button: dictating stops (what I want)
3) I run again the app, press the start button. Now I have my new activity running and dictating, but in the back I can hear the older Activity that resumed where it was, and continues dictating.
I would like for the new activity to start all over again, and not keep the other activity.
How can I do that ?
PS: This is an activity problem, and not a text-to-speech problem as I'm flushing the text-to-speech each time, It could not be kept in the memory
Thank you
EDIT:
Here is the onCreate of my Dictating class, there is tons of code in this class, I obviously don't want to post all my code, so here is some parts:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.streaming);
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
this.txtCurrentWord = (TextView) findViewById(R.id.txtCurrentWord);
this.btnPlayPause = findViewById(R.id.btnPlayPause);
this.btnPlayPause.setOnClickListener(this);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
this.tts = new TextToSpeech(this, this);
} else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}
there are a few weird things I'm doing like:
Runnable task = new Runnable() {
public void run() {
//runs on ui
runOnUiThread(new Runnable() {
public void run() {
readNextWord();
}
});
}
};
worker.schedule(task, 1, TimeUnit.SECONDS);
this delays the next word by one second, and then executes a fonction in the main ui thread. not sure if this matter
And some flushing at the end:
#Override
public void onDestroy() {
tts.shutdown();
super.onDestroy();
}
You need to add launchMode property to your activity inside AndroidManifest file, for more detail see "Using the manifest file"
This question is over a year old, but I can't believe no one ever gave you the right answer. Also, I don't think you should have accepted an answer that clearly didn't solve anything for you. By accepting such answers, you're just cluttering the StackOverflow google search results with junk for other people with the same problem.
The flushing you do at the end is completely wrong. According to the Activity lifecycle, onDestroy() is never guaranteed to be called. If you want to make sure the flushing gets done properly, do it inside of onPause().
For now the solution I'm giving you does fix the main problem you've described. However, if you do get the time to do a more complete rewrite, you'll want use a service that you bind to your activity. That will give you the finer control you require.

Categories

Resources