Wie kann ein Ergebnis (startActivityForResult) aus einer TabHost-Aktivität zurückgegeben werden?

275

Ich habe 3 Klassen in meinem Beispiel: Klasse A, die Hauptaktivität. Klasse A ruft ein startActivityForResult auf:

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

Klasse B, diese Klasse ist eine TabActivity:

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

Klasse C, diese Klasse ist eine reguläre Aktivität:

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

onActivityResult wird in Klasse A aufgerufen, aber der resultCode ist RESULT_CANCELEDanstelle von RESULT_OKund die zurückgegebene Absicht ist null. Wie kann ich etwas aus der Aktivität in einem TabHost zurückgeben?

Mir ist klar, dass das Problem darin besteht, dass meine Klasse C tatsächlich innerhalb der Klasse B läuft, und Klasse B ist das, was den RESULT_CANCELEDRücken zur Klasse A zurückbringt. Ich kenne nur noch keine Lösung.

Cameron McBride
quelle

Antworten:

366

Oh Gott! Nachdem ich einige Stunden damit verbracht habe, die Android-Quellen herunterzuladen, bin ich endlich zu einer Lösung gekommen.

Wenn Sie sich die Activity-Klasse ansehen, werden Sie sehen, dass diese finish()Methode das Ergebnis nur zurücksendet, wenn eine mParentEigenschaft auf festgelegt ist null. Andernfalls geht das Ergebnis verloren.

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

Meine Lösung besteht also darin, das Ergebnis auf die übergeordnete Aktivität zu setzen, falls vorhanden:

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

Ich hoffe, dass dies hilfreich ist, wenn jemand erneut nach dieser Problemumgehung sucht.

Ilya Taranov
quelle
1
Ich habe hier eine hackige Lösung veröffentlicht, die einfach ist und eine transparente Aktivität ohne Inhalt beinhaltet - sie erhält normale Lebenszyklusfunktionen und macht alles einfacher. stackoverflow.com/questions/7812120/…
CQM
Das ist großartig! Danke danke danke! Es funktioniert perfekt und mit sehr wenig Aufwand. Ich habe die regulären setResult () -Methoden für alle meine Aktivitäten mit diesem kleinen Juwel überschrieben. Danke dir!
Scott Biggs
Ich habe Ihre Lösung verwendet, aber mein Code fängt die Onaktivitätsergebnismethode bei der Rückkehr nicht ab. Bitte helfen Sie mir. Muss ich noch etwas verwenden?
Skygeek
11
Warum ein Ergebnis in einer Aktivität zurückgegeben wird, die nirgendwo in den API-Handbüchern dokumentiert ist, kam mir seltsam vor.
Alex.p
Verdammt! Gute Arbeit, Illya! Danke
Sirelon
64

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

Mit einer geringfügigen Änderung für "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();
}
Dave S.
quelle
2
Einfach, setResultwar die Hauptsache. Setzen Sie es auf etwas oder einen Wert zum Beispiel RESULT_OKund Sie können loslegen. setResult(RESULT_OK);. Hat mir geholfen, +1
Afzaal Ahmad Zeeshan
16

Intent.FLAG_ACTIVITY_FORWARD_RESULT?

Wenn festgelegt und diese Absicht verwendet wird, um eine neue Aktivität von einer vorhandenen Aktivität aus zu starten, wird das Antwortziel der vorhandenen Aktivität auf die neue Aktivität übertragen.

nur Gedankenarbeiten
quelle
1

Sie können ein onActivityResult auch in Klasse B implementieren und Klasse C mit startActivityForResult starten. Sobald Sie das Ergebnis in Klasse B erhalten haben, setzen Sie das Ergebnis dort (für Klasse A) basierend auf dem Ergebnis aus Klasse C. Ich habe es nicht ausprobiert, aber ich denke, das sollte funktionieren.

Eine andere Sache, auf die Sie achten sollten, ist, dass Aktivität A keine Einzelinstanzaktivität sein sollte. Damit startActivityForResult funktioniert, muss Ihre Klasse B eine Unteraktivität zu Aktivität A sein. Dies ist in einer einzelnen Instanzaktivität nicht möglich. Die neue Aktivität (Klasse B) wird in einer neuen Aufgabe gestartet.

Prashast
quelle
1
Da Klasse B eine TabAktivität und Klasse C eine Registerkarte in dieser Aktivität ist, können Sie in Klasse B kein startActivityForResult ausführen. Keine meiner Aktivitäten sind Einzelinstanzaktivitäten.
Cameron McBride
-1

Um Aktivität 2 von Aktivität 1 aus zu starten und das Ergebnis zu erhalten, können Sie startActivityForResult verwenden und onActivityResult in Aktivität 1 implementieren und setResult in Aktivität 2 verwenden.

Intent intent = new Intent(this, Activity2.class);
intent.putExtra(NUMERO1, numero1);
intent.putExtra(NUMERO2, numero2);
//startActivity(intent);
startActivityForResult(intent, MI_REQUEST_CODE);
App-SoftwareFactory
quelle