onActivityResult wird in Fragment nicht aufgerufen

877

Die Aktivität, die dieses Fragment hostet, wird onActivityResultaufgerufen, 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 onActivityResultaber 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);
    }
}
Spidy
quelle
2
Überprüfen Sie diesen Beitrag, es gibt eine Problembeschreibung und eine allgemeine Problemumgehungslösung
Oleksii K.
5
Jeder andere, der dies liest, stellt sicher, dass Sie bestehen requestCode >= 0!
Muhammad Babar
3
Stellen Sie außerdem sicher, dass Ihr Activity LauchMode nicht singleInstance oder singleTask sein darf. Andernfalls wird onActivityResult nicht aufgerufen
Jawad Zeb
Siehe diesen Link kann Ihnen helfen: androidtutorialonline.com/onactivityresult-in-fragment
Android Tutorial
Wir müssen das onActivityResult in der Aktivität auf das Fragment umleiten. Siehe diesen Link: codexpedia.com/android/…
Reejesh PK

Antworten:

1239

Die Hosting-Aktivität wird überschrieben onActivityResult(), es wurden jedoch keine nicht super.onActivityResult()behandelten Ergebniscodes aufgerufen. Obwohl das Fragment dasjenige ist, das den startActivityForResult()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 ich super.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);statt getActivity().startActivityForResult(intent,111);in Ihrem Fragment auf.

Spidy
quelle
34
Rufen Sie im onActivityResult Ihrer Aktivität super.onActivityResult ()
Spidy
167
@StErMi Stellen Sie sicher, dass Sie startActivityForResult () und nicht getActivity (). StartActivityForResult () aus Ihrem Fragment aufrufen. Siehe Antwort unten.
OferR
8
Es scheint einen verwandten Fehler zu geben, bei dem die Support-Bibliothek verwendet wird. Code.google.com/p/android/issues/detail?id=15394
Ollie C
82
Beachten Sie außerdem, dass bei Verwendung verschachtelter Fragmente das getParentFragment().startActivityForResultuntergeordnete Fragment aufgerufen werden sollte, damit für das übergeordnete Fragment die Methode onActivityResult aufgerufen wird.
Eric Brynsvold
7
@EricBrynsvold hatte recht, startActivityForResult funktioniert nicht in verschachtelten Fragmenten. Rufen Sie dazu besser getParentFragment (). StartActivityForResult () auf. In diesem übergeordneten Fragment können Sie onActivityResult () implementieren und in dieser Methode das Ergebnis an das untergeordnete Fragment senden, dh: childFragment.getParentFragment (). onActivityResult (requestCode, resultCode, data)
edrian
328

Ich glaube du hast angerufen getActivity().startActivityForResult(intent,111);. Sie sollten anrufen startActivityForResult(intent,111);.

siqing
quelle
3
Ich hatte auch das gleiche Problem mit RingtonePreferencein PreferenceFragment. Leider RingtonePreferenceAnrufe getActivity().startActivityForResult(), und ich habe keine Ergebnisse erhalten, obwohl ich super.onActivityResultdie Aktivität anrufe onActivityResult. Ich war gezwungen, eine abgeleitete RingtonePreferenceKlasse zu erstellen , die sich an die PreferenceFragmentund-Aufrufe bindet fragment.startActivityForResult().
Stan
@siqing Ich kann startActivitForResult von meiner statischen Methode nicht aufrufen. Irgendeine Lösung dafür? Ich muss activity.startActivityForResult verwenden. Bitte helfen Sie mir dabei
Shreyash Mahajan
270

Option 1:

Wenn Sie startActivityForResult()vom Fragment aus aufrufen startActivityForResult(), sollten Sie nicht aufrufen getActivity().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 überschreiben onActivityResult()und aufrufen super.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:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
}

