I have an app which have HomeActivity and 4 activities A,B,C,D.
I want when clicking on button start_activity_A_btn in HomeActivity to star activity A, and A starts B, B starts C, C starts D, then done button which takes me to HomeActivity.
NOTICE : in every activity (A,B,C,D) I have some data to save and get back to the HomeActivity after pressing done button.
What you need to do use the following flag in your intent (please check the link, it explains a similar situation to the one you are facing): FLAG_ACTIVITY_REORDER_TO_FRONT. So, in your activity D, in the onClickListener for the done button, here's the code you'd have to use:
Intent intent = new Intent(this, ActivityAname.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra("data", dataYouReceiveFromABCD);
startActivity(intent);
This will get your A Activity to resume.
Now, regarding the "data" you will just have to keep accumulating this data in a String using some separator if that's possible (since you haven't told us what this data is exactly), so if it was a username and a password you could separate the two using a random combination of characters that will possibly never occur ("246#$^") and then just keep creating a string that you keep building in A, B, C and D and then finally in D you put that String as an extra in the intent (check the code I've posted above). If it's some other sort of data then you could perhaps serialize it if that helps. However, if you do use a String with a predetermined separator then all you will have to do is in Activity A you will have to use the following code in the onResume() method of Activity A.
if(this.getIntent().getExtras().getString("data") != null)
{
String data = this.getIntent().getExtras().getString("data");
//do some stuff here with that data
}
If you need data returning an Activity, you should use startActivityForResult to start ABCD. This works very much like your HomeActivity is opening up some dialog, and once the Activity finished (by pressing done or cancel, depends), you get onActivityResult in your HomeActivity.
Related
I have 8 Activities in my Android app and I want:
1)Every time I press Back button during my first 7 Activities to go back to my previous Activity(Act1< Act2< Act3< Act4< Act5< Act6< Act7) BUT
2)ONLY when I am in the 8th Activity I want to definitely exit my Android app and go to my phone's Home Screen.I try to do it by overriding onBackPressed method in my 8th Activity (Phone Home Screen<-Act8)
I found an Android implementation in which I insert finish();in every intent of all my 8 Activities but this is not what I want since this way I can't go back to the previous Activity whenever I want(with finish(); every current Activity is removed from back stack).
How will I do it please?
My code so far in my 8th Activity is:
#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);
finish();
}
Another way: create a 9th Activity and call it FinishAllActivity or something like that. Make this activity call finish() and then return in its onCreate().
In onBackPressed() in Activity 8, start FinishAllActivity using the FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK flags (see this question for more details). Activities 1-8 will be removed from the stack, then the 9th Activity will start and immediately terminate and your task stack is clear. When you reopen the app it should start from Activity 1.
The advantage of doing it this way is that you don't have to modify Activities 1-7.
Add a public static boolean to one of your classes that indicates the app is exiting. Set this boolean in activity 8 when you want the app to finish, and have all of your other activities check it in their onResume() and finish immediately if it is true. Make sure the first activity clears it before finishing, or it may still be set the next time the app runs. (Android doesn't necessarily discard the VM when your last activity finishes, so the class and its static members may be reused next time.)
Note that this is the simple way, not the "Android way." Global variables are generally frowned upon, for reasons you can Google. The "correct" way to do this would be to start each activity for result and return a result to onActivityResult(...) that indicates whether the app is exiting.
You can implement a broadcast receiver and have each of your Activities that you want to close call finish() when they receive the broadcast (which will be sent from your last activity). I would imagine you'd need to have your broadcast receiver class be either an anonymous inner class or a private class within your activity(s) so that you can easily access your enclosing Activity's finish method.
Here's a good example of broadcast receivers:
http://www.tutorialspoint.com/android/android_broadcast_receivers.htm
Look at the custom intents section.
Doing it this way is a loosely coupled way to implement what you are looking to do.
use FLAG_ACTIVITY_CLEAR_TOP Flag in your intent like below example.
Intent intent = new Intent(getApplicationContext(),FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
in your first activity check below condition.
if (getIntent().getBooleanExtra("EXIT", false)) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
finish();
}
here FLAG_ACTIVITY_CLEAR_TOP work like below example
consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.
so here you have to call D is your last activity and A is your first activity.
This way you are finishing your 8th Activity returning to your 7th Activity and same time you are like emulating a pressing of Home button on a device. When you rerun your app it will appear with 7th Activity on a screen. If you wish to see the 8th Activity in this case then just remove the finish() method. If you wish next time your app to start with 1st Activity then you should finish all the activities from 8 to 2nd but not the 1st. Also you could launch your 1st Activity adding a FLAG NEW_TASK or some other flags.
UPDATE
My advise (for the quick result without changing the workflow) is to use startActivityForResult() to start all activities in chain. When user exits the app just return a special parameter using setActivityResult() to get all nested activities know about user's choice making all nested Activities to run finish(). This way all your 8 activities will be finished properly.
I have Activity A which has editTexts and from activity A, a user can go to activity B and fill out more information. Once the user is done on activity B, they press a button and come back to A. I would like to come back to A with the information that the user had filled in to be already there and not have to fill in the information again.
Currently, this is my code for coming back from B to A.
Intent intent = new Intent(NewAddressActivity.this, CreditCardActivity.class);
intent.putExtra("newAddressEntered", true);
intent.putExtra("newAddress", (Serializable) newAddress);
startActivity(intent);
With this code, when the user comes back, the fields on activity A are empty.
*Note - I need to pass data from B to A when going back.
Any tips on how to do this properly would be greatly appreciated.
Thanks
You are on the right track. You can do that using .putExtra
You can pass extra data via the intent using intent.putExtra("key",
text_field.getText().toString()) on the intent before you send it (in
the first activity) and getIntent().getExtras().getString("key") in
the second activity.
This is assuming text_field is your EditText you want to pass the
value from. You can change "key" to whatever you want, too.
You're actually not "coming back", but starting a new empty intent, thats why the fields are blank again. Instead, you should just call:
finish()
Regarding filling related fields from different Activities, I wouldn't recommend that, but if you need to keep it that way, you may have a singleton class to store all field values for instance.
Also, you could send B fields to A as activity results.-
http://developer.android.com/training/basics/intents/result.html
But still, I would recommend keeping all related fields in one Activity.
Change the launchmode of your Activity A (CreditCardActivity) to singleTop in manifest file and try. The documentation says
If an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity.
So your activity should retain old values.
I am new in android and I have total 6-7 activities in my application. I want to know how can I manage my activities properly means when I move to the A->B->C->D like that. Then how can I move that the stack of these activities not created.
On moving from one activity to the other I am using the below code:
Intent intent=new Intent(current.this,next.class);
startActivityForResult(intent, 0);
And now if I want to move back on the earlier activity I used the code as:
Intent start = new Intent(current.this,next.class);
startActivity(start);
finishActivity(0);
Is there a special reason that you don't want to use the activity stack and let the activities handle themselves?
The Android system has done a very good job with the activity lifecycle. It allows you to start an Activity from different places without confusing the user because the back button will bring the user back to a different activity.
If you don't have a very good reason to not use the Android guideline try to stick to the way the system is doing it. Every other thing will only give you problems.
You are starting activities for a result but how I understand you you will never return to them.
You can start an Activity and after that just finish the current Activity. That way the activity will not be put on the back stack. Now you need to listen for back button pushes and create the activities that you want to bring the user to.
If you want to move from Activity A to D like going to the start/home screen of you app you do the following:
Intent goBackToA = new Intent(context, StdActivity.class);
goBackToA.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(goBackToA);
The flag FLAG_ACTIVITY_CLEAR_TOP will tell the system that if the backstack contains an instance of the Activity this activity will be shown and all activity that are between the current activity and the target activity are removed from the backstack. This allows you to go back to a home activity without creating huge loops that the user can move through with the back button.
To move back to the previous activity you don't have to create a new intent, you can simply call this.finish() on the one that should dissapear.
To move back to the previous activity you don't have to create a new intent, you can simply call this.finish() on the one that should dissapeear or you can press Back button to see the previous Activity .
whenever you want to navigate from one class to another use this code, may be this help you to navigate the Activity,
Intent nextpage = new Intent(CurrentActivity.this,NextActivity.class);
startActivity(nextpage);
this.finish();
in my activity I have login page (L), which leads to hierarchy of activites (L -> A -> B -> C). When user log in, and he goes up to activity C, he minimizes his app and after some while, system will do a force close on this app.
Now, when he start this app again a he log-in, he should have see, where he ware last time an application was running with all opened activities on stack (if he was in C, one back button leads to B, then to A, then to L). How to achive such a behavior in Android? I am now using sharedpreference, which is hodling string of visited activities, then some flag, which tells me whether an app was finished with System close or user close and them I am persisting each activity with its own sharedpreference. If system kills my app, after login I open series of past opened activities in For cycle, but they are on the stack only. They are opened (= onCreate method is run) only when I use back button to see them.
Do you see any cleaner approach?
Thanks
When I want to maintain hierarchy after a force close I bypass the activity stack by replacing each activity with the one that it calls and then override the back event to do the same in reverse.
In ActivityL.java, where you want to go to ActivityA:
Intent intent = new Intent(getApplicationContext(), ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
You now just have one activity on the stack - ActivityA. To have the back button behave properly and return you to ActivityL, add this to ActivityA:
#Override
public void onBackPressed () {
Intent intent = new Intent(getApplicationContext(), ActivityL.class)
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
You'll still need to store enough state information to get you back to the activity where the user was before the force close. In onCreate for ActivityL, check that state info to determine which view you want the user to be on and use code similar to the first block above to go directly there.
This seems a bit cleaner to me than rebuilding the entire activity stack on startup. This does however become more complex if your activities don't follow a strict hierarchy. (i.e. sometimes activity A starts activity B and sometimes it starts activity C).
I intend to start 3 activities in a chain (like from main open Activities A, B and then C, which will be visible for the user), but I wasn't able to find some way how to do that in Android. Do not ask me why, I just have to do that for restoring my application state, where is was before.
Thanks for any ideas
Waypoint
Edit:
Ok, I have tried opening activities in For cycle, but they aren't opened properly. They are chained, but recreated only when I press back button and they display to me. I need some solution which leads to: open A, if A is opened check if needs to open B -> YES, open B, check if needs to open C -> YES, open C, no need to open another activity -> FINISH
prior to start any activity , decide which activity should be start .
Lets take your case >>first check for B , if yes check for C , now open the required 1 .
i understand comparable data is inside the activities, but a right data structure will always allow you to access the data wherever and whenever it actually requires .
For future readers: if you want to start activity with proper back stack, you should use TaskStackBuilder.
define the natural hierarchy for your activities by adding the android:parentActivityName attribute to each element in your app manifest file
create an instance of TaskStackBuilder and call addNextIntentWithParentStack(), passing it the Intent for the activity you want to start.
For more details see official documentation
Override the onResume-method in each activity. Add the check and the start of the activity there.
public void onResume() {
if( condition )
startActivity( intentForTheNextActivity );
}
Where condition is whatever condition you might have (in your example if B should be started, C should be started etc.) and intentForTheNextActivity is the intent for the following activity in the chain (e.g. if now in A, the intent is for B etc.).
I'm having a very hard time understanding exactly what it is you're trying to do. Sometimes it seems like it's a chain (A opens B, B opens C and so forth) sometimes it seems you want some random flow (A opens B, B opens A, A opens B, B opens C) - which makes it really hard to give you a specific answer.
What I can do, is recommend that you read up on the following:
Activity Lifecycle
Starting Activities and getting results (in particular the methods startActivityForResult and setResult)
If you need more help than this - you need to explain yourself better (maybe with a diagram or some sample code of what you have tried so far).
You didn't provide any information of what you've tried, so i'll give you the simplest answer:
method startActivity(Intent intent), more info here.
Edit: Hmm, how about this? I don't have SDK around me now, but i can provide a concept. I'm not sure if it works, but i hope it'll guide you to soultion.
Let's imagine this is ActivityA's code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (doINeedActivityB) {
Intent activityC = new Intent(this, ActivityC.class);
this.startActivity(activityA);
}
if (doINeedActivityC) {
Intent activityC = new Intent(this, ActivityC.class);
this.startActivity(activityC);
}
}