Android10及以上onActivityResult返回data为null、9系统正常问题
问题原因
- 核心问题是Android 10(API 29)及以上版本中,
ACTION_OPEN_DOCUMENT不接受file://类型的INITIAL_URI参数,你代码里直接将Environment.getExternalStorageDirectory()的文件路径转为Uri传入,属于非法参数,会导致系统文件选择器异常,返回空的Intent数据。 Environment.getExternalStorageDirectory()在API 29及以上已经被官方废弃,直接访问该路径下的文件会被系统权限拦截。- 若你调用
startActivityForResult时使用的是宿主Activity的实例而非DialogFragment自身的实例,结果会回传给Activity而非Fragment,也会导致Fragment内的onActivityResult拿到空数据。
解决方案
- 快速验证定位问题
先注释掉设置INITIAL_URI的两行代码,运行测试如果能拿到正常的data,说明确为初始Uri参数非法导致的问题。 - 添加存储兼容配置
在AndroidManifest.xml的<application>节点添加属性,兼容分区存储逻辑:
android:requestLegacyExternalStorage="true"
- 修正初始Uri的构造逻辑
如果需要保留指定初始路径的功能,API 29及以上版本需要构造合法的content://类型Uri传入,不要直接用文件路径转Uri。 - 检查回调接收逻辑
确保你在DialogFragment中调用的是Fragment自身的startActivityForResult(),而非getActivity().startActivityForResult();同时确认宿主Activity的onActivityResult方法调用了super.onActivityResult(),否则结果不会下发到Fragment。
修正后的代码示例
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Log.e("SELECT FILE IF = ", Build.VERSION.SDK_INT+" ~ "+Build.VERSION_CODES.KITKAT); Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); // 仅在API <29时设置file类型的初始Uri,API>=29时构造content类型Uri或者暂时去掉该参数 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { Uri internalStorage = Uri.parse(Environment.getExternalStorageDirectory().toString()+"/myfile/reports/dji/"); intent.putExtra("android.provider.extra.INITIAL_URI", internalStorage); } intent.putExtra("android.content.extra.SHOW_ADVANCED", true); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); isKitKat = true; // 调用Fragment自身的startActivityForResult,确保结果回传到Fragment startActivityForResult(Intent.createChooser(intent, "Select file"), 1); } else { Log.e("SELECT FILE ELSE = ", Build.VERSION.SDK_INT+" ~ "+Build.VERSION_CODES.KITKAT); isKitKat = false; Intent intent = new Intent(); Uri internalStorage = Uri.parse(Environment.getExternalStorageDirectory().toString()+"/myfile/reports/dji/"); intent.putExtra("android.provider.extra.INITIAL_URI", internalStorage); intent.putExtra("android.content.extra.SHOW_ADVANCED", true); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select file"), 1); }
内容的提问来源于stack exchange,提问作者mikasa
相关产品推荐
相关产品推荐

