Android Navigation and activities (determine which activity is parent) - android

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.

Related

How to handle UP button action when child activity is invoked from 2 different parent activity

I am pretty much new to android so please forgive if I sound very much immature.
I have activity A, activity B two completely independent activities. Assume I have Activity C, which gets launched when I tap on some button in Activity A. The same activity C can also be launched by tapping some other button in Activity B.
Now my doubt is I need to show UP button on activity C. I know that I need to specify parent activity for activity C in manifest file. But here in my case I have 2 different activities one of them will be parent at any given point. So how can I specify two parents activity names for activity C? How can I dynamically handle that?
Thanks in advance.
Actually, you don't need to specify the C activity's parent in the manifest file; just intercept the click on the home button, & finish your activity : you shall return to the previous, caller one:
ActivityC.java
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: // Intercept the click on the home button
finish();
return true;
}
return super.onOptionsItemSelected(item);
}

No extras in Activity.getIntent() when going back to it from a child Activity

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

Navigating Up to an activity that expects extras

I have Activities A, B, and C in my app and they flow in that order. If I implement the Up button in C, I want it to go back to B. The code stub that Eclipse generated is this:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
However, B expects extras to be passed from A in its onCreate method. The relationship between B and C is that C allows the user to set some settings that affect how B is displayed. I'm currently handling saving the changes in C in onPause(). Should I just finish() C when user presses Up instead of calling navigateUpFromSameTask(this)?
If you're going to be returning from C back to B your activity will be created again, if you use standard launch mode. onSaveInstanceState will not (reliably) work.
Declare the launch mode of your activity B as:
android:launchMode="singleTop"
in your AndroidManifest.xml, if you want to return to your activity. See docu and an explanation here.
I believe you're having a similar problem to this? Essentially, if you're going to be returning from C back to B, there's a possibility it's going to need to call onCreate() again. This means that the extras you obtain from the intent are going to be gone, so you have to store them with something like onSaveInstanceState.

Android Back Stack - UP button method

I have Activity A (Main) and Activity B.
Fact: Activity A has: android:launchMode="singleInstance"
Usual scenario is:
User launches application > Activity A.
User clicks an item > Activity B
3.A. If user clicks on back/up buttons > Back to A (without calling finish() on B)
User clicks the SAME item as before > Forth to B.
At this point he can go back and forth without new instances. It's all in the stack and it doesn't recreate activities. (All right!)
3.B. If user clicks Home, then goes to task manager and brings the app to front > Activity B (all good, so far)
If user clicks UP button, it goes to TASK MANAGER, and I want it to go to Activity A (back button is expected to work this way, so let's focus on UP button).
Here's the implementation I have in Activity B for BACK and UP buttons.
#Override
public void onBackPressed() {
moveTaskToBack(true);
// I don't want to finish() the activity, so the user can reclick the same
// item without reloading the whole activity again (webview slow when parsing html).
return;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
moveTaskToBack(true);
// I don't want to finish() the activity... idem.
// I need to implement here the bring Activity A to front
break;
}
}
So, what I want is: to "Go Back" to Activity A keeping the same idea of using the stack to reload Activity B if needed, without using Intents (unless it calls activity to front, without adding items to the stack.)
Let me know if I explained myself clearly and if you need more info.
UPDATE:
I've found this at: http://developer.android.com/training/implementing-navigation/ancestral.html
This is how I adapted it.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, Activity_A.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
} else {
moveTaskToBack(true); // I want it this way. Don't worry.
}
break;
}
}
But the method NavUtils.shouldUpRecreateTask is ALWAYS returning false.
I did the http://developer.android.com/training/implementing-navigation/ancestral.html#SpecifyParent part, so that's not the issue.
My problem is that I want to recognize if Activity A exists in the stack, for when i.e. the app is launched from the task manager.
How can I achieve this?
Thanks.
moveTaskToBack moves the entire task to the background. it doesn't finish the activity.
in order to have full control of activities, you have some possible solutions:
create your own global manager for the activities, monitor each of them through all of their lifecycle and decide what to do on each event.
you could also finish each activity as soon as you go from it, and put "it" (just its name or something) in a stack and restore its state when you come back to it.
use fragments instead, and manage them all on a single activity. be warned of configurations changes though.

How to close activity and go back to previous activity in android

