I have an Application.Suppose there are three Activities A,B,C.
A->B(Sub-Activity)->C(Sub-Activity).
I have set up these kind code to switch to next activity.
setContentView(R.layout.B);
And Problem is When i click back button on emulator or phone while i am on Activity B or C,closes the application window come back to home.
I want that if i will press back button on Activity C it will firstly move to Activity B and then to A,Afterwards if i'll click again to back button then it comes to home-screen or closes application window.
Any methods or something wrong in my code or have to edit ?
You can override the default back press and tell it you reset your content view but you will have to keep track of the stack yourself.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//code to reset view
return true;
}
return super.onKeyDown(keyCode, event);
}
This said I really recommend you look at allow android to handle the stack in the default manner. Your method will end up causing you headaches in the future.
You need to actually start a new activity and then set the layout in there for the back button to work. Have a look at Tasks and Back Stack
Just setting the view to a new layout is not the same as starting a new activity. From your code, it appears you're just changing the layout and not starting a new activity.
As the method setContentView says, you are just changing the content view for the Activity A. Check The Activity lifecycle and the method startActivity to start new Activity, and read and the Tasks and Back Stack for more information.
As you're using setContentView , you're not switching between activities.
You actually are just changing the content of one and only one activity. Which explains the reason why when you press the back button it closes the application window.
activity A / content A -> activity A / content B -> activity A / content C
if you want to go from an activity to another: you should use Intent and startActivity.
for example you implement a button within the onClick function of the button you implement this:
Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);
and in a different Java file named ActivityTwo.java you implement a class ActivityTwo which extends Activity, within the onCreate method you set a different view, which might be equivalent to content B
you're application scheme will be like this:
activity A / content A -> activity B / content B -> activity C / content C
When you'll be on activity C and you'll press the back button you'll go to activity B.
Related
I've been struggling with a particular challenge which is as follows:
My app has an activity "A" which is considered the app's "main" activity. At a certain point, it launches an activity "B" which has an action available that should launch a fragment inside activity "A" (this won't always be the same fragment, it will depend on some data coming from our backend).
I can do this just fine by simply calling startActivity with the correct Intent, however, on pressing the back button, it goes back to A's "main fragment" (this is logic implemented inside of A's onBackButtonPressed()). Essentially, what should happen is as follows:
Activity A -> Activity B -> Activity A showing Fragment X -> press back -> Activity B
What happens when using startActivity to launch Activity A:
Activity A -> Activity B -> Activity A showing Fragment X -> press back -> Activity A showing the "main fragment". From here, if I press back again the app exits, which again is part of the implementation of A's onBackButtonPressed, however I've tried retrieving an extra from the intent which invoked A in order to conditionally bring back activity B but the Intent seemed to be empty of extras for reasons I can't figure out. I am sure I am correctly putting the extras in the Intent since activity A launches the correct fragment when invoked from B based on what I put there.
More things I've tried:
Launching the desired fragment directly from within B, however this way the fragment is not shown with the navigation bar that exists in A and seems to show the main contents of activity B behind the fragment's elements, which in user experience terms is undesirable.
Using the Intent.FLAG_ACTIVITY_REORDER_TO_FRONT flag, which seemed to make no difference whatsoever.
As this is part of my company's app which already has a decent degree of complexity, I'm not at liberty to provide you with useful code samples, and hopefully my description is sufficient for someone to aid me.
Additional information
targetApi="n"
Testing on Android 11
Activity A has launchMode "singleTask"
Activity B has launchMode "singleTop"
For the intended behavior:
Avoid using any launchMode, taskAffinity or activity flags, the default behavior is absolutely good for your requirements ("standard" is the default launch mode). So when you do the action in Activity B, a new instance of Activity A will be launched after putting B in backstack, which is the default behavior.
You should have a logic in Activity A's onBackPressed() such that: if the fragment X is visible, then it will exit the whole activity, otherwise it passes by calling super(). Something like the following:
In Activity A
#Override
public void onBackPressed() {
Fragment fragment = getFragmentManager().findFragmentByTag("yourTagForFragmentX");
if (fragment instanceof XFragment) {
// The fragment is available in the fragment manager
finish()
} else {
super.onBackPressed();
}
}
For more details, here
I think you're overcomplicating things.
Remove all of the launch mode flags for A and B - they should not be necessary.
Remove custom handling of onBackPressed - default handling should suffice.
Update A to initialize itself to the correct fragment based on the intent it's given:
For example:
onCreate(...) {
if (getIntent().getAction() == "START_ON_X") {
// Notice we REPLACE and DO NOT add to back stack
getFragmentManager().replace(fragID, createXFragment()).commit()
}
else {
getFragmentManager().replace(fragID, createDefaultFragment()).commit()
}
}
Thus, you will have:
Default launcher intent launches A.
A launches B.
B launches A with specific intent to show Fragment X
This will give you a stack of A -> B -> Ax
Then when you press back, DEFAULT BEHAVIOR will leave you on B.
Then pressing back again will leave you on A.
Then pressing back again will close your app.
Again this is all standard, default behavior. KISS.
I have an Activity A which I launch with some extras(i.e. put some data to the Intent that starts the Activity). From this Activity I launch another Activity B. The problem is that when I get back from B to A, by calling finish(), A Activity's getIntent() method returns an Intent that contains no extras.
So, my questions is: Is this normal behavior? And is there some way that I can signal Activity A that I want it to keep the Intent it was started with.
Oh, and please note that I've overridden the onSaveInstanceState() in Activity A.
EDIT:
I'm no longer experiencing this behavior on my device. And I haven't changed anything in the code. I'm using a 3 year old device for testing. I wonder if this might have been caused by a glitch on the device?
I got it figured out. This issue only happens when I click on ActionBar's back arrow and not when I press the device's Back button. Because when Back button is pressed B Activity's finish() method is called and the app normally returns to the already created instance of Activity A, when ActionBar's back arrow is clicked by default the Activity B doesn't call the finish() method, instead it creates a new instance of the Activity A due to the Android lateral navigation functionality. So the solution was to Override the ActionBar's back arrow click functionality like this(method added to Activity B):
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
int itemId = menuItem.getItemId();
if (itemId == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(menuItem);
}
Is this normal behavior?
yes it is. Start B with startActivityForResult , and in A, override onActivityResult. Before finishing B call setResult(int, intent), filling up the intent with the data you want to return to A. onActivityResult get the same intent, as third parameter.
Yes The Behavior is Normal. If You want to start an Activity X from an Activity Y and get some data from X and return to Y then you have to use startActivityForResult(intent,request_code)
Then you need to override theonActivityResult()` method
In the Activity X after creating the intent and putting the data in the intent you need to do the following
setResult(RESUKT_OK,i);
`
I have three activities: A, B, C
From both Activities A,B I can call
startActivity(new Intent(this, C.class));
So the logic would be something like A->B->C or A->C .. now when I am in C, I would like to get back to B or A depending on from which activity was C started.
Now the question is, when I am in Activity C, how to get "Back" to the parent activity, from which I opened this activity C?
I have been trying something with NavUtils and Intent.FLAGS, but I was not successful.
BTW: I can not use finish() or onBackPressed(). I am using custom dynamic created theme in my app and when I use onBackPressed() it will show a default application theme (default white screen with icon) before the desired activity is loaded.
Thanks for any help.
in your manifest add this to activity C so this part solves the back button.
<activity
android:name="your.package.name.C"
android:launchMode="singleInstance" >
</activity>
lets solve up button:
you must use putExtra that indicates the parent of C activity. for example when you want to call it from activity B do this:
Intent i = new Intent(B.this,C.class);
i.putExtra(MY_PARENT,"B");
startActivity(i);
and in activity C store MY_PARENT value in a string called parent. then when the user press UP button read that and go to the parent.
that means in activity C :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
Intent i = new Intent(C.this,Class.forName(parent));
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
You may create and process too many objects in onCreate method of your Activity, so that causes the delay that you see before the desired activity get loaded...
You can do all those creation and processing in an AsyncTask and keep your onCreate method clean, then you won't see that delay anymore.
I am developing an application which starts from LoginPage. When user Login then he moves to Main Screen where grid view for different departments are present.
Every page of application except login page has a Footer which have different Icons like Home, logout, etc.
I want to add conditional back functionality using mobile back button. Some conditions are as follow:
1) LoginPage ---> Main Screen ---> On back user should log out and go to Login Page
2) Main Screen --> any department ---> Any Sub deprtment --> If user press Back button then go to back in same order
3) User is any where in application ---> If press home button from Footer ---> Comes to Main Screen --> No back functioality to go on previous page, It should follow condition 1.
4) If User on Login Page then he will exit from application on pressing Back Button
5) If User on main Screen then user should logout and go to Login Page on preseeing Back Button
I have tried with "noHistory=true" in Manifest and with Intent flags in Activity file.
Can any body suggest me best way to solved out it.
shouldn't be a problem, all you have to do is override the onBack function and add the logout process.
not a problem, the normal behavior of back buttons is exactly that.
DO NOT DO THIS!!! BAD BEHAVIOR.
normal behavior of back button.
that was step one.
this is used for exit from application on back press.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
System.exit(0);
}
return super.onKeyDown(keyCode, event);
}
if u want only back then remove System.exit(0) from above code .
By using this you can manage your all condition which one you want.
Use a stack globally to save screens order. Stack must be available in application level. And get the screen order when you click on back button. Write switch case for screen order and start that activity. that's it.
for example.
crate a class class MyStack{
//here declare a static stack
//create setter,getter method for assinging values to stack
}
when starting new activity assing screen value in stack with setter method
if you are starting a activity from main screen assign 1 into stack, you are starting sub screen assign 2 into stack.
when click on back get that value
switch(value){
case 1: //start mainscreen break;
case 2: //start sub screen break;
}
With what I understand, you cannot override the functionality of home button. By default, it minimizes your app with its current state, by calling onPause(). When you open the app again, onResume() is called and starts the app from where it was paused. As far as your back button functionality is concerned, most of the above answers are fine.
Try,
#Override
public void onBackPressed()
{
finish(); //finishes the current activity and doesnt save in stock
Intent i = new Intent(CurrentActivity.this, Login.class);
i.addflags(Intent.flag_activity_no_history);
startActivity(i);
}
Try this to trap events on the back button
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK) {
Intent Act2Intent = new Intent(thisActivity, Activity2.class);
startActivity(Act2Intent);
finish();
return true;
}
return false;
}
on each activity implement
OnBackPress().
Override it and add the functionality you want like logging out, clearing history stack and start new(previous) activity.
I think simplest approach may be to override back button in your "Main Screen" activity so that when back button is pressed you can do :
1. Executing log out logic:
2. Explicitly call your Login Page
This may give the behavior you are looking for.
On how to override back button, you can refer to this link:
http://android-developers.blogspot.com/2009/12/back-and-other-hard-keys-three-stories.html
Hope this helps!
I have an activity A that launches B with an Intent. (B is a MapActivity and has some async code)
in B i have the following code
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
// Log.d(this.getClass().getName(), "back button pressed");
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
This simply not work. I mean that when I press the back button on the phone, the current activity B disappears and the activity A that launched B is shown.
If I press again on A the button that launch B, I see B is exactly how it was when I closed it. SAME text in textboxes, same Map position... So i think the activity B is not really closed.
How can I close it for real so when I launch again it, activity B is cleas as new born?
EDIT: just to make the question clearer:
I want it to work like this: when the user is on activity B and BACK button is pressed, B has to be closed and destroyed. When the user again launches B from A, B has to be launched as a NEW activity, with blank field, reset map, etc., etc., ... just like the first time the user launches B from A.
Instead of returning true, try returning super.onKeyDown(keyCode, event) after finish().
You can try 1 more thing: specify android:noHistory="true" in the manifest for that activity.
Specifying this attribute doesn't keep the activity on the Activity Stack.
http://developer.android.com/guide/topics/manifest/activity-element.html#nohist
Have you tried lauching B by calling startActivityForResult() in A?
Do all your processing in B and then ensure you call finish on it and this should clear all data in it.
Please let me know if it works.
It's obvious. OnSaveState is called when finishing activity, and this activity is popped out of the stack. Best practice for you to clear the situation is to log all the lifecycle events in both activities, it will help to figure out where to put initializing your B activity.
Yes, and one more thing try researching onNewIntent method in B activity i suppose it will be really helpfull
As i stated in my last comment to the post, #Jianhong given me the correct answer (aslso if as a comment). As he don't copied the comment as answer in time, i add this answer and mark it as the ACCEPTED. Thanks #Jianhong!
Answer:
#Jianhong OMG! you completely right! i checked for this problem in past days but i couldn't find it as... i've not UPDATED from SVN. my coworker inserted lines of code that prefill fields by some static var!