Reputation: 19824
I'm trying to use startActivityForResult()
, I need to start an activity from a fragment, and then process the result in the original activity rather than the fragment that started it (when back is pressed). Can anyone tell me if this is possible or what my issue is?
Activity_A hosts Fragment_A, and the fragment can start Activity_B.
Fragment_A:
Intent intent = new Intent(mContext, Activity_B.class);
intent.putExtra(EXTRA_CHOSEN_BUSINESS, mChosenBusiness);
intent.putExtra(EXTRA_CHOSEN_POSITION, position);
getActivity().startActivityForResult(intent, 1);
Activity_B:
@Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra("myBoolean", wasUsingMap);
setResult(RESULT_OK, intent);
finish();
super.onBackPressed();
}
Activity_A:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
mWasUsingMap = data.getBooleanExtra("myBoolean", false);
}
}
}
The data in this case is always null.
For testing I have tried not using getActivity().startActivityForResult(intent, 1);
and simply using startActivityForResult(intent, 1);
and the placing the onActivityResult in the fragment (with a call to the super onActivityResult in the activity following this answer) but the data is still null. I need it in the hosting activity anyway though if possible. I have also tried the top answer here and am still stumped..
(as a side note the boolean is used to detect which fragment should be displayed when the user presses back).
Upvotes: 2
Views: 2153
Reputation: 1473
I had a similar problem and the solution was actually easy to implement (hard to find though...)
In FragmentA call:
startActivityForResult(intent, 1); //not getActivity().startActivityForResult(intent, 1);
and override onActivityResult (inside the fragment)
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK){
//whatever
}
if (resultCode == RESULT_CANCELED) {
//whatever
}
}
}
Then, on ActivityB do something like this:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
Log.e("home button", "pressed");
Intent returnIntent = new Intent();
returnIntent.putExtra("result",mResult);
setResult(RESULT_OK, returnIntent);
finish();
super.onBackPressed();
return true;
case R.id.others:
//whatever
}
return super.onOptionsItemSelected(item);
}
Upvotes: 5
Reputation: 19824
My issue was to do with the logic of using the Up caret in the action bar vs. using the back button. Previously I had called onBackPressed() when the up caret was hit, but this was not necessary.
The result rather confusingly was that the hardware back button successfully returned a result with the code above plus the changes suggested by user Fremmedehenvendelser, but the Up caret did not even though it would also enter onBackPressed().
Replacing the call to onBackPressed() when the home caret is hit (in Activity_B's parent):
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == android.R.id.home){
onBackPressed();
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
With this (in Activity_B) seems to work nicely for me:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home){
getDrawerToggle().setDrawerIndicatorEnabled(true);
Intent intent = new Intent();
intent.putExtra("myBoolean", wasUsingMap);
if (getParent() == null) {
setResult(RESULT_OK, intent);
} else {
getParent().setResult(RESULT_OK, intent);
}
finish();
}
return super.onOptionsItemSelected(item);
}
Interestingly it seems be essential that getDrawerToggle().setDrawerIndicatorEnabled(true);
is called otherwise the result is not sent back (this line is in onBackPressed() too).
Upvotes: 0
Reputation: 2851
super.onBackPressed();
shouldn't be the first statement, once it is called, the rest of the body of the method is unreachable.
EDIT
From a fragment, you should start another activity like this:
Intent intent = new Intent(getActivity(), Activity_B.class);
// put data
startActivityForResult(intent, 1);
Upvotes: 2