In der Kinderklasse:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}
Vinayak
quelle
4
Das hat bei mir funktioniert. Es ist eine böse Problemumgehung, aber ich habe keine bessere Idee, um diesen idiotischen Fehler zu lösen ...
Bogdan Zurac
@ Vivky, deine Antwort hat bei mir funktioniert. Aber es gibt noch ein weiteres Problem, mit dem ich konfrontiert bin, anstatt setResult(); finish();wenn ich von der zweiten Aktivität zurückdrücke, onActivityResultwird es auch mit bereitgestellt RESULT_CODE.
snehal_penurkar
hervorragende Antwort. Ich habe die dritte Lösung implementiert, um dies zu erreichen.
Sash_KP
Ich denke, die Lösung 3 würde für mich funktionieren, aber die onActivityResult()der Aktivität gibt eine seltsame zurück, requestCodedie an mein Fragment übergeben und dann ignoriert wird = /
E-Kami
1
@notGeek Du bist richtig. Das Ergebnis wird in Aktivität immer empfangen, obwohl Sie von einem Fragment oder einer Aktivität aufgerufen haben.
Vinayak
83

Falls Sie keine Fragmente in Ihrer Aktivität kennen, listen Sie sie einfach alle auf und senden Sie Aktivitätsergebnisargumente:

// In your activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    for (Fragment fragment : getSupportFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}
ruX
quelle
3
Verdammt, ich dachte, ich hätte gerade die einfachste Lösung gefunden, aber es gibt keine Methode wie getFragments ().
WindRider
2
@ WindRider gibt es. Wenn Sie die Android-Unterstützungsbibliothek (AppCompat) verwenden.
Dasar
2
Außerdem habe ich auf die harte Tour gelernt, dass man überprüfen muss, ob das Fragment im Array kein Verweis auf sich selbst ist! `if (fragment! = this) {fragment.onActivityResult (requestCode, resultCode, data); `
Rubenjohn
Dies funktioniert nicht, wenn die Fragmente verschachtelt sind, da nur das oberste Fragment in der Liste enthalten ist. Ich glaube, dass super.onActivityResult () bereits onActivityResult () für alle Fragmente in der Liste aufruft, daher ist diese Idee überflüssig.
BeccaP
83

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.

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
    if (fragment != null) {
        fragment.onActivityResult(requestCode, resultCode, intent);
    }
}
MinceMan
quelle
1
Wenn Sie Ihr untergeordnetes Fragment als privates Mitglied haben, Fragment fragment = myChildFragment;ersetzen Sie die obige findFragmentByTagCodezeile mit. Der Rest kann unverändert bleiben.
lcn
7
Ich würde dringend empfehlen, ein Fragment nicht als privates Mitglied zu behalten. Sie haben ihren eigenen Lebenszyklus, sodass Sie nie wissen, ob sie in einem guten Zustand sind, mit dem sie interagieren können. Außerdem sind sie ziemlich heftig und ich würde mir Sorgen um Speicherlecks machen. Der Manager wäre nicht erstellt worden, wenn Sie ihn nicht verwenden müssten.
MinceMan
67

Ursprünglicher Beitrag.

FragmentActivitywird requestCodedurch einen modifizierten ersetzt. Wenn danach onActivityResult()aufgerufen wird, werden FragmentActivitydie höheren 16 Bits analysiert und der Index des ursprünglichen Fragments wiederhergestellt. Schauen Sie sich dieses Schema an:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie einige Fragmente auf der Stammebene haben, gibt es keine Probleme. Wenn Sie jedoch verschachtelte Fragmente haben , z. B. Fragmentmit ein paar Registerkarten ViewPager, werden Sie garantiert mit einem Problem konfrontiert (oder haben es bereits konfrontiert).

Weil nur ein Index darin gespeichert ist requestCode. Das ist der Index von Fragmentinnen FragmentManager. Wenn wir verschachtelte Fragmente verwenden, gibt es untergeordnete Fragmente, FragmentManagerdie eine eigene Liste von Fragmenten haben. Es ist also notwendig, die gesamte Indexkette beginnend mit root zu speichern FragmentManager.

