onActivityResult tidak dipanggil dalam Fragmen

877

Aktivitas yang menampung fragmen ini memiliki onActivityResult disebut ketika aktivitas kamera kembali.

Fragmen saya memulai aktivitas untuk hasil dengan maksud yang dikirim agar kamera mengambil gambar. Aplikasi gambar dimuat dengan baik, mengambil gambar, dan kembali. The onActivityResultnamun tidak pernah memukul. Saya telah menetapkan breakpoint, tetapi tidak ada yang dipicu. Bisakah sebuah fragmen punya onActivityResult? Saya pikir begitu karena ini adalah fungsi yang disediakan. Mengapa ini tidak dipicu?

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);
    }
}
Rapi
sumber
2
periksa posting ini, ada deskripsi masalah dan solusi penyelesaian bersama: stackoverflow.com/questions/6147884/…
Oleksii K.
5
Siapa pun yang membaca ini pastikan Anda lulus requestCode >= 0!
Muhammad Babar
3
Pastikan juga Activity LauchMode Anda tidak boleh singleInstance atau singleTask. jika tidak onActivityResult tidak akan memanggil
Jawad Zeb
Lihat tautan ini dapat membantu Anda: androidtutorialonline.com/onactivityresult-in-fragment
Tutorial Android
Kita perlu mengarahkan onActivityResult dalam Activity to the Fragment. Rujuk tautan ini: codexpedia.com/android/…
Reejesh PK

Jawaban:

1240

Aktivitas hosting ditimpa onActivityResult(), tetapi tidak membuat panggilan ke super.onActivityResult()untuk kode hasil tidak tertangani. Rupanya, meskipun fragmen adalah yang membuat startActivityForResult()panggilan, aktivitas tersebut mendapat kesempatan pertama untuk menangani hasilnya. Ini masuk akal ketika Anda mempertimbangkan modularitas fragmen. Setelah saya laksanakansuper.onActivityResult() untuk semua hasil yang tidak tertangani, fragmen mencoba menangani hasil.

Dan juga dari jawaban @siqing:

Untuk mendapatkan hasil dalam fragmen Anda, pastikan Anda menelepon startActivityForResult(intent,111); alih-alih getActivity().startActivityForResult(intent,111);di dalam fragmen Anda.

Rapi
sumber
34
Dalam aktivitas Anda diActivityResult, hubungi super.onActivityResult ()
Spidy
167
@StErMi Pastikan Anda memanggil startActivityForResult () dan tidak getActivity (). StartActivityForResult () dari fragmen Anda. Lihat jawaban siqing di bawah ini.
OferR
8
Tampaknya ada bug terkait, di mana perpustakaan dukungan sedang digunakan code.google.com/p/android/issues/detail?id=15394
Ollie C
82
Juga perhatikan bahwa jika Anda menggunakan fragmen bersarang, fragmen anak harus memanggil getParentFragment().startActivityForResultsehingga fragmen induk akan memanggil metode onActivityResult.
Eric Brynsvold
7
@EricBrynsvold benar, startActivityForResult tidak berfungsi dalam fragmen bersarang. Untuk ini, Anda sebaiknya memanggil getParentFragment (). StartActivityForResult (), dan dalam fragmen induk itu, maka, Anda bisa mengimplementasikan onActivityResult () dan dalam metode itu mengirimkan hasilnya ke fragmen anak, yaitu: childFragment.getParentFragment (). onActivityResult (requestCode, resultCode, data)
edrian
328

Saya pikir Anda menelepon getActivity().startActivityForResult(intent,111);. Anda harus menelepon startActivityForResult(intent,111);.

siqing
sumber
3
Saya juga punya masalah yang sama dengan RingtonePreferenceterletak di PreferenceFragment. Sayangnya, RingtonePreferencepanggilan getActivity().startActivityForResult(), dan saya tidak mendapatkan hasil meskipun saya memanggil super.onActivityResultaktivitas onActivityResult. Saya terpaksa membuat turunan dari RingtonePreferencekelas, yang mengikat dirinya ke PreferenceFragmentdan panggilan fragment.startActivityForResult().
Stan
@siqing Saya tidak dapat memanggil startActivitForResult dari metode statis saya. Ada solusi untuk itu? Saya harus menggunakan activity.startActivityForResult. Tolong bantu saya dalam hal ini
Shreyash Mahajan
270

Pilihan 1:

