Android 11上传内部存储文件出现Open Failed: EACCES(Permission Denied)异常
Android 11 上传文件报 EACCES Denied 解决方案
现有问题根因
- 权限申请逻辑完全错误:
MANAGE_EXTERNAL_STORAGE不属于运行时危险权限,不能用ActivityCompat.requestPermissions弹出授权框,你写的这段申请代码系统不会响应,等于没申请。 - 分区存储规则限制:当应用
targetSdk >= 30时,Android 11会强制启用分区存储,你配置的android:requestLegacyExternalStorage="true"会直接失效,普通READ_EXTERNAL_STORAGE权限无法直接访问外部存储公共目录的文件。
可选适配方案
方案1:仅需要用户选择文件上传(优先推荐)
不需要申请任何存储权限,直接调用系统存储访问框架(SAF)的文件选择器,拿到的Uri自带读取权限,无兼容问题:
- 调起系统文件选择器:
Intent pickFileIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT); pickFileIntent.addCategory(Intent.CATEGORY_OPENABLE); // 按需求过滤文件类型,比如仅选图片则设为 "image/*",所有文件设为 "*/*" pickFileIntent.setType("*/*"); startActivityForResult(pickFileIntent, UPLOAD_REQUEST_CODE);
- 在
onActivityResult中获取选中文件的Uri,直接通过getContentResolver().openInputStream(uri)读取文件即可。
方案2:需要批量遍历/访问整个外部存储
必须申请「所有文件访问权限」,该权限需要跳转系统设置页授权,不能用运行时弹窗申请:
- 先在Manifest中声明权限:
<!-- 适配Android 10及以下的普通存储权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 11+ 所有文件访问权限声明 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
- 按版本判断申请逻辑:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // 先判断是否已经授予所有文件访问权限 if (!Environment.isExternalStorageManager()) { // 跳转应用的所有文件权限设置页,等待用户授权 Intent manageStorageIntent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); manageStorageIntent.setData(Uri.parse("package:" + getContext().getPackageName())); startActivityForResult(manageStorageIntent, MANAGE_STORAGE_REQUEST_CODE); } } else { // Android 10及以下走原有普通存储权限申请流程即可 if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_PERMISSION_CODE); } }
注意:如果应用仅为了上传单个文件申请「所有文件访问权限」,上架应用商店时大概率会被审核驳回,优先用SAF方案。
内容的提问来源于stack exchange,提问作者Manikanta
相关产品推荐
相关产品推荐

