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

Android如何访问其他APP共享文件 解决URI scheme is not "file"报错

Android访问WhatsApp共享语音Content URI的正确方案

错误原因

你拿到的audioUri是content://开头的内容URI,并非file://开头的文件URI,这是Android 7.0之后系统强制要求的应用间共享文件的标准格式,禁止直接向外部应用暴露本地文件路径,因此无法直接通过new File(uri.getPath())的方式读取文件。

正确实现方式

Android系统提供了ContentResolver专门用于处理内容URI的读写操作,你不需要转成File对象,直接通过该工具打开输入流即可读取内容。

基础读取流示例

Intent intent = getIntent();
if (Intent.ACTION_SEND.equals(intent.getAction()) && intent.getType() != null && intent.getType().startsWith("audio/")) {
    Uri audioUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
    InputStream audioStream = null;
    try {
        // 直接通过ContentResolver打开输入流
        audioStream = getContentResolver().openInputStream(audioUri);
        // 此处可直接使用输入流进行上传操作
    } catch (FileNotFoundException e) {
        // 处理文件不存在的异常
        e.printStackTrace();
    } finally {
        // 用完及时关闭流避免内存泄漏
        if (audioStream != null) {
            try {
                audioStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

OkHttp POST上传示例

如果用OkHttp作为网络请求库,可直接通过流构造RequestBody无需转存本地:

// 获取音频的MIME类型
String mimeType = getContentResolver().getType(audioUri);
RequestBody audioBody = new RequestBody() {
    @Nullable
    @Override
    public MediaType contentType() {
        // WhatsApp语音默认是ogg格式,可根据实际返回的mimeType调整
        return MediaType.parse(mimeType != null ? mimeType : "audio/ogg");
    }

    @Override
    public void writeTo(@NonNull BufferedSink sink) throws IOException {
        try (InputStream inputStream = getContentResolver().openInputStream(audioUri)) {
            byte[] buffer = new byte[8192];
            int readLen;
            while ((readLen = inputStream.read(buffer)) != -1) {
                sink.write(buffer, 0, readLen);
            }
        }
    }
};
// 构造多部分请求体提交到服务端
MultipartBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("audio_file", "whatsapp_voice.ogg", audioBody)
        .build();

注意事项

  • 无需额外申请存储权限:通过ContentResolver访问其他应用共享的内容URI时,对方应用已经为你授予了临时的访问权限,不需要申请READ_EXTERNAL_STORAGE等存储权限,Android 13及以上版本也不需要申请音频媒体权限
  • 不要尝试将内容URI转换为本地文件路径:不同厂商系统、不同应用的内容URI规则没有统一标准,不存在通用的转换方法,直接操作流是官方推荐的唯一稳妥方案
  • 临时权限有效期:你对该URI的访问权限仅在当前Activity处于活跃状态时有效,如果需要后台处理,需要调用getContentResolver().takePersistableUriPermission()申请长期访问权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 17:36:03