Geben Sie hier die Bildbeschreibung ein

Wie lösen wir dieses Problem? In diesem Beitrag gibt es eine allgemeine Problemumgehungslösung .

GitHub: https://github.com/shamanland/nested-fragment-issue

Oleksii K.
quelle
Ich habe das gleiche Problem wie bei der Verwendung eines ViewPagers im übergeordneten Fragment, das andere Fragmente als Registerkarten enthält. Versucht mit dem Nested-Fragment-Problem, endete aber mit Kompilierungsfehlern. Können Sie mir die Lösung vorschlagen? Auch hier wurde ein
Problem angesprochen:
Ich antwortete auf Github, also lassen Sie uns dieses Gespräch bewegen von hier github.com/shamanland/nested-fragment-issue/issues/...
Oleksii K.
Vielen Dank! Wenn es sich nicht um eine empfohlene Lösung handelt, empfehle ich, die Antwort entsprechend zu bearbeiten, damit Sie keine Zeit damit verbringen müssen, dies zu versuchen, um zu wissen, dass es Kompilierungsfehler gibt.
cgr
44

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 startActivityForResultdirekt von Fragment aus anrufen, aber tatsächlich werden alle Mechaniker von Activity übernommen.

Sobald Sie startActivityForResultvon 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:

       /** Pass your fragment reference **/
       frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345

2) Überschreiben Sie jetzt in Ihrer Elternaktivität **onActivityResult() : **

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

Sie müssen dies in der übergeordneten Aktivität aufrufen, damit es funktioniert.

3) In Ihrem Fragmentaufruf:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {

       }
}

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.

KishuDroid
quelle
Ich habe die Systemabsicht mit 'Aktivität' angefordert, ich musste nur den Fragmentkontext verwenden.
Uzair
18

FÜR VIELE NESTED FRAGMENTS (zum Beispiel bei Verwendung eines ViewPagers in einem Fragment)

In Ihrer Haupttätigkeit :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

In Ihrem Fragment:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    for (Fragment fragment : getChildFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

In Ihrem verschachtelten Fragment

Aktivität anrufen

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

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

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == uniqueInstanceInt ) {
        // TODO your code
    }
}

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."

Luciano Marqueto
quelle
Funktioniert hervorragend in Aktivität> Fragment (ViewPager)> Fragment
Oleksandr Firsov
14

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

android:noHistory="false"

Stellen Sie zum Starten der Aktivität den Startmodus als Standard ein, falls vorhanden

android:launchMode="standard"
Jowett
quelle
13

Ich hatte auch das gleiche Problem, als ich diesen Codeblock außerhalb eines Fragments in eine Utility-Klasse verschoben habe , parentActivitydie als Argument übergeben wurde.

Intent intent = new Intent(parentActivity, CameraCaptureActivity.class);
parentActivity.startActivityForResult(intent,requestCode);

Dann bekam ich keinen Wert in der onActivityResultMethode dieses Fragments . Danach änderte ich das Argument in Fragment , sodass die überarbeitete Definition der Methode so aussah:

Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class);
fragment.startActivityForResult(intent,requestCode);

Danach konnte ich Wert onActivityResultauf das Fragment legen

Shamsul Arefin Sajib
quelle
10

Ich habe dieses Problem auch in einem Fragment getroffen. Und ich rief startActivityForResultein DialogFragment.

Aber jetzt ist dieses Problem behoben :
FragmentClassname.this.startActivityForResult .

Courysky
quelle
Großartig, hat für mich funktioniert, weil ich startActivityForResult(...)aus einer abstrakten Klasse im Code des Fragments aufgerufen habe.
Vince
9

FÜR NESTED FRAGMENTS (zum Beispiel bei Verwendung eines ViewPagers)

In Ihrer Haupttätigkeit:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