Jika Anda menelepon startActivityForResult()dari fragmen maka Anda harus menelepon startActivityForResult(), bukangetActivity().startActivityForResult() , karena akan menghasilkan fragmen padaActivityResult ().

Jika Anda tidak yakin di mana Anda menelepon startActivityForResult()dan bagaimana Anda akan memanggil metode.

Pilihan 2:

Karena Aktivitas mendapatkan hasil onActivityResult(), Anda perlu mengganti aktivitas onActivityResult()dan panggilan super.onActivityResult()untuk menyebar ke masing-masing fragmen untuk kode hasil yang tidak ditangani atau untuk semua.

Jika dua opsi di atas tidak bekerja, maka merujuk ke opsi 3 karena pasti akan berhasil.

Opsi 3:

Panggilan eksplisit dari fragmen ke fungsi onActivityResult adalah sebagai berikut.

Di kelas induk Aktivitas, menimpa metode onActivityResult () dan bahkan menimpa yang sama di kelas Fragmen dan panggilan sebagai kode berikut.

Di kelas induk:

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

Di kelas anak:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}
Vinayak
sumber
4
Ini berhasil untuk saya. Ini solusi buruk, tapi saya tidak punya ide yang lebih baik untuk menyelesaikan bug idiot ini ...
Bogdan Zurac
@Vivky, Jawaban Anda berhasil untuk saya. Tetapi ada satu masalah lagi yang saya hadapi, alih-alih setResult(); finish();ketika saya menekan kembali dari aktivitas kedua kemudian onActivityResultdipanggil juga dengan ketentuan RESULT_CODE.
snehal_penurkar
jawaban yang luar biasa. Saya menerapkan solusi ketiga untuk menyelesaikannya.
Sash_KP
Saya pikir solusi 3 akan bekerja untuk saya tetapi onActivityResult() aktivitas mengembalikan aneh requestCodeyang diteruskan ke fragmen saya dan kemudian diabaikan = /
E-Kami
1
@ notGeek Anda benar. Hasil selalu diterima dalam Aktivitas meskipun Anda dipanggil dari fragmen atau aktivitas.
Vinayak
83

Jika Anda tidak tahu fragmen dalam aktivitas Anda, sebutkan saja semuanya dan kirim argumen hasil aktivitas:

// 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
sumber
3
Sial, saya pikir saya baru saja menemukan solusi paling sederhana, tetapi tidak ada metode seperti getFragments ().
WindRider
2
@ WindRider Ada. Jika Anda menggunakan perpustakaan dukungan Android (AppCompat).
dasar
2
Juga, saya belajar dengan cara yang sulit bahwa Anda harus memeriksa apakah fragmen dalam array bukan referensi untuk dirinya sendiri! `if (fragment! = this) {fragment.onActivityResult (requestCode, resultCode, data); `
reubenjohn
Ini tidak berfungsi jika fragmen bersarang, karena hanya fragmen teratas yang ada dalam daftar. Saya percaya bahwa super.onActivityResult () sudah memanggil onActivityResult () pada semua fragmen dalam daftar, jadi ide ini berlebihan.
BeccaP
83

Saya mengalami masalah yang sama dengan ChildFragmentManager. Manajer tidak akan meneruskan hasilnya ke fragmen bersarang, Anda harus melakukannya secara manual di fragmen dasar Anda.

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);
    }
}
Tuan Putra
sumber
1
Jika Anda memiliki Fragmen anak Anda sebagai anggota pribadi, maka gunakan Fragment fragment = myChildFragment;untuk mengganti findFragmentByTagbaris kode di atas. Sisanya bisa tidak berubah.
lcn
7
Saya kira saya akan sangat menyarankan agar tidak menyimpan fragmen sebagai anggota pribadi. Mereka memiliki siklus hidup mereka sendiri sehingga Anda tidak pernah tahu apakah mereka dalam kondisi yang baik untuk berinteraksi dengan manajer. Juga mereka cukup besar dan saya akan khawatir tentang kebocoran memori. Manajer tidak akan dibuat jika Anda tidak perlu menggunakannya.
MinceMan
67

Pos asli.

FragmentActivitydiganti requestCodedengan yang dimodifikasi. Setelah itu, ketika onActivityResult()akan dipanggil, FragmentActivityparsing 16 bit yang lebih tinggi dan mengembalikan indeks Fragmen asli. Lihatlah skema ini:

Masukkan deskripsi gambar di sini

