setResult does not work when BACK button pressed
AndroidAndroid Problem Overview
I am trying to setResult after the BACK button was pressed. I call in onDestroy
Intent data = new Intent();
setResult(RESULT_OK, data)
But when it comes to
onActivityResult(int requestCode, int resultCode, Intent data)
the resultCode is 0 (RESULT_CANCELED) and data is 'null'.
So, how can I pass result from activity terminated by BACK button?
Android Solutions
Solution 1 - Android
You need to overide the onBackPressed()
method and set the result before the call to superclass, i.e
@Override
public void onBackPressed() {
Bundle bundle = new Bundle();
bundle.putString(FIELD_A, mA.getText().toString());
Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
super.onBackPressed();
}
Solution 2 - Android
Activity
result must be set before finish()
is called. Clicking BACK actually calls finish()
on your activity
, so you can use the following snippet:
@Override
public void finish() {
Intent data = new Intent();
setResult(RESULT_OK, data);
super.finish();
}
If you call NavUtils.navigateUpFromSameTask();
in onOptionsItemSelected()
, finish()
is called, but you will get the wrong result code
. So you have to call finish()
not navigateUpFromSameTask
in onOptionsItemSelected()
.
https://stackoverflow.com/questions/10564474/wrong-requestcode-in-onactivityresult
Solution 3 - Android
If you want to set some custom RESULT_CODE
in onBackPressed
event then you need to first set the result
and then call the super.onBackPressed()
and you will receive the same RESULT_CODE
in the caller activity's onActivityResult
method
@Override
public void onBackPressed()
{
setResult(SOME_INTEGER);
super.onBackPressed();
}
Solution 4 - Android
I refactored my code. Initially I prepared some data and set it as activity result
in onDestroy
(this did not work). Now I set activity
data each time the data to be returned is updated, and have nothing in onDestroy
.
Solution 5 - Android
You should override onOptionsItemSelected like this:
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
final Intent mIntent = new Intent();
mIntent.putExtra("param", "value");
setResult(RESULT_OK, mIntent);
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Solution 6 - Android
Refer onActivityResult(int, int, Intent) doc
Solution is to check the resultCode for value Activity.RESULT_CENCELED. If yes, then it means that either BACK was pressed or the activity crashed. Hope it works for you guys, works for me :).
Solution 7 - Android
onDestroy
is too late in the chain — instead override onPause
and check isFinishing()
to check if your activity is at the end of its lifecycle.
Solution 8 - Android
Try overriding onBackPressed (from android level 5 up), or override onKeyDown() and catch KeyEvent.BUTTON_BACK (see https://stackoverflow.com/questions/1798252/android-activity-results) This does the trick for me.
Solution 9 - Android
Don't rely on any logic executed in onPause of one activity when you return to the initial one. According to the docs:
> Implementations of this method (onPause) must be very quick because > the next activity will not be resumed until this method returns
See http://goo.gl/8S2Y for details.
The safest way is to set result after each result altering operation is complete (as you mention in your answer)
Solution 10 - Android
i paste the answer may be will be helpful to other people: when a set launcheMode with android:launchMode="singleTask" i also cant get the result, the doc says:
/* <p>Note that this method should only be used with Intent protocols
* that are defined to return a result. In other protocols (such as
* {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
* not get the result when you expect. For example, if the activity you
* are launching uses the singleTask launch mode, it will not run in your
* task and thus you will immediately receive a cancel result.
*/
and:
/* <p>As a special case, if you call startActivityForResult() with a requestCode
* >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
* activity, then your window will not be displayed until a result is
* returned back from the started activity. This is to avoid visible
* flickering when redirecting to another activity.
*/