In Ihrem Hauptfragment der obersten Ebene (ViewPager-Fragment):

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    YourFragment frag = (YourFragment) getChildFragmentManager().getFragments().get(viewPager.getCurrentItem());
    frag.yourMethod(data);  // Method for callback in YourFragment
    super.onActivityResult(requestCode, resultCode, data);
}

In YourFragment (verschachteltes Fragment):

public void yourMethod(Intent data){
    // Do whatever you want with your data
}
Jyotman Singh
quelle
8

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 FragmentActivitymüssen Sie verwenden getSupportFragmentManagerstatt getChildFragmentManager:

List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
    for (Fragment fragment : fragments) {
        if(fragment instanceof UserProfileFragment) {
            fragment.onActivityResult(requestCode, resultCode, data);
        }
    }
}
Hazlo8
quelle
6

Zusamenfassend,

In Fragment deklarieren Fragment fragment = this;

nach diesem Gebrauch fragment.startActivityForResult.

Das Ergebnis wird in activityResult zurückgegeben.

Clevester
quelle
6

Lösung 1:

Anruf startActivityForResult(intent, REQUEST_CODE);statt getActivity().startActivityForResult(intent, REQUEST_CODE);.

Lösung 2:

Wenn startActivityForResult(intent, REQUEST_CODE);aufgerufen wird, wird die Aktivität onActivityResult(requestCode,resultcode,intent)aufgerufen, und dann können Sie fragments onActivityResult()von hier aus anrufen und die übergeben requestCode, resultCode and intent.

Amey Haldankar
quelle
5

Rufen Sie in Ihrem Fragment an

this.startActivityForResult(intent, REQUEST_CODE);

wo thisbezieht sich auf das Fragment. Andernfalls tun Sie, was @Clevester sagte:

Fragment fragment = this;
....
fragment.startActivityForResult(intent, REQUEST_CODE);

Ich musste auch anrufen

super.onActivityResult(requestCode, resultCode, data);

in der übergeordneten Aktivität onActivityResult, damit es funktioniert.

(Ich habe diese Antwort aus der Antwort von @ Clevester übernommen.)

Suragch
quelle
5

Für diejenigen, die Android Navigation Component verwenden, sollten Sie in Activity's onActivityResult(...)die primaryNavigationFragmentFragmentreferenz abrufen und Fragmente aufrufen fragment.onActivityResult(...).

Hier ist Aktivität onActivityResult(...)

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageData)
{
    super.onActivityResult(requestCode, resultCode, imageData);

    for (Fragment fragment : getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager().getFragments())
    {
            fragment.onActivityResult(requestCode, resultCode, imageData);
    }
}
Mohit Mehta
quelle
4

Die meisten dieser Antworten besagen immer wieder, dass Sie super.onActivityResult(...)Ihren Gastgeber Activityfür Ihre anrufen müssen Fragment. Aber das schien für mich nicht zu funktionieren.

Also sollten Sie in Ihrem Host stattdessen ActivityIhren anrufen Fragments onActivityResult(...). Hier ist ein Beispiel.

public class HostActivity extends Activity {

    private MyFragment myFragment;

    protected void onActivityResult(...) {
        super.onActivityResult(...);
        this.myFragment.onActivityResult(...);
    }
}

Irgendwann in Ihrem müssen HostActivitySie das zuweisen, this.myFragmentdas FragmentSie verwenden. Oder verwenden Sie das FragmentManager, um das zu erhalten, Fragmentanstatt einen Verweis darauf in Ihrem zu behalten HostActivity. Überprüfen nullSie auch, bevor Sie versuchen, das anzurufen this.myFragment.onActivityResult(...);.

prolink007
quelle
3
public class takeimage extends Fragment {

