TabHostアクティビティから結果(startActivityForResult)を返す方法は?


275

私の例では3つのクラスがあります。クラスA、メインアクティビティです。クラスAがstartActivityForResultを呼び出します。

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

クラスB、このクラスはTabActivityです。

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

クラスC、このクラスは通常のアクティビティです:

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

onActivityResultはクラスAで呼び出されますが、resultCodeはRESULT_CANCELED代わりにRESULT_OK返され、返されるインテントはnullです。TabHost内のアクティビティから何かを返すにはどうすればよいですか?

私の問題は、私のクラスCが実際にクラスBの内部で実行されていること、そしてクラスBがRESULT_CANCELEDクラスAに戻るものであることに気づきました。

回答:


366

ああ、神様!数時間かけてAndroidソースをダウンロードした後、ようやく解決策を見つけました。

Activityクラスを見るfinish()と、mParentプロパティがに設定されている場合にのみ、そのメソッドが結果を返すことがわかりますnull。そうでない場合、結果は失われます。

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);
    }
}

したがって、私の解決策は、存在する場合、結果を親アクティビティに設定することです。

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

誰かがこの問題の回避策をもう一度探した場合に役立つことを願っています。


1
私はここにハックソリューションを投稿しました。シンプルで、コンテンツのない透明なアクティビティを伴います。通常のライフサイクル機能を取得し、すべてを簡単にします。stackoverflow.com/questions/7812120/...
CQM

すごい!ありがとう、ありがとう、ありがとう!それは完璧に機能し、大騒ぎはほとんどありません。この小さな宝石を使用して、すべてのアクティビティーの通常のsetResult()メソッドをオーバーライドしました。ありがとうございました!
Scott Biggs

私はあなたの解決策を使いましたが、それでも私のコードは戻ってきたときにonactivityresultメソッドをキャッチしていません。私を助けてください..他に何かを使用する必要がありますか?
skygeek

11
APIガイドのどこにも記載されていないアクティビティで結果が返されるのはなぜか奇妙な印象を受けました。
alex.p 2014年

くそー!イリヤ、よくできました!ありがとう
シレロン

64

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

"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();
}

2
シンプルsetResultなことが主なものでした。それを何か、またはたとえば値に設定すれば、問題RESULT_OKありません。setResult(RESULT_OK);。助けてくれた+1
Afzaal Ahmad Zeeshan

16

Intent.FLAG_ACTIVITY_FORWARD_RESULT?

設定され、このインテントが既存のアクティビティから新しいアクティビティを起動するために使用されている場合、既存のアクティビティの返信ターゲットは新しいアクティビティに転送されます。


1

クラスBにもonActivityResultを実装し、startActivityForResultを使用してクラスCを起動できます。クラスBで結果を取得したら、クラスCの結果に基づいてそこに結果を設定します(クラスAの場合)。私はこれを試していませんが、うまくいくと思います。

もう1つの注意点は、アクティビティAがsingleInstanceアクティビティであってはならないことです。startActivityForResultが機能するためには、クラスBがアクティビティAのサブアクティビティである必要があり、これは単一インスタンスアクティビティでは不可能です。新しいアクティビティ(クラスB)が新しいタスクで開始されます。


1
クラスBはTabActivityであり、クラスCはそのアクティビティのタブであるため、クラスBでstartActivityForResultを実行することはできません。私のアクティビティはいずれもシングルインスタンスアクティビティではありません。
キャメロンマクブライド

-1

アクティビティ1からアクティビティ2を開始して結果を取得するには、アクティビティ1にstartActivityForResultを使用してonActivityResultを実装し、アクティビティ2にsetResultを使用します。

Intent intent = new Intent(this, Activity2.class);
intent.putExtra(NUMERO1, numero1);
intent.putExtra(NUMERO2, numero2);
//startActivity(intent);
startActivityForResult(intent, MI_REQUEST_CODE);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.