onActivityResultがフラグメントで呼び出されていません


877

このフラグメントをホストするonActivityResultアクティビティは、カメラアクティビティが戻ったときに呼び出されます。

私のフラグメントは、カメラが写真を撮るために送信された意図で結果のアクティビティを開始します。画像アプリケーションは正常に読み込まれ、写真を撮って戻ります。onActivityResultしかし、ヒットされることはありません。ブレークポイントを設定しましたが、何もトリガーされません。フラグメントは持つことができますonActivityResultか?提供機能なのでそう思います。なぜこれがトリガーされないのですか?

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

2
この記事をチェックし、問題の説明と、共通の問題を回避するソリューションがあります:stackoverflow.com/questions/6147884/...
Oleksii K.

5
これを読んでいる誰もがあなたが合格することを確認してくださいrequestCode >= 0
ムハンマドババール2015

3
また、アクティビティのLauchModeがsingleInstanceまたはsingleTaskでないことを確認してください。そうでない場合、onActivityResultは呼び出されません
Jawad Zeb

このリンクがあなたを助けるかもしれません:androidtutorialonline.com/onactivityresult-in-fragment
Androidチュートリアル

アクティビティのonActivityResultをフラグメントにリダイレクトする必要があります。:このリンク参照してくださいcodexpedia.com/android/...
Reejesh PK

回答:


1240

ホスティングアクティビティはをオーバーライドしますがonActivityResult()super.onActivityResult()未処理の結果コードを呼び出しませんでした。どうやら、フラグメントはstartActivityForResult()呼び出しを行うフラグメントであるにもかかわらず、アクティビティは結果の処理で最初のショットを取得します。フラグメントのモジュール性を考えると、これは理にかなっています。super.onActivityResult()処理されていないすべての結果に実装すると、フラグメントは結果の処理に成功しました。

また、@ siqingの回答から:

フラグメントで結果を取得するには、フラグメント内ではstartActivityForResult(intent,111);なく、必ずを呼び出しgetActivity().startActivityForResult(intent,111);てください。


34
アクティビティのonActivityResultで、super.onActivityResult()を呼び出します
Spidy

167
@StErMiフラグメントからgetActivity()。startActivityForResult()ではなく、startActivityForResult()を呼び出すようにしてください。以下のsiqingの回答を参照してください。
OferR 2012

8
関連するバグがあり、サポートライブラリが使用されているようですcode.google.com/p/android/issues/detail?id=15394
Ollie C

82
また、ネストされたフラグメントを使用している場合は、子フラグメントを呼び出しgetParentFragment().startActivityForResultて、親フラグメントのonActivityResultメソッドが呼び出されるようにする必要があります。
Eric Brynsvold、2013

7
@EricBrynsvoldは正しかった、startActivityForResultはネストされたフラグメントでは機能しません。そのためには、getParentFragment()。startActivityForResult()を呼び出す方がよいでしょう。その親フラグメントで、onActivityResult()を実装し、そのメソッドで結果を子フラグメントに配信できます。つまり、childFragment.getParentFragment()です。 onActivityResult(requestCode、resultCode、data)
エイドリアン

328

呼んだと思いますgetActivity().startActivityForResult(intent,111);。お電話くださいstartActivityForResult(intent,111);


3
にあるでも同じ問題がRingtonePreferenceありましたPreferenceFragment。残念ながら、をRingtonePreference呼び出します。アクティビティのgetActivity().startActivityForResult()を呼び出しても結果は得られませんでした。にバインドし、を呼び出すクラスから派生したものを作成せざるを得ませんでした。super.onActivityResultonActivityResultRingtonePreferencePreferenceFragmentfragment.startActivityForResult()
2013年

@siqing静的メソッドからstartActivitForResultを呼び出すことができません。そのための解決策はありますか?activity.startActivityForResultを使用する必要があります。これで私を助けてください
Shreyash Mahajan 2015

270

オプション1:

startActivityForResult()フラグメントから呼び出す場合は、フラグメントstartActivityForResult()ではなくgetActivity().startActivityForResult()、を呼び出す必要があります。フラグメントonActivityResult()になります。

どこで呼び出しているのstartActivityForResult()か、どのようにメソッドを呼び出すのかわからない場合。

オプション2:

Activityはの結果を取得するため、未処理の結果コードまたはすべてに対してonActivityResult()、アクティビティのonActivityResult()とを呼び出しsuper.onActivityResult()て、それぞれのフラグメントに伝播する必要があります。

上記の2つのオプションが機能しない場合は、確実に機能するため、オプション3を参照してください。

オプション3:

フラグメントからonActivityResult関数への明示的な呼び出しは次のとおりです。