    private Uri mImageCaptureUri;
    private static final int PICK_FROM_CAMERA = 1;
    private static final int PICK_FROM_FILE = 2;
    private String mPath;
    private ImageView mImageView;
    Bitmap bitmap = null;
    View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_send_image, container, false);
        final String[] items = new String[] { "From Camera", "From SD Card" };
        mImageView = (ImageView)view.findViewById(R.id.iv_pic);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Select Image");

        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                if (item == 0) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File file = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_"
                        + String.valueOf(System.currentTimeMillis())
                        + ".jpg");
                    mImageCaptureUri = Uri.fromFile(file);

                    try {
                        intent.putExtra(
                            android.provider.MediaStore.EXTRA_OUTPUT,
                            mImageCaptureUri);
                        intent.putExtra("return-data", true);

                        getActivity().startActivityForResult(intent,
                            PICK_FROM_CAMERA);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    dialog.cancel();
                } else {
                    Intent intent = new Intent();

                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);

                    getActivity().startActivityForResult(
                        Intent.createChooser(intent,
                            "Complete action using"), PICK_FROM_FILE);
                }
            }
        });
        final AlertDialog dialog = builder.create();

        Button show = (Button) view.findViewById(R.id.btn_choose);
        show.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // Switch the tab content to display the list view.
                dialog.show();
            }
        });

    return view;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode != Activity.RESULT_OK)
            return;

        if (requestCode == PICK_FROM_FILE) {
            mImageCaptureUri = data.getData();
            // mPath = getRealPathFromURI(mImageCaptureUri); //from Gallery

            if (mPath == null)
                mPath = mImageCaptureUri.getPath(); // from File Manager

            if (mPath != null)
                bitmap = BitmapFactory.decodeFile(mPath);
        } else {
            mPath = mImageCaptureUri.getPath();
            bitmap = BitmapFactory.decodeFile(mPath);
        }
        mImageView.setImageBitmap(bitmap);  
    }

    public String getRealPathFromURI(Uri contentUri) {
        String [] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery(contentUri, proj, null, null,null);

        if (cursor == null) return null;

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
} 
Shakirullah Orakzai
quelle
3
  1. Sie können BaseActivity onActivityResultfür Fragment einfach überschreiben baseActivity.startActivityForResult.

  2. Fügen Sie in BaseActivity die Schnittstelle hinzu und überschreiben Sie onActivityResult.

    private OnBaseActivityResult baseActivityResult;
    public static final int BASE_RESULT_RCODE = 111;
    public interface OnBaseActivityResult{
        void onBaseActivityResult(int requestCode, int resultCode, Intent data);
       }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(getBaseActivityResult() !=null && requestCode == BASE_RESULT_RCODE){
        getBaseActivityResult().onBaseActivityResult(requestCode, resultCode, data);
        setBaseActivityResult(null);
    }
  3. Auf Fragment implementiert OnBaseActivityResult

    @Override
    public void onBaseActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("RQ","OnBaseActivityResult");
    if (data != null) {
        Log.d("RQ","OnBaseActivityResult + Data");
        Bundle arguments = data.getExtras();
      }
    }

Diese Problemumgehung reicht aus.

Khaled Lela
quelle
3

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.

Fragment fragment = getFragmentManager().findFragmentById(android.R.id.tabcontent);
fragment.onActivityResult(requestCode, resultCode, data);

Oder:

Fragment fragment = getFragmentManager().findFragmentById("fragment id here");
fragment.onActivityResult(requestCode, resultCode, data);

Und fügen Sie den folgenden Aufruf in Ihr Fragment ein ...

callbackManager.onActivityResult(requestCode, resultCode, data);
Ketan Patel
quelle
2

Ein weiterer Anwendungsfall, der in anderen Antworten noch nicht beschrieben wurde:

onActivityResult()In Fragment deklariert wird nicht aufgerufen, wenn exception.startResolutionForResult():

if (exception is ResolvableApiException) {
    exception.startResolutionForResult(activity!!, MY_REQUEST_CODE)
}

In diesem Fall durch exception.startResolutionForResult()Fragmente ersetzen startIntentSenderForResult():

