onActivityResult is not being called in Fragment
当相机活动返回时,托管此片段的活动将调用其
我的片段开始一个结果的活动,目的是让相机拍照。图片应用程序加载良好,拍照,然后返回。然而,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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); } } |
托管活动覆盖
还有来自@Siqing的回复:
要在片段中得到结果,请确保在片段中调用
我想你打电话给
选项1:
如果您从片段调用
如果您不确定在哪里调用
选项2:
由于activity得到
如果上述两个选项不起作用,则参考选项3,因为它肯定会起作用。
选项3:
从fragment到onActivityResult函数的显式调用如下。
在父Activity类中,重写onActivityResult()方法,甚至重写fragment类中的方法,并调用以下代码。
在父类中:
1 2 3 4 5 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane); fragment.onActivityResult(requestCode, resultCode, data); } |
在儿童班:
1 2 3 4 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // In fragment class callback } |
如果您不知道活动中的片段,只需枚举它们并发送活动结果参数:
1 2 3 4 5 6 7 8 | // 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); } } |
我和
1 2 3 4 5 6 7 | 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); } } |
原来的职位。
一个
如果你有一个片段在几个层次的根有问题。如果你有一个嵌套的片段,例如
由于只有一个索引是存储在
我们如何解决这个问题的?有一个解决方案,在这一篇普通的workaround。
GitHub的https://://shamanland github.com嵌套的片段。
这是一个最受欢迎的问题。关于这个问题,我们可以找到很多线索。但这些都对我没用。
所以我用这个方法解决了这个问题。
让我们先了解一下为什么会发生这种情况。
我们可以直接从片段中调用
一旦从片段调用
一旦活动被导航回,结果将与修改后的请求代码一起发送到活动的OnActivityResult,该代码将被解码为原始请求代码+片段的标识。之后,活动将通过onActivityResult将活动结果发送到该片段。一切都结束了。
问题是:
活动只能将结果发送到直接附加到活动的片段,而不能发送到嵌套的片段。这就是为什么嵌套片段的onActivityResult永远不会被调用的原因。
解决方案:
1)通过以下代码开始片段中的意图:
1 2 | /** Pass your fragment reference **/ frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345 |
2)现在在您的父活动中覆盖**
1 2 3 4 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } |
您必须在父活动中调用它才能使其工作。
3)在片段调用中:
1 2 3 4 5 6 7 | @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { } } |
就是这样。有了这个解决方案,无论是否嵌套,它都可以应用于任何单个片段。是的,它也涵盖了所有的情况!此外,这些代码也很好而且很干净。
对于许多嵌套片段(例如,在片段中使用viewpager时)
在您的主要活动中:
1 2 3 4 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } |
在你的片段中:
1 2 3 4 5 6 | @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { for (Fragment fragment : getChildFragmentManager().getFragments()) { fragment.onActivityResult(requestCode, resultCode, data); } } |
在嵌套片段中
通话活动
1 | getParentFragment().startActivityForResult(intent, uniqueInstanceInt); |
uniqueinstanceint-用嵌套片段中唯一的int替换它,以防止另一个片段处理答案。
接收响应
1 2 3 4 5 6 | @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == uniqueInstanceInt ) { // TODO your code } } |
敬告
uniqueinstanceint中需要使用一个介于0和65536之间的数字,以避免"只能对请求代码使用16位以下的数字"。
如果还是有人做不到,我可以加两条建议。在manifest.xml文件中,确保在回调时宿主活动没有完成,并且要启动的活动具有标准的启动模式。具体如下:
对于托管活动,如果有,则将no history属性设置为false
1 | android:noHistory="false" |
对于要启动的活动,将启动模式设置为标准(如果有)
1 | android:launchMode="standard" |
我也遇到这个问题,在片段。我叫
现在这个问题已得到解决:
我也面临同样的问题,当我将这段代码从一个片段转移到一个实用程序类中时,
1 2 | Intent intent = new Intent(parentActivity, CameraCaptureActivity.class); parentActivity.startActivityForResult(intent,requestCode); |
然后我没有得到该片段的
1 2 | Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class); fragment.startActivityForResult(intent,requestCode); |
在那之后,我可以在
Solution 1:
Call
Solution 2:
When
总之,
在宣布
这是
在activityresult将返回的结果。
Inside your fragment, call
1 | this.startActivityForResult(intent, REQUEST_CODE); |
在
1 2 3 | Fragment fragment = this; .... fragment.startActivityForResult(intent, REQUEST_CODE); |
我也不得不呼叫
1 | super.onActivityResult(requestCode, resultCode, data); |
在父母的
一本从"适应clevester答案的答案。)
在我的例子中,这是一个Android错误(http://technet.weblineindia.com/mobile/onactivityresult not getting called in nested fragments android/),如果您使用支持的
1 2 3 4 5 6 7 8 | List<Fragment> fragments = getSupportFragmentManager().getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { if(fragment instanceof UserProfileFragment) { fragment.onActivityResult(requestCode, resultCode, data); } } } |
对于嵌套片段(例如,使用viewpager时)
在您的主要活动中:
1 2 3 4 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } |
在主顶级片段(viewpager片段)中:
1 2 3 4 5 6 | @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); } |
在片段(嵌套片段)中:
1 2 3 | public void yourMethod(Intent data){ // Do whatever you want with your data } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 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); } } |
这些答案中的大多数都说,你必须在你的主机中打电话给
所以,在你的主机
1 2 3 4 5 6 7 8 9 | public class HostActivity extends Activity { private MyFragment myFragment; protected void onActivityResult(...) { super.onActivityResult(...); this.myFragment.onActivityResult(...); } } |
在您的
如果以上的问题是当你在Facebook的登录使用下面的代码可以在你的父的片段样活性。
1 2 | Fragment fragment = getFragmentManager().findFragmentById(android.R.id.tabcontent); fragment.onActivityResult(requestCode, resultCode, data); |
或:
1 2 | Fragment fragment = getFragmentManager().findFragmentById("fragment id here"); fragment.onActivityResult(requestCode, resultCode, data); |
添加下面的呼叫和在你的片段……
1 | callbackManager.onActivityResult(requestCode, resultCode, data); |
你可以简单地重写baseactivity
在线baseactivity onactivityresult)接口和覆盖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); } |
在线
1 2 3 4 5 6 7 8 | @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(); } } |
这将workaround的戏法。
我有一个强烈的被怀疑在所有的答案是不多的黑客。我想很多人都和他们没有任何可靠的结论,但总有一些排序)的愚蠢的问题。我是一个不能依靠不一致的结果。如果你看看官方的Android API的谷歌文档你会清楚地看到美国片段以下:
Call startActivityForResult(Intent, int) from the fragment's containing Activity.
国有企业:Android API的片段。
操作系统,它将似乎是最准确和可靠的方法,其实是从主机startactivityforresult(呼叫)的活性也导致onactivityresult(手柄),从那里。
正如Ollie C所提到的,在使用嵌套片段时,支持库有一个活动的bug,它使用返回到onActivityResult的值。我刚刚打了一下。
请参见fragment.onActivityResult,请求代码时未调用!= 0。
你有嵌套的代码片段。呼叫super.onactivityforresult不是工作
你不想你的每一个活性的修改,称为片段,可以从工作或使呼叫和在每个片段的片段链。
这里是一个解决方案的许多工作。创建一个片段,它直接飞到电线与支持经理活性片段。然后从新创建的呼叫startactivityforresult片段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 <div class="suo-content">[collapse title=""]<ul><li>这确实有效,我只有一票支持。在飞行中创建一个片段。太简单了,但它真正的工作解决方案。甚至有人试图为我编辑它。</li></ul>[/collapse]</div><hr><P>我的问题是主机活动,我是用一套<wyn>android:launchMode="standard"</wyn>找到它的,我把它暂时删除了一个IT工作!</P><p><center>[wp_ad_camp_5]</center></p><hr><P>如果您使用的是嵌套片段,那么这也可以工作:</P>[cc]getParentFragment().startActivityForResult(intent, RequestCode); |
除此之外,还必须从父活动调用
只要使用下面的代码片段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @Override public void onOtherButtonClick(ActionSheet actionSheet, int index) { if (index == 1) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1); } } public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == 1) { if (requestCode == 1) { Uri selectedImageUri = data.getData(); //selectedImagePath = getPath(selectedImageUri); } } } |
它的母onactivityresult打电话没有电话。
如果fragment类中的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode == Activity.RESULT_OK) { // If the user had agreed to enabling Bluetooth, // populate the ListView with all the paired devices. this.arrayDevice = new ArrayAdapter<String>(this.getContext(), R.layout.device_item); for(BluetoothDevice bd : this.btService.btAdapater.getBondedDevices()) { this.arrayDevice.add(bd.getAddress()); this.btDeviceList.setAdapter(this.arrayDevice); } } super.onActivityResult(requestCode, resultCode, data); } |
如上面代码所示,只需添加
我还通过将这个代码块放入
因此,如果您希望fragment类有自己的
最简单的方法之一是从片段开始一个活动。
1 | startActivity(ActivityName); |
然后,从你的活动中添加你称之为
1 2 3 4 5 6 7 8 9 10 | 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. } |
One point no one has
mention that make sure your Host Activity launch mode must not set tosingleInstance orsingleTask .
如果启动模式设置为singleInstance或singleTask,则OnActivityResult将不起作用。或者使用这些intentfilters调用您的活动
我通过编写一个扩展
我只是做了一个变通方法:
1 2 3 4 5 6 7 | 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); } |
在片段中,在StartActivityResult之前,设置
1 | MainActivity._tempFragment = this; |
OnActivityResult之后<--in fragment
1 2 3 4 5 6 7 8 9 10 | @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Do your job { } MainActivity._tempFragment = null; } |
只需打电话:
1 | startActivityForResult(intent,"1"); |