278

I have 3 classes in my example: Class A, the main activity. Class A calls a startActivityForResult:

Intent intent = new Intent(this, ClassB.class);
startActivityForResult(intent, "STRING");

Class B, this class is a TabActivity:

Intent intent = new Intent(this, ClassC.class);
tabHost.addTab...

Class C, this class is a regular Activity:

Intent intent = this.getIntent();
intent.putExtra("SOMETHING", "EXTRAS");
this.setResult(RESULT_OK, intent);
finish();

onActivityResult is called in Class A, but the resultCode is RESULT_CANCELED instead of RESULT_OK and the returned intent is null. How do I return something from the Activity inside a TabHost?

I realize that the problem is that my Class C is actually running inside of Class B, and Class B is what is returning the RESULT_CANCELED back to Class A. I just don't know a work around yet.

MiguelHincapieC
5,5318 gold badges44 silver badges74 bronze badges
asked Mar 23, 2010 at 2:32

5 Answers 5

367

Oh, god! After spending several hours and downloading the Android sources, I have finally come to a solution.

If you look at the Activity class, you will see, that finish() method only sends back the result if there is a mParent property set to null. Otherwise the result is lost.

public void finish() {
 if (mParent == null) {
 int resultCode;
 Intent resultData;
 synchronized (this) {
 resultCode = mResultCode;
 resultData = mResultData;
 }
 if (Config.LOGV) Log.v(TAG, "Finishing self: token=" + mToken);
 try {
 if (ActivityManagerNative.getDefault()
 .finishActivity(mToken, resultCode, resultData)) {
 mFinished = true;
 }
 } catch (RemoteException e) {
 // Empty
 }
 } else {
 mParent.finishFromChild(this);
 }
}

So my solution is to set result to the parent activity if present, like that:

Intent data = new Intent();
 [...]
if (getParent() == null) {
 setResult(Activity.RESULT_OK, data);
} else {
 getParent().setResult(Activity.RESULT_OK, data);
}
finish();

I hope that will be helpful if someone looks for this problem workaround again.

Artem Russakovskii
22.1k18 gold badges98 silver badges120 bronze badges
answered Apr 12, 2010 at 10:46
Sign up to request clarification or add additional context in comments.

4 Comments

I posted a hacky solution here, its simple and involves a transparent activity with no contents - it gets normal lifecycle functions and makes everything easier. stackoverflow.com/questions/7812120/…
I used your solution, still my code is not catching the onactivityresult method when coming back. please help me.. do i need to use any thing else?
Why is returning a result in an Activity not documented anywhere in the API guides, struck me as odd.
thank you for your awesome job, just one thing, I wanna use this method in my onBackPressed override method too, but I Can't, do you know why? I cant use finish() in onBack and when I don't use its data and result code will be null in the A activity, do you know how can I Do such thing?
64

http://tylenoly.wordpress.com/2010/10/27/how-to-finish-activity-with-results/

With a slight modification for "param_result"

/* Start Activity */
public void onClick(View v) {
 Intent intent = new Intent(Intent.ACTION_VIEW);
 intent.setClassName("com.thinoo.ActivityTest", "com.thinoo.ActivityTest.NewActivity");
 startActivityForResult(intent,90);
}
/* Called when the second activity's finished */
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 switch(requestCode) {
 case 90:
 if (resultCode == RESULT_OK) {
 Bundle res = data.getExtras();
 String result = res.getString("param_result");
 Log.d("FIRST", "result:"+result);
 }
 break;
 }
}
private void finishWithResult()
{
 Bundle conData = new Bundle();
 conData.putString("param_result", "Thanks Thanks");
 Intent intent = new Intent();
 intent.putExtras(conData);
 setResult(RESULT_OK, intent);
 finish();
}
answered Aug 14, 2013 at 14:36

1 Comment

Simple, setResult was the main thing. Set it to something, or a value for example RESULT_OK and you are good to go; setResult(RESULT_OK);. Helped me, +1
16

Intent.FLAG_ACTIVITY_FORWARD_RESULT?

If set and this intent is being used to launch a new activity from an existing one, then the reply target of the existing activity will be transfered to the new activity.

answered Jul 13, 2011 at 0:10

Comments

1

You could implement a onActivityResult in Class B as well and launch Class C using startActivityForResult. Once you get the result in Class B then set the result there (for Class A) based on the result from Class C. I haven't tried this out but I think this should work.

Another thing to look out for is that Activity A should not be a singleInstance activity. For startActivityForResult to work your Class B needs to be a sub activity to Activity A and that is not possible in a single instance activity, the new Activity (Class B) starts in a new task.

answered Mar 23, 2010 at 6:57

1 Comment

Since Class B is a TabActivity and Class C is a Tab in that activity you cannot do a startActivityForResult in Class B. None of my activities are Single Instance Activities.
-1

For start Activity 2 from Activity 1 and get result, you could use startActivityForResult and implement onActivityResult in Activity 1 and use setResult in Activity2.

Intent intent = new Intent(this, Activity2.class);
intent.putExtra(NUMERO1, numero1);
intent.putExtra(NUMERO2, numero2);
//startActivity(intent);
startActivityForResult(intent, MI_REQUEST_CODE);
Sufian Latif
13.4k3 gold badges37 silver badges71 bronze badges
answered Jul 31, 2015 at 16:12

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.