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

如何将SD卡/外部存储文件上传至服务器?遇权限拒绝报错求解决

解决外部SD卡文件上传权限被拒的问题

这个坑我之前踩过!你遇到的java.io.FileNotFoundException:/mnt/media_rw/:/open failed: EACCESS(Permission denied)错误,核心原因是Android 10及以上版本的分区存储(Scoped Storage)限制,再加上你用的MediaStore.Files.FileColumns.DATA字段在高版本系统里已经被废弃,直接拿路径访问外部SD卡文件会被系统拦截——哪怕你在Manifest里加了权限也没用。

为什么原来的方法行不通?

  1. 分区存储限制:Android 10开始,应用只能直接访问自己沙箱内的文件,外部SD卡的文件属于公共存储,必须通过ContentResolver或者DocumentFile来操作,直接用路径打开会触发权限拒绝。
  2. DATA字段废弃:MediaStore.Files.FileColumns.DATA在Android Q之后被标记为废弃,返回的路径要么无效,要么没有实际访问权限,尤其是外部SD卡的文件。

推荐解决方案:直接通过Uri读取文件流上传(最稳妥)

放弃获取真实路径的思路,改用ContentResolver.openInputStream()直接读取文件内容,绕开路径访问的权限问题,这也是符合Android现代存储规范的做法。

示例代码:

private void uploadFileViaUri(Uri fileUri) {
    try {
        // 通过ContentResolver获取文件输入流
        InputStream fileInputStream = getContentResolver().openInputStream(fileUri);
        if (fileInputStream == null) {
            // 处理文件获取失败的情况
            return;
        }

        // 这里以OkHttp为例实现上传,你可以替换成自己的上传逻辑
        RequestBody requestBody = RequestBody.create(
            MediaType.parse("application/octet-stream"),
            fileInputStream
        );

        Request uploadRequest = new Request.Builder()
            .url("你的服务器上传接口地址")
            .post(requestBody)
            .build();

        OkHttpClient client = new OkHttpClient();
        client.newCall(uploadRequest).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 上传失败的处理逻辑
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    // 上传成功的处理逻辑
                } else {
                    // 上传返回错误的处理逻辑
                }
                response.close();
            }
        });

    } catch (IOException e) {
        e.printStackTrace();
    }
}

额外注意事项

  • 动态权限申请:即使Manifest里加了权限,Android 6.0+还需要动态申请对应权限:
    • Android 12及以下:READ_EXTERNAL_STORAGE
    • Android 13及以上:根据文件类型申请READ_MEDIA_IMAGES/READ_MEDIA_VIDEO/READ_MEDIA_AUDIO
  • 不要试图绕开分区存储限制(比如用requestLegacyExternalStorage),这只是临时方案,后续版本会被彻底禁用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:26:19