Die Aktivität, die dieses Fragment hostet, wird onActivityResult
aufgerufen, wenn die Kameraaktivität zurückkehrt.
Mein Fragment startet eine Aktivität für ein Ergebnis mit der Absicht, dass die Kamera ein Bild aufnehmen soll. Die Bildanwendung wird einwandfrei geladen, nimmt ein Bild auf und kehrt zurück. Das wird onActivityResult
aber nie getroffen. Ich habe Haltepunkte gesetzt, aber nichts wird ausgelöst. Kann ein Fragment haben onActivityResult
? Ich würde es mir vorstellen, da es sich um eine bereitgestellte Funktion handelt. Warum wird das nicht ausgelöst?
ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, 1888);
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if( requestCode == 1888 ) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
}
}
requestCode >= 0
!Antworten:
Die Hosting-Aktivität wird überschrieben
onActivityResult()
, es wurden jedoch keine nichtsuper.onActivityResult()
behandelten Ergebniscodes aufgerufen. Obwohl das Fragment dasjenige ist, das denstartActivityForResult()
Anruf tätigt, erhält die Aktivität anscheinend den ersten Versuch, das Ergebnis zu verarbeiten. Dies ist sinnvoll, wenn Sie die Modularität von Fragmenten berücksichtigen. Nachdem ichsuper.onActivityResult()
alle nicht behandelten Ergebnisse implementiert hatte , konnte das Fragment das Ergebnis verarbeiten.Und auch von @siqing Antwort:
Um das Ergebnis in Ihrem Fragment zu erhalten, rufen Sie
startActivityForResult(intent,111);
stattgetActivity().startActivityForResult(intent,111);
in Ihrem Fragment auf.quelle
getParentFragment().startActivityForResult
untergeordnete Fragment aufgerufen werden sollte, damit für das übergeordnete Fragment die Methode onActivityResult aufgerufen wird.Ich glaube du hast angerufen
getActivity().startActivityForResult(intent,111);
. Sie sollten anrufenstartActivityForResult(intent,111);
.quelle
RingtonePreference
inPreferenceFragment
. LeiderRingtonePreference
AnrufegetActivity().startActivityForResult()
, und ich habe keine Ergebnisse erhalten, obwohl ichsuper.onActivityResult
die Aktivität anrufeonActivityResult
. Ich war gezwungen, eine abgeleiteteRingtonePreference
Klasse zu erstellen , die sich an diePreferenceFragment
und-Aufrufe bindetfragment.startActivityForResult()
.Option 1:
Wenn Sie
startActivityForResult()
vom Fragment aus aufrufenstartActivityForResult()
, sollten Sie nicht aufrufengetActivity().startActivityForResult()
, da dies zu einem Fragment onActivityResult () führt.Wenn Sie nicht sicher sind, wo Sie anrufen
startActivityForResult()
und wie Sie Methoden aufrufen.Option 2:
Da Aktivität das Ergebnis von erhält
onActivityResult()
, müssen Sie die Aktivität überschreibenonActivityResult()
und aufrufensuper.onActivityResult()
, um sie für nicht behandelte Ergebniscodes oder für alle an das jeweilige Fragment weiterzugeben.Wenn die beiden oben genannten Optionen nicht funktionieren, beziehen Sie sich auf Option 3, da dies definitiv funktioniert.
Option 3:
Ein expliziter Aufruf des Fragments an die Funktion onActivityResult lautet wie folgt.
Überschreiben Sie in der übergeordneten Activity-Klasse die onActivityResult () -Methode und überschreiben Sie sie sogar in der Fragment-Klasse und rufen Sie den folgenden Code auf.
In der Elternklasse:
In der Kinderklasse:
quelle
setResult(); finish();
wenn ich von der zweiten Aktivität zurückdrücke,onActivityResult
wird es auch mit bereitgestelltRESULT_CODE
.onActivityResult()
der Aktivität gibt eine seltsame zurück,requestCode
die an mein Fragment übergeben und dann ignoriert wird = /Falls Sie keine Fragmente in Ihrer Aktivität kennen, listen Sie sie einfach alle auf und senden Sie Aktivitätsergebnisargumente:
quelle
Ich habe das gleiche Problem mit dem
ChildFragmentManager
. Der Manager übergibt das Ergebnis nicht an das verschachtelte Fragment. Sie müssen dies manuell in Ihrem Basisfragment tun.quelle
Fragment fragment = myChildFragment;
ersetzen Sie die obigefindFragmentByTag
Codezeile mit. Der Rest kann unverändert bleiben.Ursprünglicher Beitrag.
FragmentActivity
wirdrequestCode
durch einen modifizierten ersetzt. Wenn danachonActivityResult()
aufgerufen wird, werdenFragmentActivity
die höheren 16 Bits analysiert und der Index des ursprünglichen Fragments wiederhergestellt. Schauen Sie sich dieses Schema an:Wenn Sie einige Fragmente auf der Stammebene haben, gibt es keine Probleme. Wenn Sie jedoch verschachtelte Fragmente haben , z. B.
Fragment
mit ein paar RegisterkartenViewPager
, werden Sie garantiert mit einem Problem konfrontiert (oder haben es bereits konfrontiert).Weil nur ein Index darin gespeichert ist
requestCode
. Das ist der Index vonFragment
innenFragmentManager
. Wenn wir verschachtelte Fragmente verwenden, gibt es untergeordnete Fragmente,FragmentManager
die eine eigene Liste von Fragmenten haben. Es ist also notwendig, die gesamte Indexkette beginnend mit root zu speichernFragmentManager
.Wie lösen wir dieses Problem? In diesem Beitrag gibt es eine allgemeine Problemumgehungslösung .
GitHub: https://github.com/shamanland/nested-fragment-issue
quelle
Dies ist eines der beliebtesten Themen. Wir können viele Threads zu diesem Thema finden. Aber keiner von ihnen ist nützlich für MICH.
Also habe ich dieses Problem mit dieser Lösung gelöst.
Lassen Sie uns zunächst verstehen, warum dies geschieht.
Wir können
startActivityForResult
direkt von Fragment aus anrufen, aber tatsächlich werden alle Mechaniker von Activity übernommen.Sobald Sie
startActivityForResult
von einem Fragment aus aufrufen , wird requestCode geändert, um die Identität des Fragments an den Code anzuhängen. Auf diese Weise kann Activity nachverfolgen, wer diese Anforderung gesendet hat, sobald das Ergebnis empfangen wurde.Sobald die Aktivität zurück navigiert wurde, wird das Ergebnis mit dem geänderten requestCode an onActivityResult von Activity gesendet, der in die ursprüngliche Identität von requestCode + Fragment dekodiert wird. Danach sendet Activity das Aktivitätsergebnis über onActivityResult an dieses Fragment. Und es ist alles erledigt.
Das Problem ist:
Aktivität kann das Ergebnis nur an das Fragment senden, das direkt an Aktivität angehängt wurde, nicht jedoch an das verschachtelte. Dies ist der Grund, warum onActivityResult eines verschachtelten Fragments niemals aufgerufen wurde, egal was passiert.
Lösung:
1) Starten Sie Intent in Ihrem Fragment mit dem folgenden Code:
2) Überschreiben Sie jetzt in Ihrer Elternaktivität **
onActivityResult()
: **Sie müssen dies in der übergeordneten Aktivität aufrufen, damit es funktioniert.
3) In Ihrem Fragmentaufruf:
Das ist es. Mit dieser Lösung kann sie für jedes einzelne Fragment angewendet werden, unabhängig davon, ob es verschachtelt ist oder nicht. Und ja, es deckt auch den ganzen Fall ab! Darüber hinaus sind die Codes auch schön und sauber.
quelle
FÜR VIELE NESTED FRAGMENTS (zum Beispiel bei Verwendung eines ViewPagers in einem Fragment)
In Ihrer Haupttätigkeit :
In Ihrem Fragment:
In Ihrem verschachtelten Fragment
Aktivität anrufen
uniqueInstanceInt - Ersetzen Sie es durch ein int, das unter den verschachtelten Fragmenten eindeutig ist, um zu verhindern, dass ein anderes Fragment die Antwort behandelt.
Antwort erhalten
Beachtung
In uniqueInstanceInt muss eine Zahl zwischen 0 und 65536 verwendet werden, um Fehler zu vermeiden. "Kann nur niedrigere 16 Bit für requestCode verwenden."
quelle
Ich kann zwei Ratschläge hinzufügen, wenn jemand es immer noch nicht schafft. Stellen Sie in der Datei Manifest.xml sicher, dass die Hosting-Aktivität beim Rückruf nicht beendet wurde und die zu startende Aktivität standardmäßig den Startmodus hat. Siehe Details wie folgt:
Setzen Sie für die Hosting-Aktivität die Eigenschaft no history auf false, falls vorhanden
Stellen Sie zum Starten der Aktivität den Startmodus als Standard ein, falls vorhanden
quelle
Ich hatte auch das gleiche Problem, als ich diesen Codeblock außerhalb eines Fragments in eine Utility-Klasse verschoben habe ,
parentActivity
die als Argument übergeben wurde.Dann bekam ich keinen Wert in der
onActivityResult
Methode dieses Fragments . Danach änderte ich das Argument in Fragment , sodass die überarbeitete Definition der Methode so aussah:Danach konnte ich Wert
onActivityResult
auf das Fragment legenquelle
Ich habe dieses Problem auch in einem Fragment getroffen. Und ich rief
startActivityForResult
einDialogFragment
.Aber jetzt ist dieses Problem behoben :
FragmentClassname.this.startActivityForResult
.quelle
startActivityForResult(...)
aus einer abstrakten Klasse im Code des Fragments aufgerufen habe.FÜR NESTED FRAGMENTS (zum Beispiel bei Verwendung eines ViewPagers)
In Ihrer Haupttätigkeit:
In Ihrem Hauptfragment der obersten Ebene (ViewPager-Fragment):
In YourFragment (verschachteltes Fragment):
quelle
In meinem Fall war es ein Android - Bug ( http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/ ), wenn Sie unterstützt verwenden
FragmentActivity
müssen Sie verwendengetSupportFragmentManager
stattgetChildFragmentManager
:quelle
Zusamenfassend,
In Fragment deklarieren
Fragment fragment = this
;nach diesem Gebrauch
fragment.startActivityForResult
.Das Ergebnis wird in activityResult zurückgegeben.
quelle
Lösung 1:
Anruf
startActivityForResult(intent, REQUEST_CODE);
stattgetActivity().startActivityForResult(intent, REQUEST_CODE);
.Lösung 2:
Wenn
startActivityForResult(intent, REQUEST_CODE);
aufgerufen wird, wird die AktivitätonActivityResult(requestCode,resultcode,intent)
aufgerufen, und dann können Siefragments onActivityResult()
von hier aus anrufen und die übergebenrequestCode, resultCode and intent
.quelle
Rufen Sie in Ihrem Fragment an
wo
this
bezieht sich auf das Fragment. Andernfalls tun Sie, was @Clevester sagte:Ich musste auch anrufen
in der übergeordneten Aktivität
onActivityResult
, damit es funktioniert.(Ich habe diese Antwort aus der Antwort von @ Clevester übernommen.)
quelle
Für diejenigen, die Android Navigation Component verwenden, sollten Sie in Activity's
onActivityResult(...)
dieprimaryNavigationFragment
Fragmentreferenz abrufen und Fragmente aufrufenfragment.onActivityResult(...)
.Hier ist Aktivität
onActivityResult(...)
quelle
Die meisten dieser Antworten besagen immer wieder, dass Sie
super.onActivityResult(...)
Ihren GastgeberActivity
für Ihre anrufen müssenFragment
. Aber das schien für mich nicht zu funktionieren.Also sollten Sie in Ihrem Host stattdessen
Activity
Ihren anrufenFragments
onActivityResult(...)
. Hier ist ein Beispiel.Irgendwann in Ihrem müssen
HostActivity
Sie das zuweisen,this.myFragment
dasFragment
Sie verwenden. Oder verwenden Sie dasFragmentManager
, um das zu erhalten,Fragment
anstatt einen Verweis darauf in Ihrem zu behaltenHostActivity
. Überprüfennull
Sie auch, bevor Sie versuchen, das anzurufenthis.myFragment.onActivityResult(...);
.quelle
quelle
Sie können BaseActivity
onActivityResult
für Fragment einfach überschreibenbaseActivity.startActivityForResult
.Fügen Sie in BaseActivity die Schnittstelle hinzu und überschreiben Sie onActivityResult.
Auf Fragment implementiert
OnBaseActivityResult
Diese Problemumgehung reicht aus.
quelle
Wenn das oben genannte Problem bei der Facebook-Anmeldung auftritt , können Sie den folgenden Code in einer übergeordneten Aktivität Ihres Fragments verwenden, z.
Oder:
Und fügen Sie den folgenden Aufruf in Ihr Fragment ein ...
quelle
Ein weiterer Anwendungsfall, der in anderen Antworten noch nicht beschrieben wurde:
onActivityResult()
In Fragment deklariert wird nicht aufgerufen, wennexception.startResolutionForResult()
:In diesem Fall durch
exception.startResolutionForResult()
Fragmente ersetzenstartIntentSenderForResult()
:quelle
Kotlin-Version (In Ihrer Aktivität onActivityResult ())
quelle
Wie Ollie C erwähnt hat, gibt es einen aktiven Fehler für die Unterstützungsbibliothek, der zurückgegebene Werte für onActivityResult verwendet, wenn Sie verschachtelte Fragmente verwenden. Ich habe es gerade getroffen :-(.
Siehe Fragment.onActivityResult wird nicht aufgerufen, wenn requestCode! = 0 ist .
quelle
Ich habe den starken Verdacht, dass alle Antworten hier nichts anderes als Hacks sind. Ich habe sie alle und viele andere ausprobiert, aber ohne verlässliche Schlussfolgerung, da es immer ein dummes Problem gibt. Ich kann mich nicht auf inkonsistente Ergebnisse verlassen. Wenn Sie sich die offizielle Android-API-Dokumentation für Fragmente ansehen, sehen Sie, dass Google Folgendes klar angibt:
Siehe: Android Fragment API
Es scheint also, dass der korrekteste und zuverlässigste Ansatz darin besteht, startActivityForResult () von der Hosting-Aktivität aus aufzurufen und von dort aus auch das resultierende onActivityResult () zu verarbeiten.
quelle
mActivity.startActivityFromFragment(this, intent, requestCode)
- also nichts anderes als ein Convenience-WrapperIhr Code hat ein verschachteltes Fragment. Das Aufrufen von super.onActivityForResult funktioniert nicht
Sie möchten nicht jede Aktivität ändern, von der aus Ihr Fragment aufgerufen werden kann, und nicht jedes Fragment in der Fragmentkette aufrufen.
Hier ist eine von vielen Arbeitslösungen. Erstellen Sie ein Fragment im laufenden Betrieb und verbinden Sie es direkt mit der Aktivität mit dem Support-Fragment-Manager. Rufen Sie dann startActivityForResult aus dem neu erstellten Fragment auf.
quelle
Mein Problem war mit der Host-Aktivität. Ich habe sie mit einem Set gefunden.
android:launchMode="standard"
Ich habe sie vorübergehend entfernt und es funktioniert!quelle
onActivityResult funktioniert nicht, wenn Ihr Startmodus auf SingleInstance oder SingleTask eingestellt ist. oder Sie rufen Ihre Aktivität mit diesen IntentFiltern auf
standard
odersingleTop
Startmodus wird gut funktionieren.quelle
Wenn Sie verschachtelte Fragmente verwenden, funktioniert dies auch:
Darüber hinaus müssen Sie
super.onActivityResult
von der übergeordneten Aktivität aus aufrufen und dieonActivityResult
Methode des Fragments ausfüllen .quelle
Ich habe das Problem behoben, indem ich eine Basisklasse geschrieben habe, die sich erweitert
Fragment
, und inonactivityresult
der Aktivität habe ich das aktuell ausgeführte Fragment mithilfe von identifiziertfragmenttag
. Dann rufe ich eine benutzerdefinierte Methode in der Fragmentbase-Klasse auf. Dadurch wird ein Ereignis im aktuell ausgeführten Fragment ausgelöst.quelle