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!
Related
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.
Suppose I have 3 activities: A, B and C.
A: Home Activity
B: Information gather Activity
C: Information display Activity
My desired flow goes like:
A triggers B to gather information.
When B ends, C will get the information and display.
A->B->C->A.
When C ends, it should go back to A. (this is never a problem as I will B: finish())
My first attempt: (Failed due to I do not want to see the A after B, even for few miliseconds)
A triggers B to gather information. (startActivityAsResult)
B pass result to A, and B :finish(). (onActivityResult)
Then A triggers C to display. (startActivity)
My second attempt: (Succeed but I'm thinking is there a better way despite this?)
A triggers B to gather information. (startActivity)
B triggers C, and B :finish(). (startActivity)
Questions:
Is there any alternative way (which is simpler/direct) of defining the sequence of navigation flows like i see taskBuilder with nextIntent() API?
In Activity C on back button press clear the backstack and navigate to A
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
}
return super.onKeyDown(keyCode, event);
}
public void onBackPressed() {
Intent myIntent = new Intent(C.this,A.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// clear the backstack
startActivity(myIntent);
finish();
return;
}
A to B To C
In your activity back stack you will have C at the top, next B and next A.
When you press back button in C, activity C is popped from stack, destroyed and the previous activity B takes focus. So if you wish to navigate to A from C ,clear the back stack , navigate to A and finish the current activity.
If I understand you correctly, you just want to make it impossible for the user to use the back button to get into activities that have already been "used up," yes? Try modifying the activity tags in your AndroidManifest.xml using something like the following:
<activity
android:name="yourpackagename.yourappname.YourActivity"
android:label="#string/your_app_title"
android:noHistory="true" >
Once you add the noHistory attribute, the activity in question is yanked from the activity history, and you'll be able to force your user to go only forwards as your intents describe.
When the BACK button is pressed on the phone, I want to prevent a specific activity from returning to its previous one.
Specifically, I have login and sign up screens, both start a new activity called HomeScreen when successful login/signup occurs. Once HomeScreen is started, I want to prevent the users from being able to return to the login or sign up screens by pressing the BACK key.
I tried using Intent.FLAG_ACTIVITY_NO_HISTORY, but since the application has Facebook integration, when the 'Login with Facebook' is used, Facebook should return to the initial login screen, therefore I should keep a history of these activities.
I thought of overriding the behaviour of the BACK button on HomeScreen to directly finish an application when the button is pressed and I used
#Override
public void onBackPressed() {
finish();
}
but that also does not work.
My suggestion would be to finish the activity that you don't want the users to go back to. For instance, in your sign in activity, right after you call startActivity, call finish(). When the users hit the back button, they will not be able to go to the sign in activity because it has been killed off the stack.
Following solution can be pretty useful in the usual login / main activity scenario or implementing a blocking screen.
To minimize the app rather than going back to previous activity, you can override onBackPressed() like this:
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
moveTaskToBack(boolean nonRoot) leaves your back stack as it is, just puts your task (all activities) in background. Same as if user pressed Home button.
Parameter boolean nonRoot - If false then this only works if the activity is the root of a task; if true it will work for any activity in a task.
I'm not sure exactly what you want, but it sounds like it should be possible, and it also sounds like you're already on the right track.
Here are a few links that might help:
Disable back button in android
MyActivity.java =>
#Override
public void onBackPressed() {
return;
}
How can I disable 'go back' to some activity?
AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>
There are two solutions for your case, activity A starts activity B, but you do not want to back to activity A in activity B.
1. Removed previous activity A from back stack.
Intent intent = new Intent(activityA.this, activityB.class);
startActivity(intent);
finish(); // Destroy activity A and not exist in Back stack
2. Disabled go back button action in activity B.
There are two ways to prevent go back event as below,
1) Recommend approach
#Override
public void onBackPressed() {
}
2)Override onKeyDown method
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK) {
return false;
}
return super.onKeyDown(keyCode, event);
}
Hope that it is useful, but still depends on your situations.
Since there are already many great solutions suggested, ill try to give a more dipictive explanation.
How to skip going back to the previous activity?
Remove the previous Activity from Backstack. Simple
How to remove the previous Activity from Backstack?
Call finish() method
The Normal Flow:
All the activities are stored in a Stack known as Backstack.
When you start a new Activity(startActivity(...)) then the new Activity is pushed to top of the stack and when you press back button the Activity is popped from the stack.
One key point to note is that when the back button is pressed then finish(); method is called internally. This is the default behavior of onBackPressed() method.
So if you want to skip Activity B?
ie A<--- C
Just add finish(); method after your startActvity(...) in the Activity B
Intent i = new Intent(this, C.class);
startActivity(i);
finish();
finish() gives you method to close current Activity not whole application. And you better don't try to look for methods to kill application. Little advice.
Have you tried conjunction of Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY? Remember to use this flags in Intent starting activity!
Put finish() just after
Intent i = new Intent(Summary1.this,MainActivity.class);
startActivity(i);
finish();
If you don't want to go back to all the activities on your application, you can use
android:launchMode="singleTask"
Learn more here: http://developer.android.com/guide/topics/manifest/activity-element.html
paulsm4's answer is the correct one. If in onBackPressed() you just return, it will disable the back button. However, I think a better approach given your use case is to flip the activity logic, i.e. make your home activity the main one, check if the user is signed in there, if not, start the sign in activity. The reason is that if you override the back button in your main activity, most users will be confused when they press back and your app does nothing.
This method is working fine
Intent intent = new Intent(Profile.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
#Override
public void onBackPressed() {
}
When you create onBackPressed() just remove super.onBackPressed();and that should work
Just override the onKeyDown method and check if the back button was pressed.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
//Back buttons was pressed, do whatever logic you want
}
return false;
}
Put
finish();
immediately after
ActivityStart
to stop the activity preventing any way of going back to it.
Then add
onCreate(){
getActionBar().setDisplayHomeAsUpEnabled(false);
...
}
to the activity you are starting.
AndroidManifest.xml
<activity
android:name=".welcome.SplashActivity"
android:noHistory="true" // just add this line
android:exported="true">
</activity>
A little info as to why I am attempting to do this: I am using ActivityGroups to open an activity from a tabHost activity and have that new activity stay under the tabs. That part i've got. But when in that new activity, if I use the back button it takes me right out of the tabs activity so I have to click a few times to get back to where I was.
Is there a way to set the back button to go to a specific activity rather than killing the current activity window?
I believe you should be able to do something like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
// start new Activity here
}
return super.onKeyDown(keyCode, event);
}
But overriding the expected functionality of the back button is not advisable.
In general, I would advise against that because it breaks the UX. The user expects the back button to kill the entire window, especially since you are using the tabhost. To the user, the entire bunch (tabs and all) is a single activity that he wants to exit when he hits the back button.
If you still want to do it, refer to #onBackPressed(). It is called when the activity has detected the user's press of the back key. The default is to finish the activity, but you can make it do whatever you want. I advise care and caution.
You might find some inspiration from here.
I have 3 activities A,B and C. Activity A contains a list of items. When we click a row in Activity A, it calls Activity B which describes the item. In activity B i have another list. When I click on a row in it, it calls Activity C.
I have to pass id field from A to B and then to C.
Suppose I have values
Small
Medium
in Activity A.
I am clicking Small from this and going to Activity B and then to C. Everything works fine. The id passed is also correct throughout the activities.
Now from C, I am clicking phone's back button and going to B and then agin clicking phone's back button and going to A.
Now I am clicking Medium from the list. The id is correctly passed to B. But when I reach C, its not going to onCreate() instead to onResume(). There I am getting id value as the old one, of that of Small. But I want the correct id. What may be the reason for this issue? Could anyone please help. Thanks in advance.
I think.. U have to finish the activity when u r handling the back button in Activity C
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
finish();
}
return super.onKeyDown(keyCode, event);
}
The problem occurs because Activity C doesn't get killed, only suspended.
I haven't tested, but I'm fairly certain that if you pass the data via Intent.putExtra, you should get the behaviour you're looking for (I sincerely hope different extra-data causes a new instance to get launched)
Hope this helps,
Phil Lello
As per my knowledge in android activity get destroyed when you press back button(by default).
I suspect you might be dong something wrong while passing data between activities.
But still if you fill it is related to activity is not getting destroyed. You can finish your Activity C in onPause() method. It will resolve your problem.