Jika Anda memiliki beberapa fragmen di level root, tidak ada masalah. Tetapi jika Anda memiliki fragmen bersarang , misalnya Fragmentdengan beberapa tab di dalamnya ViewPager, Anda dijamin akan menghadapi masalah (atau sudah dihadapkan).

Karena hanya satu indeks yang disimpan di dalam requestCode. Itulah indeks Fragmentdi dalamnya FragmentManager. Ketika kami menggunakan fragmen bersarang, ada anak-anak FragmentManager, yang memiliki daftar Fragmen mereka sendiri. Jadi, penting untuk menyimpan seluruh rantai indeks, mulai dari root FragmentManager.

Masukkan deskripsi gambar di sini

Bagaimana kita mengatasi masalah ini? Ada solusi penyelesaian umum dalam posting ini .

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

Oleksii K.
sumber
Saya memiliki masalah yang sama seperti saya menggunakan ViewPager dalam fragmen induk yang menyimpan fragmen lain sebagai tab. Sudah mencoba menggunakan nested-fragment-issue tetapi berakhir dengan kompilasi erros. Bisakah Anda menyarankan saya solusinya? Mengangkat masalah juga di sini github.com/shamanland/nested-fragment-issue/issues/2
cgr
Saya menjawab di github, jadi mari kita pindahkan percakapan ini dari sini github.com/shamanland/nested-fragment-issue/issues/…
Oleksii K.
Terima kasih! Jika itu bukan solusi yang disarankan, saya sarankan mengedit jawaban yang sesuai sehingga orang tidak perlu menghabiskan waktu mencoba ini untuk mengetahui ia memiliki kompilasi erros.
cgr
44

Ini adalah salah satu masalah paling populer. Kami dapat menemukan banyak utas tentang masalah ini. Tetapi tidak satupun dari mereka yang berguna bagiKU.

Jadi saya telah memecahkan masalah ini menggunakan solusi ini.

Pertama mari kita pahami mengapa ini terjadi.

Kita dapat memanggil startActivityForResultlangsung dari Fragment tetapi sebenarnya mekanik di belakang semuanya ditangani oleh Activity.

Begitu Anda menelepon startActivityForResult dari Fragmen, requestCode akan diubah untuk melampirkan identitas Fragmen ke kode. Dengan begitu, Activity dapat melacak kembali siapa yang mengirim permintaan ini begitu hasilnya diterima.

Setelah Aktivitas dinavigasi kembali, hasilnya akan dikirim ke onActivityResult Activity dengan kode request yang dimodifikasi yang akan diterjemahkan ke kode requestCode asli + identitas Fragmen. Setelah itu, Aktivitas akan mengirimkan Hasil Aktivitas ke Fragmen itu melalui onActivityResult. Dan semuanya sudah selesai.

Masalahnya adalah:

Aktivitas dapat mengirim hasilnya hanya ke Fragmen yang telah dilampirkan langsung ke Aktivitas tetapi bukan yang bersarang. Itulah alasan mengapa onActivityResult fragmen bersarang tidak akan pernah dipanggil apa pun yang terjadi.

Larutan:

1) Mulai Intent di Fragmen Anda dengan kode di bawah ini:

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

2) Sekarang di Override Activity Induk Anda **onActivityResult() : **

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

Anda harus memanggil ini dalam aktivitas induk untuk membuatnya berfungsi.

3) Dalam panggilan fragmen Anda:

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

       }
}

Itu dia. Dengan solusi ini, itu bisa diterapkan untuk setiap fragmen apakah itu bersarang atau tidak. Dan ya, itu juga mencakup semua kasing! Apalagi kodenya juga bagus dan bersih.

KishuDroid
sumber
Saya meminta maksud sistem dengan 'aktivitas' saya hanya harus menggunakan konteks fragmen.
Uzair
18

UNTUK BANYAK TEMPAT YANG DIBERI BANYAK (misalnya, ketika menggunakan ViewPager dalam sebuah fragmen)

Dalam aktivitas utama Anda :

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

Dalam fragmen Anda:

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

Di fragmen bersarang Anda

Aktivitas panggilan

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

unikInstanceInt - ganti dengan int yang unik di antara fragmen bersarang untuk mencegah fragmen lain memperlakukan jawabannya.

Terima respons

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

Perhatian

Angka antara 0 dan 65536 perlu digunakan dalam uniqueInstanceInt untuk menghindari kesalahan "Hanya dapat menggunakan 16 bit lebih rendah untuk requestCode".

Luciano Marqueto
sumber
Berfungsi bagus dalam Aktivitas> Fragmen (ViewPager)> Fragmen
Oleksandr Firsov
14

