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

Android从图库选PDF转Base64遇文件找不到错误求助

问题分析与解决方案

问题根源

你遇到的FileNotFoundException是因为对Android的Content URI机制理解有误。从图库选择PDF后返回的Uri是内容URI(格式如content:/com.google.android.apps.docs.storage/document/...),它指向的是Content Provider管理的资源,并不是文件系统中的真实路径。你直接用这个URI字符串创建File对象,再用FileInputStream读取,系统自然找不到对应的文件,就像错误日志里显示的:

W/System.err: java.io.FileNotFoundException: content:/com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3D5693 (No such file or directory)

修复步骤与代码示例

正确的做法是通过ContentResolver来获取这个Content URI对应的输入流,再将流转换为Base64字符串。下面是修改后的完整代码:

1. 更新onActivityResult方法

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 7 && resultCode == RESULT_OK && null != data) {
        Uri uri = data.getData();
        if (uri == null) {
            Log.e("Assignment", "获取的文件Uri为空");
            return;
        }
        
        try {
            // 通过ContentResolver打开Uri对应的输入流
            InputStream inputStream = getContentResolver().openInputStream(uri);
            base64String = convertInputStreamToBase64(inputStream);
            
            if (base64String != null) {
                Log.d("Assignment","Base64 String : --> "+base64String );
            }
        } catch (IOException e) {
            Log.e("Assignment", "读取文件失败", e);
        }
    }
}

2. 重写转换方法(支持InputStream)

public static String convertInputStreamToBase64(InputStream inputStream) {
    if (inputStream == null) {
        return null;
    }
    
    byte[] byteArray = null;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
    try {
        byte[] buffer = new byte[1024 * 11]; // 11KB缓冲区
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, bytesRead);
        }
        byteArray = bos.toByteArray();
        Log.e("Byte array", "转换后的字节数组长度:" + byteArray.length);
    } catch (IOException e) {
        Log.e("Assignment", "字节流转换失败", e);
    } finally {
        // 务必关闭流资源,避免内存泄漏
        try {
            inputStream.close();
            bos.close();
        } catch (IOException e) {
            Log.e("Assignment", "关闭流失败", e);
        }
    }
    
    return byteArray != null ? Base64.encodeToString(byteArray, Base64.NO_WRAP) : null;
}

额外注意事项

  • 权限处理:
    • Android 9(API 28)及以下:需要在AndroidManifest.xml中声明<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />,并且在运行时动态请求该权限。
    • Android 10(API 29)及以上:由于分区存储机制,通过系统Intent选择的文件,应用可以直接通过ContentResolver访问,无需申请READ_EXTERNAL_STORAGE权限。
  • 异常处理:代码中增加了空值判断和详细的日志输出,方便排查后续可能出现的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:10:05