You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13及以上设备FileNotFoundException权限问题求助

Android 13+ 任意文件访问权限问题解决方案

问题复盘

在Android 13及以上设备中,写入/storage/emulated/0/Download/MyTest.apk时触发EACCES (Permission denied)异常,即使文件已存在;现有权限仅能获取音频、视频、照片的访问权限,而相同功能在Android 11可正常运行。

先纠正权限声明中的错误

你添加的权限列表存在多处无效写法:

  • ACTION_OPEN_DOCUMENT_TREE、ACTION_OPEN_DOCUMENT、ACTION_CREATE_DOCUMENT是Intent动作,并非权限,不能放在<uses-permission>标签内
  • READ_MEDIA_*、WRITE_MEDIA_*这类通配符写法无效,Android 13的媒体权限为具体的READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO,且不存在WRITE_MEDIA_*系列权限
  • READ_MEDIA_FILES*多了多余星号,正确写法为READ_MEDIA_FILES(Android 14新增的媒体文件权限)

方案1:使用MANAGE_EXTERNAL_STORAGE权限(直接访问所有文件)

这是唯一能通过文件路径直接访问任意文件的方式,但Google对该权限的应用审核极为严格,仅文件管理器、备份工具等特定类型应用可通过审核。

  1. 清单中正确声明权限:
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        android:minSdkVersion="30" />
    
  2. 需跳转至系统设置页让用户手动开启权限(无法通过普通权限申请流程获取):
    if (!Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivity(intent);
    }
    
  3. 通过Environment.isExternalStorageManager()检查权限是否授权成功

方案2:使用Storage Access Framework(SAF,推荐,符合Google政策)

若你的应用不属于文件管理器类,推荐使用SAF——通过用户手动选择文件/目录的方式操作,无需特殊权限审核。

写入Download目录APK文件示例:

  1. 发起创建/选择文件的Intent:
    private static final int REQUEST_CODE_CREATE_FILE = 1001;
    
    // 触发文件选择/创建流程
    public void createApkFile() {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("application/vnd.android.package-archive"); // APK对应的MIME类型
        intent.putExtra(Intent.EXTRA_TITLE, "MyTest.apk");
        startActivityForResult(intent, REQUEST_CODE_CREATE_FILE);
    }
    
  2. 在回调中获取文件Uri并写入数据:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_CREATE_FILE && resultCode == RESULT_OK) {
            Uri fileUri = data.getData();
            // 通过ContentResolver写入数据
            try (OutputStream outputStream = getContentResolver().openOutputStream(fileUri)) {
                // 在这里写入你的文件内容到outputStream中
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
  3. 若需操作整个目录,可使用ACTION_OPEN_DOCUMENT_TREE让用户选择目标目录,之后即可访问该目录下的所有文件。

权限变化原因

Android 11引入分区存储机制,当targetSdkVersion<30时,WRITE_EXTERNAL_STORAGE仍可部分生效;但Android 13彻底收紧权限:仅媒体文件可通过媒体权限访问,APK等非媒体文件必须通过SAF或MANAGE_EXTERNAL_STORAGE权限操作。

内容的提问来源于stack exchange,提问作者Chamin Thilakarathne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 23:22:41