961

このフラグメントをホストする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);
    }
}
4

40 に答える 40

1330

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

また、@siqingの回答から:

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

于 2011-05-27T04:42:16.570 に答える
356

に電話したと思いますgetActivity().startActivityForResult(intent,111);。に電話する必要がありますstartActivityForResult(intent,111);

于 2012-06-13T09:13:48.960 に答える
306

オプション1:

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

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
}
于 2013-06-12T09:17:30.237 に答える
106

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

//Java

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

//コトリン

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        for (fragment in supportFragmentManager.fragments) {
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }
于 2014-03-27T10:40:11.357 に答える
72

元の投稿。

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

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

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

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

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

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

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

于 2014-06-19T09:34:27.993 に答える
18

FOR MANY NESTED FRAGMENTS (たとえば、フラグメントで 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
    }
}

注意

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

于 2016-01-22T17:17:33.673 に答える
14

それでもうまくいかない人がいたら、2 つのアドバイスを追加できます。Manifest.xml ファイルで、コールバック時にホスティング アクティビティが終了していないことと、開始​​するアクティビティの起動モードが標準であることを確認します。以下のように詳細を参照してください。

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

android:noHistory="false"

アクティビティを開始するには、起動モードを標準に設定します。

android:launchMode="standard"
于 2012-12-30T03:36:06.810 に答える
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.

于 2014-12-18T09:01:14.340 に答える
5

フラグメント内で、呼び出します

this.startActivityForResult(intent, REQUEST_CODE);

wherethisはフラグメントを参照しています。それ以外の場合は、@Clevester が言ったように行います。

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

私も電話しなければならなかった

super.onActivityResult(requestCode, resultCode, data);

親アクティビティonActivityResultでそれを機能させます。

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

于 2014-12-23T08:11:16.663 に答える
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);
于 2015-10-27T13:25:34.647 に答える
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);
    }
} 
于 2013-04-08T08:31:08.500 に答える
2

これを追加

public void onClick(View v) {   
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, 1);
}

コードを上記のコードに置き換えると、自動的にこれ

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

メソッドは動作を開始します

//No Need to write this code in onclick method
    Intent intent=new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT)
    startActivityForResult(intent,1);
    Toast.makeText(getContext(), "image"+intent, Toast.LENGTH_SHORT).show();
于 2012-02-20T11:05:04.110 に答える
1

Ollie C が述べたように、ネストされたフラグメントを使用している場合に onActivityResult への戻り値を使用するサポート ライブラリにアクティブなバグがあります。私はちょうどそれを打ちました:-(。

requestCode != 0 の場合に Fragment.onActivityResult が呼び出されないことを参照してください。

于 2014-06-09T21:59:07.260 に答える
1

ここでの答えはすべてハッキングにすぎないのではないかと私は強く疑っています。私はそれらすべてと他の多くのものを試しましたが、常にある種のばかげた問題があるため、信頼できる結論はありません. 私は一貫性のない結果に頼ることはできません。Fragments の公式の Android API ドキュメントを見ると、Google が次のように明確に述べていることがわかります。

フラグメントを含む Activity から startActivityForResult(Intent, int) を呼び出します。

参照: Android フラグメント API

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

于 2014-09-15T12:47:31.603 に答える
1

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

于 2016-06-23T02:13:00.683 に答える
1

mentionホスト アクティビティの起動モードsingleInstanceをまたはに設定してはならないことを誰も確認していない 1 つのポイントsingleTask

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

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

于 2016-08-04T06:36:57.160 に答える
1

まず、Activity でこのコードをオーバーライドする必要があります。

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

その後、フラグメントで、

startActivityForResult(intent,GALLERY_REQUEST_CODE);

そして再びあなたの断片よりも、

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // Result code is RESULT_OK only if the user selects an Image
    if (resultCode == Activity.RESULT_OK) {

    }

}
于 2019-11-12T13:36:10.907 に答える
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();
}
于 2014-11-23T09:25:51.807 に答える
0

最も簡単な方法の 1 つは、フラグメントからアクティビティを開始することです。

startActivity(ActivityName);

次に、startActivityForResult(intent,"1");アクティビティからの呼び出しを追加し、アクティビティに追加onActivityResultします

startActivityForResult(intent,"1");

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
// perform other activity result like fetching from Uris or handling cursors

finish(); // finish the activity will  get to back to your fragment.
}
于 2016-05-30T09:21:15.067 に答える
0

回避策を作成するだけです:

public static Fragment _tempFragment = null;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(_tempFragment != null)
        _tempFragment.onActivityResult(requestCode, resultCode, data);
}

Fragment で、startActivityResult の前に設定します

MainActivity._tempFragment = this;

onActivityResult の後 <-- フラグメント内

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

     // Do your job
     {

     }
     MainActivity._tempFragment = null;
}
于 2013-11-06T09:40:34.967 に答える
-7

単に呼び出すだけです:

startActivityForResult(intent, "1");
于 2015-11-23T10:47:12.120 に答える