親Activityクラスで、onActivityResult()メソッドをオーバーライドし、さらにFragmentクラスで同じものをオーバーライドして、次のコードとして呼び出します。

親クラス:

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

子クラス:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}

4
これでうまくいきました。それは厄介な回避策ですが、私はこのばかげたバグを解決するためのより良い考えを持っていません...
ボグダンズラック2013年

@Vivky、あなたの答えは私のために働いた。しかし、私が直面しているもう1つの問題がありますsetResult(); finish();。2番目のアクティビティから押し戻すときの代わりに、provide onActivityResultが呼び出されますRESULT_CODE
snehal_penurkar

素晴らしい答え。私はそれを行うために3番目のソリューションを実装しました。
Sash_KP

私はソリューション3がうまくいくと思いますonActivityResult()が、アクティビティのは奇妙なrequestCodeものを返しますが、それは私のフラグメントに渡されて無視されます= /
E-Kami

1
@notGeekあなたは正しいです。フラグメントまたはアクティビティから呼び出した場合でも、結果は常にアクティビティで受信されます。
ビナヤク2018

83

アクティビティのフラグメントがわからない場合は、それらをすべて列挙し、アクティビティの結果引数を送信します。

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

3
くそー、私は最も単純な解決策を見つけたと思ったが、getFragments()などのメソッドはありません。
WindRider 2014年

2
@WindRiderあります。Androidサポートライブラリ(AppCompat)を使用する場合。
dasar 2014年

2
また、配列内のフラグメントがそれ自体への参照ではないかどうかを確認する必要がある難しい方法を学びました!`if(fragment!= this){fragment.onActivityResult(requestCode、resultCode、data); `
ルーベンジョン2015

フラグメントがネストされている場合、これは機能しません。リストにあるのは最上位のフラグメントのみです。super.onActivityResult()は、リスト内のすべてのフラグメントでonActivityResult()をすでに呼び出していると思いますので、このアイデアは冗長です。
BeccaP


83

と同じ問題が発生していChildFragmentManagerます。マネージャーはネストされたフラグメントに結果を渡しません。ベースフラグメントで手動で行う必要があります。

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

1
子メンバーをプライベートメンバーとして持っている場合は、を使用Fragment fragment = myChildFragment;して上記findFragmentByTagのコード行を置き換えます。残りは変更しないでおくことができます。
lcn 2013年

7
フラグメントをプライベートメンバーとして保持しないことを強くお勧めします。彼らは独自のライフサイクルを持っているので、彼らが対話するのに良い状態にあるかどうかは決してわかりませんが、マネージャーはそうします。また、それらはかなり多額であり、私はメモリリークについて心配するでしょう。マネージャーを使用する必要がなければ、マネージャーは作成されませんでした。
MinceMan 2013年

67

元の投稿。

FragmentActivityrequestCode変更されたものに置き換えます。その後、onActivityResult()が呼び出されると、FragmentActivityは上位16ビットを解析し、元のフラグメントのインデックスを復元します。このスキームを見てください:

ここに画像の説明を入力してください

ルートレベルにいくつかのフラグメントがある場合、問題はありません。ただし、たとえば内にいくつかのタブがあるフラグメントネストしている場合、問題に直面する(またはすでに直面している)ことが保証されFragmentます。ViewPager

内部に格納されるインデックス1つだけなのでrequestCode。それはFragmentその中のインデックスですFragmentManager。ネストされたフラグメントを使用している場合、子FragmentManagerのがあり、フラグメントの独自のリストがあります。したがって、rootから始めて、インデックスのチェーン全体を保存する必要がありますFragmentManager

ここに画像の説明を入力してください

この問題を解決するにはどうすればよいですか?この投稿には一般的な回避策があります。

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


他のフラグメントをタブとして保持する親フラグメントでViewPagerを使用したのと同じ問題があります。ネストされたフラグメントの問題を使用してみましたが、コンパイルエラーが発生しました。私に解決策を提案できますか?ここでも問題が発生しましたgithub.com/shamanland/nested-fragment-issue/issues/2
cgr

私はここをこの会話を移動させ、githubの上で答えgithub.com/shamanland/nested-fragment-issue/issues/...
Oleksii K.

ありがとう!これが推奨される解決策ではない場合は、それに応じて回答を編集することをお勧めします。これにより、コンパイルエラーがあることを知るために時間を費やす必要がなくなります。
cgr 2015年

44

これは最も人気のある問題の1つです。この問題に関するスレッドがたくさん見つかります。しかし、それらのどれもMEに役立ちません。

したがって、私はこのソリューションを使用してこの問題を解決しました。

まず、これがなぜ起こっているのかを理解しましょう。