I have a main activity, that when I click on a button, starts a new activity, i used the following code to do so:
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
The above code was run from the main activity.
Now in my new activity which is called by the main activity, I have a back button.
When I click on this back button I want my new activity to close and it must go back to the original main activity.
I have tried calling super.finish() and just finish() (from the new activity) but this then closes my entire application (including my main activity).
How can I just close the activity that is currently in focus, and then return to the main activity?
EDITED
The fact that my phone's back button also closes my entire app, leads me to think that i have started up the second activity incorrectly?
OK I have been looking,
I created a Settings Activity that uses the same manifest code and the same code to Start the activity.
For the settings Activity when I push the back button, it returns to the Main activity.
With the activity mentioned above in the main question it simply exits my entire app.
So the problem doesn't seem to be with the code to finish the activity but the activity itself.
I think you are calling finish() method in MainActivity before starting SettingsActivity.
The scenario which you have described will occur in following two ways:
EITHER
You have set android:noHistory = "true" for MainActivity inside AndroidManifest.xml which causes MainActivity to finish automatically on pressing the back key.
OR
Before switching to your 'SettingsActivity', you have called finish() in your MainActivity, which kills it. When you press back button,since no other activity is preset in stack to pop, it goes back to main screen.
You can go back to the previous activity by just calling finish() in the activity you are on. Note any code after the finish() call will be run - you can just do a return after calling finish() to fix this.
If you want to return results to activity one then when starting activity two you need:
startActivityForResults(myIntent, MY_REQUEST_CODE);
Inside your called activity you can then get the Intent from the onCreate() parameter or used
getIntent();
To set return a result to activity one then in activity two do
setResult(Activity.RESULT_OK, MyIntentToReturn);
If you have no intent to return then just say
setResult(Activity.RESULT_OK);
If the the activity has bad results you can use Activity.RESULT_CANCELED (this is used by default). Then in activity one you do
onActivityResult(int requestCode, int resultCode, Intent data) {
// Handle the logic for the requestCode, resultCode and data returned...
}
To finish activity two use the same methods with finish() as described above with your results already set.
if you use fragment u should use
getActivity().onBackPressed();
if you use single activity u can use
finish();
When you click your button you can have it call:
super.onBackPressed();
Button edit = (Button) view.findViewById(R.id.yourButton);
edit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(this, YourMainActivity.class);
startActivity(intent);
finish();
}
});
try this code instead of finish:
onBackPressed();
I believe your second activity is probably not linked to your main activity as a child activity. Check your AndroidManifest.xml file and see if the <activity> entry for your child activity includes a android:parentActivityName attribute. It should look something like this:
<?xml ...?>
...
<activity
android:name=".MainActivity"
...>
</activity>
<activity
android:name=".ChildActivity"
android:parentActivityName=".MainActivity"
...>
</activity>
...
This closes the entire application:
this.finish();
You are making this too hard. If I understand what you are trying to do correctly, the built-in 'back' button and Android itself will do all the work for you: http://developer.android.com/guide/components/tasks-and-back-stack.html
Also, implementing a custom "back" button violates Core App Quality Guideline UX-N1: http://developer.android.com/distribute/googleplay/quality/core.html
I don't know if this is even usefull or not but I was strugling with the same problem and I found a pretty easy way, with only a global boolean variable and onResume() action. In my case, my Activity C if clicked in a specific button it should trigger the finish() of Activity B!
Activity_A -> Activity_B -> Activity_C
Activity_A (opens normally Activity_B)
Activity_B (on some button click opens Activity_C):
// Global:
boolean its_detail = false;
// -------
SharedPreferences prefs = getApplicationContext().getSharedPreferences("sharedpreferences", 0);
boolean v = prefs.getBoolean("select_client", false);
its_detail = v;
startActivity(C);
#Override
public void onResume(){
super.onResume();
if(its_detail == true){
finish();
}
}
So, whenever I click the button on Activity C it would do the "onResume()" function of Activity B and go back to Activity A.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if ( id == android.R.id.home ) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
Try this it works both on toolbar back button as hardware back button.
Finish closes the whole application, this is is something i hate in Android development not finish that is fine but that they do not keep up wit ok syntax they have
startActivity(intent)
Why not
closeActivity(intent)
?
We encountered a very similar situation.
Activity 1 (Opening) -> Activity 2 (Preview) -> Activity 3 (Detail)
Incorrect "on back press" Response
Device back press on Activity 3 will also close Activity 2.
I have checked all answers posted above and none of them worked. Java syntax for transition between Activity 2 and Activity 3 was reviewed to be correct.
Fresh from coding on calling out a 3rd party app. by an Activity. We decided to investigate the configuration angle - eventually enabling us to identify the root cause of the problem.
Scope: Configuration of Activity 2 (caller).
Root Cause:
android:launchMode="singleInstance"
Solution:
android:launchMode="singleTask"
Apparently on this "on back press" issue singleInstance considers invoked Activities in one instance with the calling Activity, whereas singleTask will allow for invoked Activities having their own identity enough for the intended on back press to function to work as it should to.
on onCreate method of your activity
write the following code.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Then override the onOptionsItem selected method of your activity as follows
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
}
return super.onOptionsItemSelected(item);
}
And you are good to go.
Just don't call finish() on your MainActivity then this eliminates the need to Override your onBackPressed() in your SecondActivity unless you are doing other things in that function. If you feel the "need" for this back button then you can simply call finish() on the SecondActivity and that will take you to your MainActivity as long as you haven't called finish() on it
it may be possible you are calling finish(); in the click button event so the main activity is closed just after you clicking the button and when you are coming back from next activity the application is exit because main activity is already closed and there is no active activity.
You have to use this in your MainActivity
Intent intent = new Intent(context , yourActivity);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
context.startActivity(intent);
The flag will start multiple tasks that will keep your MainActivity, when you call finish it will kill the other activity and get you back to the MainActivity
In case none of the above answers helped, I think this might help someone.
I was also having the same problem while pressing the built-in back button or my custom back button, the app closes without returning to the previous activity.
I was calling the second activity from the first activity's toolbar.
But in the starter activity I was calling this:
case android.R.id.home:
if (isActionMode) {
clearSelectingToolbar();
adapter.notifyDataSetChanged();
} else {
onBackPressed(); // This was making the activity to finish
}
break;
And this code to start the activity
case R.id.settings:
context.startActivity(new Intent(ShowAllDirectoriesActivity.this, SettingsActivity.class));
After removing 'case android.R.id.home' part, my activity was able to perform in a normal flow i.e getting back to the previous activity.
So check it if you are also using the same thing!
{ getApplicationContext.finish(); }
Try this method..

Categories

Resources