使用FileProvider在onActivityResult中遇EACCES权限拒绝问题求助
问题解决:将录制视频从Content Uri复制到应用本地文件夹
核心错误分析
- 查询字段错误:
getRealPathFromURI中误用MediaStore.Images.Media.DATA查询视频文件,应替换为MediaStore.Video.Media.DATA,否则部分系统无法正确获取路径。 - 冗余的FileProvider操作:
onActivityResult返回的selectedMediaUri本身带有临时访问权限,无需通过自己的FileProvider生成Uri再读取,直接用ContentResolver即可访问。 - Scoped Storage限制:Android 10+禁止直接访问外部存储的真实路径,直接操作文件会触发权限拒绝。
修正后的代码实现
简化复制逻辑(无需获取真实路径)
直接通过ContentResolver读取视频流,写入应用私有目录(无需额外权限):
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); .... } else if (requestCode == CAMERA_REQUEST_VIDEO) { if (resultCode == Activity.RESULT_OK && data != null) { .... Uri selectedMediaUri = data.getData(); if (selectedMediaUri == null) { Log.e("App", "Media Uri is null"); return; } Log.d("App", "got link:" + selectedMediaUri); // 目标文件:应用私有目录,这里用内部存储的files目录 File fileCameraTemp = new File(getFilesDir(), "camera_result_temp.mp4"); // 也可以用外部私有目录:getExternalFilesDir(Environment.DIRECTORY_MOVIES) try (InputStream is = getContentResolver().openInputStream(selectedMediaUri); FileOutputStream fos = new FileOutputStream(fileCameraTemp)) { byte[] buf = new byte[4096]; // 增大缓冲区提升复制效率 int len; while ((len = is.read(buf)) > 0) { fos.write(buf, 0, len); } Log.d("App", "视频复制成功,路径:" + fileCameraTemp.getAbsolutePath()); } catch (IOException e) { Log.e("App", "复制视频失败", e); } .... } } }
(可选)修正FileProvider配置(仅当需要分享文件时)
如果后续需要将应用内的视频分享给其他应用,需保证配置一致:
- 统一Manifest和代码中的
authorities,比如都改为de.x.y.app.fileprovider:
<provider android:name="androidx.core.content.FileProvider" android:authorities="de.x.y.app.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>
- 精简
file_paths.xml,只保留需要的应用内路径:
<?xml version="1.0" encoding="utf-8"?> <paths> <files-path name="files" path="."/> <external-files-path name="external_files" path="."/> </paths>
关键注意事项
- 应用私有目录(
getFilesDir()、getCacheDir()、getExternalFilesDir()等)无需额外存储权限,系统默认允许访问。 - 使用
try-with-resources语法自动关闭流,避免资源泄漏。 - 该方案适配Android 7.0+全版本,包括Android 10+的Scoped Storage限制。
内容的提问来源于stack exchange,提问作者aqm
相关产品推荐
相关产品推荐