startActivityForResultFragmentから直接呼び出すこともできますが、実際には背後のメカニックはすべてActivityによって処理されます。

startActivityForResultフラグメントから呼び出すと、コードにフラグメントのIDを添付するようにrequestCodeが変更されます。これにより、Activityは、結果が受信されたときにこのリクエストを送信したユーザーを追跡できます。

Activityが戻ってナビゲートされると、結果は、変更されたrequestCodeとともにActivityのonActivityResultに送信されます。これは、元のrequestCode + FragmentのIDにデコードされます。その後、ActivityはonActivityResultを介してそのフラグメントにアクティビティ結果を送信します。そして、すべて完了です。

問題は:

アクティビティは、ネストされたものではなく、アクティビティに直接アタッチされているフラグメントのみに結果を送信できます。これが、ネストされたフラグメントのonActivityResultが何があっても呼び出されない理由です。

解決:

1)以下のコードでフラグメントのインテントを開始します:

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

2)親アクティビティのオーバーライドで**onActivityResult():**

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

これを機能させるには、親アクティビティでこれを呼び出す必要があります。

3)フラグメント呼び出しで:

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

       }
}

それでおしまい。このソリューションを使用すると、ネストされているかどうかに関係なく、単一のフラグメントに適用できます。そして、はい、それはすべてのケースもカバーします!また、コードもきれいです。


私はフラグメントコンテキストを使用する必要がある 'アクティビティ'でシステムインテントを要求していました。
Uzair

18

多くのネストされたフラグメントの場合(たとえば、フラグメントでViewPagerを使用する場合)

あなたの主な活動

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

あなたのフラグメントで:

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

ネストされたフラグメント

通話アクティビティ

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

uniqueInstanceInt-ネストされたフラグメント間で一意のintに置き換えて、別のフラグメントが回答を処理しないようにします。

応答を受け取る

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

注意

エラーを回避するには、uniqueInstanceIntで「requestCodeに下位16ビットしか使用できない」という0〜65536の数値を使用する必要があります。


で素晴らしい作品活動>フラグメント(ViewPager)>フラグメント
オレクサンドルFirsov

14

誰かがまだそれを作ることができないならば、私は2つのアドバイスを加えることができます。Manifest.xmlファイルで、コールバック時にホスティングアクティビティが完了しておらず、開始するアクティビティに標準の起動モードがあることを確認します。詳細は以下をご覧ください:

ホスティングアクティビティの場合、履歴なしプロパティをfalseに設定します。

android:noHistory="false"

アクティビティを開始するには、必要に応じて起動モードを標準として設定します

android:launchMode="standard"

13

私は、コード外のこのブロックシフトしたら、私も同じ問題に直面していた断片をするユーティリティクラスで、parentActivityとして渡された引数

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

次にonActivityResult、そのFragmentのメソッドで値を取得していませんでした。その後、引数Fragmentに変更したため、メソッドの改訂された定義は次のようになりました、

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

その後、私はフラグメントで価値を得ることができonActivityResultました


10

この問題はフラグメントでも発生しました。そして私はを呼びstartActivityForResultましたDialogFragment

しかし、この問題は解決されました:
FragmentClassname.this.startActivityForResult


startActivityForResult(...)フラグメントのコード内の抽象クラスから呼び出していたため、うまくいきました。
ビンス

9

ネストされたフラグメントの場合(たとえば、ViewPagerを使用する場合)

あなたの主な活動:

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

メイントップレベルのフラグメント(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);
}

YourFragment(ネストされたフラグメント):

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

8

私の場合、それは、Androidのバグ(だったhttp://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/ご使用はサポートされている場合、)FragmentActivityあなたが使用する必要がgetSupportFragmentManager代わりのをgetChildFragmentManager

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

6

要するに、

断片的に、宣言しFragment fragment = thisます。

その後の使用fragment.startActivityForResult

結果はactivityResultに返されます。


6

解決策1:

startActivityForResult(intent, REQUEST_CODE);代わりに呼び出しますgetActivity().startActivityForResult(intent, REQUEST_CODE);

解決策2:

ときにstartActivityForResult(intent, REQUEST_CODE);呼び出されたアクティビティのがonActivityResult(requestCode,resultcode,intent)呼び出され、その後、あなたは呼び出すことができますfragments onActivityResult()渡し、ここからrequestCode, resultCode and intent


5

フラグメント内で、

this.startActivityForResult(intent, REQUEST_CODE);

ここでは、this断片に言及されています。それ以外の場合は@Clevesterが言ったようにします

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

私も電話しなければなりませんでした

super.onActivityResult(requestCode, resultCode, data);

親アクティビティでonActivityResultそれを機能させるためのものです。

(@Clevesterの回答からこの回答を採用しました。)


5

使う人のためのAndroidのナビゲーションコンポーネントの活動の中で使用する必要があり、それはフラグメント参照と呼びフラグメントのです取得します。onActivityResult(...)primaryNavigationFragmentfragment.onActivityResult(...)

こちらがアクティビティです 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);
    }
}

