setResult does not work when BACK button pressed

Android

Android 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. 
 */

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionalex2k8View Question on Stackoverflow
Solution 1 - Androidn224576View Answer on Stackoverflow
Solution 2 - AndroidJBMView Answer on Stackoverflow
Solution 3 - AndroidKhurram ShehzadView Answer on Stackoverflow
Solution 4 - Androidalex2k8View Answer on Stackoverflow
Solution 5 - AndroidmdolanciView Answer on Stackoverflow
Solution 6 - AndroidAnkurView Answer on Stackoverflow
Solution 7 - AndroidRoman NurikView Answer on Stackoverflow
Solution 8 - AndroidMrJreView Answer on Stackoverflow
Solution 9 - AndroidBostoneView Answer on Stackoverflow
Solution 10 - Androidbanxi1988View Answer on Stackoverflow