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

Android上传assets文件至Google Drive遇ENOENT异常的排查与解决

问题原因与解决方案

这个坑我之前踩过!你遇到的FileNotFoundException核心原因是:Android项目assets目录下的文件是打包在APK内部的,并非设备文件系统中的真实文件,你直接用java.io.File去访问file:///android_asset/config.json这个路径完全行不通——这个URI只是Android用来访问内部资源的协议,对应不到真实的文件系统路径。

解决思路

要上传assets里的文件,你得先通过Android的AssetManager读取文件的输入流,再把流转换成Google Drive API能识别的内容格式(要么写入临时文件,要么直接用流上传)。

方案一:写入临时文件后上传(兼容性好)

这种方式是把assets里的文件先复制到设备的临时目录,再用这个临时文件来上传,代码修改如下:

try {
    // 1. 获取AssetManager并打开config.json的输入流
    AssetManager assetManager = getAssets();
    InputStream inputStream = assetManager.open("config.json");

    // 2. 创建临时文件
    File tempFile = File.createTempFile("config", ".json", getCacheDir());
    FileOutputStream outputStream = new FileOutputStream(tempFile);

    // 3. 将assets文件流写入临时文件
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) > 0) {
        outputStream.write(buffer, 0, length);
    }
    inputStream.close();
    outputStream.close();

    // 4. 用临时文件上传到Google Drive
    File fileMetadata = new File();
    fileMetadata.setName("config.json");
    fileMetadata.setParents(Collections.singletonList("appDataFolder"));
    FileContent mediaContent = new FileContent("application/json", tempFile);
    
    File file = mService.files().create(fileMetadata, mediaContent)
            .setFields("id")
            .execute();
    Log.d("File ID: ", file.getId());

    // 5. 上传完成后删除临时文件(可选,避免占用空间)
    tempFile.delete();

} catch (IOException e) {
    Log.d("Upload Error: ", e.getMessage());
    e.printStackTrace();
}

方案二:直接用InputStreamContent上传(更高效,无需临时文件)

Google Drive API其实支持直接传入输入流,用InputStreamContent代替FileContent,这样可以省去创建临时文件的步骤:

try {
    // 1. 获取AssetManager并打开文件流
    AssetManager assetManager = getAssets();
    InputStream inputStream = assetManager.open("config.json");

    // 2. 构建InputStreamContent
    InputStreamContent mediaContent = new InputStreamContent("application/json", inputStream);
    // 设置文件长度(可选,但建议设置,避免API处理异常)
    mediaContent.setLength(assetManager.openFd("config.json").getLength());

    // 3. 上传到Google Drive
    File fileMetadata = new File();
    fileMetadata.setName("config.json");
    fileMetadata.setParents(Collections.singletonList("appDataFolder"));
    
    File file = mService.files().create(fileMetadata, mediaContent)
            .setFields("id")
            .execute();
    Log.d("File ID: ", file.getId());

    inputStream.close();

} catch (IOException e) {
    Log.d("Upload Error: ", e.getMessage());
    e.printStackTrace();
}

注意事项

  • 如果你用的是Fragment,获取AssetManager需要用requireContext().getAssets(),而不是直接调用getAssets()
  • 方案二中的setLength步骤很重要,因为有些情况下输入流无法自动获取长度,会导致上传失败
  • 不用额外申请外部存储权限,因为临时文件存在App的缓存目录里,属于App私有空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:13:43