Saya dapat menambahkan dua saran jika seseorang masih tidak bisa datang. Dalam file Manifest.xml, pastikan aktivitas hosting tidak selesai ketika dipanggil kembali dan aktivitas yang akan dimulai memiliki mode peluncuran sebagai standar. Lihat detailnya seperti di bawah ini:

Untuk aktivitas Hosting, tetapkan properti no history sebagai false jika ada

android:noHistory="false"

Agar Aktivitas dimulai, setel mode peluncuran sebagai standar jika ada

android:launchMode="standard"
jowett
sumber
13

Saya juga menghadapi masalah yang sama begitu saya menggeser blok kode ini di luar Fragmen ke Kelas Utilitas , dengan parentActivityditeruskan sebagai argumen ,

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

Kemudian saya tidak mendapatkan nilai apa pun dalam onActivityResultmetode Fragmen itu, Setelah itu, saya mengubah argumen menjadi Fragmen , sehingga definisi metode yang direvisi tampak seperti,

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

Setelah itu, saya bisa mendapatkan nilai onActivityResultpada Fragmen

Shamsul Arefin Sajib
sumber
10

Saya juga menemui masalah ini dalam Fragmen. Dan aku menelepon startActivityForResultdalam DialogFragment.

Tapi sekarang masalah ini telah diselesaikan:
FragmentClassname.this.startActivityForResult .

Courysky
sumber
Hebat, bekerja untuk saya, karena saya menelepon startActivityForResult(...)dari kelas abstrak di dalam kode fragmen.
Vince
9

UNTUK FRAGMENT YANG DIBERIKAN (misalnya, saat menggunakan ViewPager)

Dalam aktivitas utama Anda:

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

Di fragmen tingkat atas utama Anda (fragmen ViewPager):

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

Di YourFragment (fragmen bersarang):

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

Dalam kasus saya itu adalah bug Android ( http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/ ), jika Anda menggunakan dukungan, FragmentActivityAnda harus menggunakan getSupportFragmentManageralih-alih getChildFragmentManager:

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

Pendeknya,

Dalam fragmen, nyatakan Fragment fragment = this;

setelah itu gunakan fragment.startActivityForResult.

Hasilnya akan kembali di activityResult.

Clevester
sumber
6

Solusi 1:

Panggil startActivityForResult(intent, REQUEST_CODE);alih-alih getActivity().startActivityForResult(intent, REQUEST_CODE);.

Solusi 2:

Kapan startActivityForResult(intent, REQUEST_CODE);aktivitas onActivityResult(requestCode,resultcode,intent)dipanggil, lalu Anda dapat menelepon fragments onActivityResult()dari sini, meneruskan requestCode, resultCode and intent.

Amey Haldankar
sumber
5

Di dalam fragmen Anda, panggil

this.startActivityForResult(intent, REQUEST_CODE);

di mana thismengacu pada fragmen. Jika tidak, lakukan seperti yang dikatakan @Clevester:

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

Saya juga harus menelepon

super.onActivityResult(requestCode, resultCode, data);

dalam aktivitas induk onActivityResultuntuk membuatnya berfungsi.

(Saya mengadaptasi jawaban ini dari jawaban @ Clevester.)

Suragch
sumber
5

Bagi mereka yang menggunakan Android Komponen Navigasi harus menggunakan dalam Kegiatan ini onActivityResult(...)dalam primaryNavigationFragmentuntuk mendapatkan itu referensi fragmen dan panggilan fragmen ini fragment.onActivityResult(...).

Inilah Kegiatan 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
sumber
4

Sebagian besar jawaban ini terus mengatakan bahwa Anda harus memanggil super.onActivityResult(...)tuan rumah ActivityAnda untuk Anda Fragment. Tapi itu sepertinya tidak berhasil untukku.

Jadi, di host ActivityAnda, Anda harus memanggil Anda Fragments onActivityResult(...)sebagai gantinya. Berikut ini sebuah contoh.

public class HostActivity extends Activity {

    private MyFragment myFragment;

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

Pada titik tertentu di Anda, HostActivityAnda perlu menetapkan this.myFragmentyang FragmentAnda gunakan. Atau, gunakan FragmentManageruntuk mendapatkan Fragmentalih - alih menyimpan referensi di dalamnya HostActivity. Juga, periksa nullsebelum Anda mencoba menelepon this.myFragment.onActivityResult(...);.

prolink007
sumber
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
sumber
3
  1. Anda bisa mengesampingkan BaseActivity onActivityResultpada fragmen baseActivity.startActivityForResult.