4

これらの回答のほとんどはsuper.onActivityResult(...)、あなたのホストActivityにあなたのを呼ぶ必要があると言い続けていますFragment。しかし、それは私にとってはうまくいかなかったようです。

したがって、ホストでActivityFragments onActivityResult(...)代わりにを呼び出す必要があります。ここに例があります。

public class HostActivity extends Activity {

    private MyFragment myFragment;

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

あなたのある時点であなたはあなたが使用しているあなたHostActivityを割り当てる必要があります。または、への参照を保持する代わりに、を使用してを取得します。また、を呼び出す前に確認してください。this.myFragmentFragmentFragmentManagerFragmentHostActivitynullthis.myFragment.onActivityResult(...);


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

3
  1. あなたは単にonActivityResultフラグメントのBaseActivity をオーバーライドすることができますbaseActivity.startActivityForResult

  2. BaseActivityでインターフェースを追加し、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. フラグメントの実装 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();
      }
    }

この回避策でうまくいきます。


3

上記の問題がFacebookログインで直面する場合は、以下のコードをフラグメントの親アクティビティで使用できます。

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

または:

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

そして、以下の呼び出しをフラグメントに追加してください...

callbackManager.onActivityResult(requestCode, resultCode, data);

2

他の回答でまだ説明されていない別のユースケース:

onActivityResult()使用時にフラグメントで宣言されたものが呼び出されないexception.startResolutionForResult()

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

この場合exception.startResolutionForResult()、フラグメントで置き換えstartIntentSenderForResult()ます:

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

2

Kotlinバージョン(あなたのアクティビティ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)
    }
 }


1

ここでの答えはすべてハックに他ならないという強い疑いがあります。私はそれらすべてを試してみましたが、常になんらかの愚かな問題があるため、信頼できる結論はありませんでした。私は矛盾した結果に頼ることはできません。Fragmentsの公式のAndroid APIドキュメントを見ると、Googleが次のように明確に述べていることがわかります。

フラグメントを含むアクティビティからstartActivityForResult(Intent、int)を呼び出します。

参照:Android Fragment API

したがって、最も正確で信頼性の高いアプローチは、ホスティングアクティビティから実際にstartActivityForResult()を呼び出し、そこから結果のonActivityResult()を処理することです。


2
「アクティビティからstartActivityForResultを呼び出す」はお勧めしません。Fragment基本クラス内の実装を見ると、mActivity.startActivityFromFragment(this, intent, requestCode)それが行うことはすべて、コンビニエンスラッパーに他なりません
Anti Veeranna

1

コードにネストされたフラグメントがあります。super.onActivityForResultの呼び出しが機能しない

フラグメントを呼び出すことができるすべてのアクティビティを変更したり、フラグメントチェーン内のすべてのフラグメントの呼び出しに対処したりする必要はありません。

これは、多くの実用的なソリューションの1つです。オンザフライでフラグメントを作成し、サポートフラグメントマネージャーを使用してアクティビティに直接ワイヤリングします。次に、新しく作成されたフラグメントからstartActivityForResultを呼び出します。

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

これは実際に機能し、私はそれに1票しかありません。その場でフラグメントを作成します。簡単すぎますが、その真の実用的なソリューションです。誰かが私のためにそれを編集しようとしました。
danny117 2016年

1

私の問題は、ホストアクティビティにありました。セットでそれを見つけまし android:launchMode="standard"た。一時的にそれを削除しました。


1

mentionホストアクティビティの起動モードsingleInstanceまたはに設定されていないことを確認することは誰にもありませんsingleTask

起動モードがSingleInstanceまたはSingleTaskに設定されている場合、onActivityResultは機能しません。または、これらのIntentFiltersを使用してアクティビティを呼び出します

standardまたはsingleTop起動モードは正常に動作します。


1

ネストされたフラグメントを使用している場合、これも機能しています:

getParentFragment().startActivityForResult(intent, RequestCode);

これに加えてsuper.onActivityResult、親アクティビティから呼び出してonActivityResult、フラグメントのメソッドを埋める必要があります。


1

私は拡張する基本クラスを記述することで問題を処理し、アクティビティのFragmentonactivityresultで、を使用して現在実行中のフラグメントを識別しましたfragmenttag。次に、fragmentbaseクラスのユーザー定義メソッドを呼び出します。これにより、現在実行中のフラグメントでイベントが発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.