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

Android 10下Nearby Connections API无法访问接收文件的问题

别担心,Android 10上用Nearby Connections API实现接收文件并上传完全是可行的,你遇到的问题主要是Scoped Storage(分区存储)限制导致的,咱们一步步来解决:

问题根源分析

Android 10引入的Scoped Storage限制了APP对公共目录(比如Downloads)的直接路径访问,Nearby Connections接收的文件存在Downloads/Nearby下,这时候用asJavaFile()获取File对象会返回null——因为File需要依赖文件路径,但你的APP没有权限直接访问这个公共目录的路径。不过Nearby已经通过ParcelFileDescriptor给了你访问该文件的临时权限,这才是正确的操作入口。

正确的文件读取与上传方案

你不需要通过MediaStore或者文件路径来访问文件,直接利用ParcelFileDescriptor提供的权限操作输入流即可,下面是具体实现:

1. 读取文件流(适用于上传或Bitmap处理)

使用try-with-resources语法自动管理资源,避免权限或资源泄漏问题:

// 获取ParcelFileDescriptor
try (ParcelFileDescriptor pfd = filePayload.asFile().asParcelFileDescriptor()) {
    if (pfd == null) {
        // 处理异常情况
        return;
    }

    // 读取文件输入流
    try (FileInputStream inputStream = new FileInputStream(pfd.getFileDescriptor())) {
        // 如果你需要转成Bitmap:
        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
        // 后续Bitmap操作...

        // 如果你要直接上传到REST API,推荐直接用流上传,不需要转Bitmap
        uploadFileToApi(inputStream);
    }
} catch (IOException e) {
    e.printStackTrace();
}

2. 直接上传到REST API(高效方案)

直接用文件流上传比转成Bitmap再上传更高效,以OkHttp为例:

private void uploadFileToApi(InputStream inputStream) throws IOException {
    OkHttpClient client = new OkHttpClient();

    // 大文件推荐用流式写入,避免一次性读入内存
    RequestBody requestBody = new RequestBody() {
        @Override
        public MediaType contentType() {
            return MediaType.parse("image/jpeg"); // 根据实际文件类型调整
        }

        @Override
        public void writeTo(BufferedSink sink) throws IOException {
            sink.writeAll(Okio.source(inputStream));
        }
    };

    Request request = new Request.Builder()
            .url("你的REST API上传地址")
            .post(requestBody)
            .build();

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

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                // 上传成功逻辑
            } else {
                // 处理错误响应
            }
        }
    });
}
额外注意事项
  • 不要试图通过MediaStore访问这些文件:Nearby保存的文件没有被MediaStore索引,且无扩展名,所以即使扫描也无法被识别,完全没必要走这条路。
  • 依赖版本:你用的com.google.android.gms:play-services-nearby:17.0.0是兼容Android 10的,但可以考虑升级到最新稳定版(比如20.x系列),获取更多bug修复和优化。
  • 权限有效期:ParcelFileDescriptor的权限是临时的,要确保在接收文件的回调生命周期内完成读取/上传操作,不要保存这个对象到后续使用。

这样就能顺利实现接收文件并上传的功能了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:18:14