  2. Pada BaseActivity menambahkan antarmuka dan menimpa 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. Pada implementasi Fragment 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();
      }
    }

Solusi ini akan melakukan trik.

Khaled Lela
sumber
3

Jika masalah di atas dihadapi saat login Facebook maka Anda dapat menggunakan kode di bawah ini dalam aktivitas induk dari fragmen Anda seperti:

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

Atau:

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

Dan tambahkan panggilan di bawah ini dalam fragmen Anda ...

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

Kasus penggunaan lain yang belum dijelaskan dalam jawaban lain:

onActivityResult()dideklarasikan dalam fragmen tidak dipanggil saat menggunakan exception.startResolutionForResult():

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

Dalam hal ini ganti exception.startResolutionForResult()dengan fragmen startIntentSenderForResult():

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

Versi Kotlin (Dalam aktivitas Anda diActivityResult ())

 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
sumber
1

Saya memiliki kecurigaan yang kuat bahwa semua jawaban di sini tidak lebih dari peretasan. Saya sudah mencoba semuanya dan banyak yang lain, tetapi tanpa kesimpulan yang dapat diandalkan karena selalu ada semacam masalah bodoh. I untuk satu tidak dapat mengandalkan hasil yang tidak konsisten. Jika Anda melihat dokumentasi API Android resmi untuk Fragmen, Anda akan melihat Google dengan jelas menyatakan sebagai berikut:

Panggil startActivityForResult (Intent, int) dari Activity yang berisi fragmen.

Lihat: Android Fragment API

Jadi, tampaknya pendekatan yang paling benar dan andal adalah dengan memanggil startActivityForResult () dari aktivitas hosting dan juga menangani onActivityResult () yang dihasilkan dari sana.

Chris
sumber
2
Saya tidak berpikir "panggil startActivityForResult from Activity" adalah rekomendasi. Jika Anda melihat implementasi di dalam kelas dasar Fragment, maka yang dilakukannya adalah mActivity.startActivityFromFragment(this, intent, requestCode)- jadi tidak ada yang lain selain pembungkus kenyamanan
Anti Veeranna
1

Kode Anda memiliki fragmen bersarang. Memanggil super.onActivityForResult tidak berfungsi

Anda tidak ingin mengubah setiap aktivitas yang dapat dipanggil dari fragmen Anda dan atau berusaha menyelesaikan setiap fragmen dalam rantai fragmen.

Ini adalah salah satu dari banyak solusi kerja. buat fragmen dengan cepat dan kirimkan langsung ke aktivitas dengan manajer fragmen dukungan. Kemudian panggil startActivityForResult dari fragmen yang baru dibuat.

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
sumber
Ini sebenarnya bekerja dan saya hanya punya satu suara untuk itu. Buat sebuah fragmen dengan cepat. Terlalu mudah tetapi solusi kerjanya yang sebenarnya. Seseorang bahkan mencoba mengeditnya untuk saya.
danny117
1

Masalah saya adalah dengan aktivitas Host saya menemukannya dengan set android:launchMode="standard"saya menghapusnya sementara itu berfungsi!

Chulo
sumber
1

Satu titik tidak ada mentionyang memastikan mode peluncuran Aktivitas Host Anda tidak boleh diatur ke singleInstanceatau singleTask.

onActivityResult tidak akan berfungsi jika mode peluncuran Anda diatur ke SingleInstance atau SingleTask. atau Anda memanggil aktivitas Anda menggunakan IntentFilters ini

standardatau singleTopmode peluncuran akan berfungsi dengan baik.

Jawad Zeb
sumber
1

Jika Anda menggunakan fragmen bersarang, ini juga berfungsi:

getParentFragment().startActivityForResult(intent, RequestCode);

Selain itu, Anda harus memanggil super.onActivityResultdari aktivitas induk dan mengisi onActivityResultmetode fragmen.

Oguz Ozcan
sumber
1

Saya telah menangani masalah ini dengan menulis kelas dasar yang diperluas Fragment, dan dalam onactivityresultaktivitas tersebut saya telah mengidentifikasi fragmen yang sedang berjalan menggunakan fragmenttag. Kemudian saya memanggil metode yang ditentukan pengguna dalam kelas fragmentbase. Ini akan memecat suatu peristiwa dalam fragmen yang sedang berjalan.

Bytecode
sumber