skynova2070
skynova2070

Reputation: 29

setResult is ignored when user presses the back button

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?

Upvotes: 1

Views: 614

Answers (2)

Fidan Bacaj
Fidan Bacaj

Reputation: 416

Remove : android:launchMode="singleTop"

and remove super.onBackpressed in on onBackpressed function because you used finish()

Upvotes: 1

Reaz Murshed
Reaz Murshed

Reputation: 24211

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!

Upvotes: 0

Related Questions