in action bar when back button is pressed how do I know in the previous activity that back button was pressed , onCreate() does not get called when back button is pressed
I know from the code below that on current activity that back button was pressed but I need to know on previous activity that back button was pressed
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You can navigate between activities using registerForActivityResult() API, and put some extra data in the returned intent that can show you from where it came from.
At source activity:
ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == AppCompatActivity.RESULT_OK) {
if (result.getData() != null) {
String data = result.getData().getStringExtra("ACTIVITY_FROM");
if (data != null)
switch (data) {
case "ACTIVITY2":
// Returned from Activity2
Log.d(TAG, "onCreate: Returned from Activity2");
break;
case "ACTIVITY3":
// Returned from Activity3
Log.d(TAG, "onCreate: Returned from Activity3");
break;
}
}
}
}
);
// Go to Activity 2:
auncher.launch(new Intent(this, Activity2.class));
At the destination activity:
Then put the data when you need to return back from Activity2:
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
setIntent();
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
setIntent();
finish();
super.onBackPressed();
}
private void setIntent() {
Intent intent = new Intent();
intent.putExtra("ACTIVITY_FROM", "ACTIVITY2");
setResult(Activity.RESULT_OK, intent);
}
Related
I have onClick method in MainActivity as following,
public void onClick(View view) {
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("I", "0");
startActivity(i);
}
In SecondActivity I validated the Intent as following
if (getIntent().getStringExtra("I") == null) {
Toast.makeText(this, "NULL", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "NOT NULL", Toast.LENGTH_LONG).show();
}
and started the ThirdActivity from SecondActivity as following
public void onClick(View view) {
Intent i = new Intent(this, ThirdActivity.class);
startActivity(i);
}
Now when come back to SecondActivity from ThirdActivity getIntent().getStringExtra("I") returns null. I also tried overriding onOptionsItemSelected as following.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent i = getIntent();
i.putExtra("I", "0");
break;
}
return super.onOptionsItemSelected(item);
}
Now don't know how to fix this issue. I don't want to use SharedPreference for this issue.
Please follow these steps:
start ThirdActivity for result
public void onClick(View view) {
Intent i = new Intent(this, ThirdActivity.class);
startActivityForResult(i, 1);
}
Update following method, add setResult(Activity.RESULT_OK, i);
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent i = getIntent();
i.putExtra("I", "0");
setResult(Activity.RESULT_OK, i);
break;
}
return super.onOptionsItemSelected(item);
}
In SecondActivity, implement onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == 1 && resultCode == RESULT_OK) {
// Now use data.getStringExtra("I");
}
}
You are not finishing any activity, and you are passing value from main activity to second, then calling third activity, just returning from the third activity and resuming the second activity, you are not passing any data to second activity while coming from third activity.
just change your code as follow:-
//from second to third
public void onClick(View view) {
Intent i = new Intent(this, ThirdActivity.class);
startActivity(i);
finish();
}
// returning from third to second
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent i = new Intent(this, second.class);
i.putextra("I","0");
startActivity(i);
finish();
break;
}
return super.onOptionsItemSelected(item);
}
also you can change like this:-
#Override
public void onBackPressed() {
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("I","0");
startActivity(i);
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
in your third activity only
if you dont want to startactivty then startActivtyForResult() from second to third:-
startActivityForResult(i,101);
implement onActivtyResult method in second activity:-
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == 101 && resultCode == RESULT_OK) {
// Now use data.getStringExtra("I");
}
}
for third activity just finish it in onBackpress() like:-
#Override
public void onBackPressed() {
Intent resultData = new Intent();
resultData.putExtra("I", "0");
setResult(Activity.RESULT_OK, resultData);
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
This is because when you come back from third activity to second activity, getIntent() returns the Intent of third activity and not the first.
And while navigating from third activity to second, you are not passing any string extra and hence you get a null value.
You can try using startActivityForResult() method for your linking from SecondActivity to ThirdActivity this way, you can then use setResult(intent) before killing the ThirdActivty. Thus when you come back to your SecondActivity you will have the result intent you passed in your ThirdActivty inside the onActivityResult method of your SecondActivity.
Hope this helps.
Make a change when you move towards SecondActivity from ThirdActivity.:
Intent i = new Intent(this, SeconActivity.class);
i.putExtra("I",getIntent().getStringExtra("I"));
startActivity(i);
you have to pass again
i.putExtra("I", "0");
from third activity to second activity
try this :
put this on your thirdactivity
#Override
public void onBackPressed() {
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("I","0");
startActivity(i);
finish();
}
How can I get back to the main fragment when I click the back button in activity whilst keeping the entered data in the same fragment? In the code below, I'm calling this from my second activity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
if(fromString.equalsIgnoreCase("second")){
//finish();
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}else if(fromString.equalsIgnoreCase("first")){
finish(); // close this activity and return to preview activity (if there is any)
}
}
return super.onOptionsItemSelected(item);
}
To go back to the fragment from my first activity I am calling finish() and it is working fine and keeps the data. I want this to work the same as going back to the fragment from the second activity.
Before moving to next activity you can store the data in SharedPreferences in your fragment class
SharedPreferences preferences;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
if(fromString.equalsIgnoreCase("second")){
//finish();
preferences = getContext().getSharedPreferences("my_prefs", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("pause", false);
editor.apply();
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}else if(fromString.equalsIgnoreCase("first")){
finish(); // close this activity and return to preview activity (if there is any)
}
}
return super.onOptionsItemSelected(item);
}
and in onCreate() method you can retrieve the values like
#Override
public void onCreate(Bundle savedInstanceState) {
preferences = getContext().getSharedPreferences("my_prefs", 0);
boolean pause = preferences.getBoolean("pause", false);
}
In my application, I defined 2 activities in the Manifest file like this:
<activity android:name=".event.EventDetailsActivity"
android:launchMode="singleTop"
android:parentActivityName=".main.MainActivity"
android:theme="#style/AppTheme.WithActionBar"/>
<activity
android:name=".main.MainActivity"
android:launchMode="singleTop"/>
In the MainActivity, I have 4 fragments. In one fragment, I start the EventDetailsActivity in one fragment using:
Intent intent = new Intent(new Intent(getContext(), EventDetailsActivity.class));
intent.putExtra(EventDetailsActivity.ID_KEY, id);
intent.putExtra(EventDetailsActivity.TYPE_KEY, true);
startActivityForResult(intent, DETAILS_REQUEST);
How I handle the back navigation in EventDetailsActivity:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onSupportNavigateUp() {
Log.d(TAG, "Navigate up");
onBackPressed();
return true;
}
#Override
public void onBackPressed() {
Log.d(TAG, "Back pressed " + isChanged);
if (isChanged) {
Log.d(TAG, "Set result");
setResult(RESULT_OK);
finish();
}
super.onBackPressed();
}
The problem is onActivityResult get called in the calling Fragment but the result code is always 0 (RESULT_CANCELED). Also, onSupportNavigateUp never gets called if I press the back arrow button. Is there any workaround for this problem?
Remove : android:launchMode="singleTop"
and remove super.onBackpressed in on onBackpressed function
because you used finish()
As you're getting the onActivityResult callback from your Fragment correctly I assume the problem is about setting the proper result to the starting Activity. So here's I'm proposing some edit you might consider in your code.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
setResult(RESULT_OK);
return true;
}
return super.onOptionsItemSelected(item);
}
// No longer necessary
/* #Override
public boolean onSupportNavigateUp() {
Log.d(TAG, "Navigate up");
onBackPressed();
return true;
} */
/* #Override
public void onBackPressed() {
// Super call needs to be the first line
super.onBackPressed();
if (isChanged) {
setResult(RESULT_OK);
}
} */
So I've omitted the onBackPressed function because by default, if the user presses the back button, the result will be Activity.RESULT_CANCELED.
So there's a hacky solution here is to implement the key event callback listener like this.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
setResult(RESULT_OK);
finish();
}
return super.onKeyDown(keyCode, event);
}
Hope that helps!
I'm having a problem in my android application. I don't know why 'onActivityResult' method is not being called when 'Up navigation' button from action bar is pressed. I think I've done everything properly:
Parent activity launch child activity with 'startActivityForResult' method.
Intent intent = new Intent(ParentActivity.this, ChildActivity.class);
startActivityForResult(intent, 1000);
Parent activity has overridden 'onActivityResult' method.
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (data != null && requestCode == 1000)
{
Bundle extras = data.getExtras();
Boolean rc = extras.getBoolean(MyConstants.INTENT_EXTRA_RESULT);
if (rc)
{
.......
}
}
}
Child activity has overridden 'onOptionsItemSelected' and calls 'NavUtils.navigateUpFromSameTask'.
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home)
{
Intent result = new Intent((String)null);
result.putExtra(MyConstants.INTENT_EXTRA_RESULT, true);
setResult(RESULT_OK, result);
NavUtils.navigateUpFromSameTask(this);
return true;
}
else
{
return super.onOptionsItemSelected(item);
}
}
Child activity has overriden 'finish' method. This method set a result.
public void finish()
{
Intent result = new Intent((String)null);
result.putExtra(Constantes.INTENT_EXTRA_HAY_QUE_RECALCULAR, hayQueRecalcular);
setResult(RESULT_OK, result);
super.finish();
}
I'm not sure why 'onActivityResult' method is not being called.
What I've observed is that child activity is not being finished ('finish' method is not being called) when 'Up navigation' button from action bar is pressed. However it is called when back button (hardware button) is pressed.
What I'm doing wrong?
Thanks
As your child Activity is just on the top of your Parent Activity, no need of this method
NavUtils.navigateUpFromSameTask(this);
write like
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Intent result = new Intent((String) null);
result.putExtra(MyConstants.INTENT_EXTRA_RESULT, true);
setResult(RESULT_OK, result);
finish();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
finish your Child Activity when home button is pressed.
Here is my problem:
Create a MainActivity. Add a button which will start another activity SecondActivity.
Intent i = new Intent(getActivity(),SecondActivity.class);
startActivityForResult(i,0);
Inside the SecondActivity, I capture the back button click event and also add a button to return to the first Activity.
When back button in action bar is clicked:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// back button
Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
setResult(Activity.RESULT_OK, resultIntent);
//finish();
return false;
}
return super.onOptionsItemSelected(item);
}
When the button inside activity is clicked:
Button btn = (Button)this.findViewById(R.id.button2);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
});
The onActivityResult in MainActivity is called when I click the button inside the SecondActivity, but it's never been called if I click the back button in Actionbar of SecondActivity. Can anybody tell me why? Thanks
Here is the code which is working:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// back button
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
I guess the finish() will close the current Activity, and return true inform that action has been processed. (The default back action seems to be different from finish().)
Try this:-
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
Good answer is Gopal Rao code in the same question. Its worked for me. This is a copy of his solution:
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Intent result = new Intent((String) null);
result.putExtra("SOME_CONSTANT_NAME", true);
setResult(RESULT_OK, result);
finish();
return true;
}
else {
return super.onOptionsItemSelected(item);
}
}