if (exception is ResolvableApiException) {
    startIntentSenderForResult(exception.resolution.intentSender, MY_REQUEST_CODE, null, 0, 0, 0, null)
}
dominik
quelle
2

Kotlin-Version (In Ihrer Aktivität onActivityResult ())

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    //add following lines in your activity
    if(supportFragmentManager?.fragments!=null && supportFragmentManager?.fragments!!.size>0)
     for (i in 0..supportFragmentManager?.fragments!!.size-1) {
         val fragment= supportFragmentManager?.fragments!!.get(i)
         fragment.onActivityResult(requestCode, resultCode, data)
    }
 }
Ranjith Kumar
quelle
1

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:

Rufen Sie startActivityForResult (Intent, int) aus dem Fragment auf, das Activity enthält.

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.

Chris
quelle
2
Ich denke nicht, dass "call startActivityForResult from Activity" eine Empfehlung ist. Wenn Sie sich die Implementierung in der Fragment-Basisklasse ansehen, dann ist alles, was es tut mActivity.startActivityFromFragment(this, intent, requestCode)- also nichts anderes als ein Convenience-Wrapper
Anti Veeranna
1

Ihr 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.

private void get_UserEmail() {

    if (view == null) {
        return;
    }
    ((TextView) view.findViewById(R.id.tvApplicationUserName))
            .setText("Searching device for user accounts...");

    final FragmentManager fragManager = getActivity().getSupportFragmentManager();

    Fragment f = new Fragment() {
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            startActivityForResult(AccountPicker.newChooseAccountIntent(null, null,
                    new String[]{"com.google"}, false, null, null, null, null), REQUEST_CODE_PICK_ACCOUNT);
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                                     Intent data) {
            if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
                String mEmail = "";
                if (resultCode == Activity.RESULT_OK) {
                    if (data.hasExtra(AccountManager.KEY_ACCOUNT_NAME)) {
                        mEmail = data
                                .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                    }
                }
                if (mActivity != null) {
                    GoPreferences.putString(mActivity, SettingApplication.USER_EMAIL, mEmail);
                }
                doUser();
            }
            super.onActivityResult(requestCode, resultCode, data);
            fragManager.beginTransaction().remove(this).commit();
        }
    };
    FragmentTransaction fragmentTransaction = fragManager
            .beginTransaction();
    fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
    fragmentTransaction.commit();
}
danny117
quelle
Das funktioniert tatsächlich und ich habe nur eine Stimme dafür. Erstellen Sie ein Fragment im laufenden Betrieb. Zu einfach, aber es ist eine echte funktionierende Lösung. Jemand hat sogar versucht, es für mich zu bearbeiten.
danny117
1

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!

Chulo
quelle
1

Ein Punkt, den niemand hat mention, um sicherzustellen, dass der Startmodus Ihrer Host-Aktivität nicht auf singleInstanceoder eingestellt ist singleTask.

onActivityResult funktioniert nicht, wenn Ihr Startmodus auf SingleInstance oder SingleTask eingestellt ist. oder Sie rufen Ihre Aktivität mit diesen IntentFiltern auf

standardoder singleTopStartmodus wird gut funktionieren.

Jawad Zeb
quelle
1

Wenn Sie verschachtelte Fragmente verwenden, funktioniert dies auch:

getParentFragment().startActivityForResult(intent, RequestCode);

Darüber hinaus müssen Sie super.onActivityResultvon der übergeordneten Aktivität aus aufrufen und die onActivityResultMethode des Fragments ausfüllen .

Oguz Ozcan
quelle
1

Ich habe das Problem behoben, indem ich eine Basisklasse geschrieben habe, die sich erweitert Fragment, und in onactivityresultder Aktivität habe ich das aktuell ausgeführte Fragment mithilfe von identifiziert fragmenttag. Dann rufe ich eine benutzerdefinierte Methode in der Fragmentbase-Klasse auf. Dadurch wird ein Ereignis im aktuell ausgeführten Fragment ausgelöst.

Bytecode
quelle