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

Android保存RecyclerView内容为PDF时遇FileNotFoundException求助

解决RecyclerView内容保存PDF时的FileNotFoundException问题

我之前也碰到过一模一样的坑,结合你给出的报错和代码场景,大概率是这几个环节没处理到位,咱们一步步来搞定:

1. 先确认存储权限是否真的生效

你虽然在Manifest里加了WRITE_EXTERNAL_STORAGE,但Android 6.0(API 23)及以上版本需要动态申请权限,只在Manifest里声明是没用的。而且从Android 10(API 29)开始,分区存储政策默认开启,直接写外部公共目录会有更多限制。

给你个动态申请权限的示例代码:

private static final int REQUEST_STORAGE_PERMISSION = 100;

// 在触发保存PDF的动作前先检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
            REQUEST_STORAGE_PERMISSION);
} else {
    // 权限已获取,执行保存PDF的逻辑
    saveRecyclerViewToPdf();
}

// 处理权限申请结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_STORAGE_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            saveRecyclerViewToPdf();
        } else {
            // 用户拒绝权限,提示无法保存
            Toast.makeText(this, "需要存储权限才能保存PDF", Toast.LENGTH_SHORT).show();
        }
    }
}

2. 确保目标目录存在,先创建目录再生成文件

报错里的/storage/emulated/0/MyPDFDocument/这个目录可能根本不存在,系统不会自动帮你创建,所以得先检查并创建目录:

File pdfDir = new File(Environment.getExternalStorageDirectory(), "MyPDFDocument");
if (!pdfDir.exists()) {
    // mkdirs()会创建多级目录,mkdir()只能创建单级
    boolean isDirCreated = pdfDir.mkdirs();
    if (!isDirCreated) {
        // 目录创建失败,提示用户
        Toast.makeText(this, "无法创建存储目录", Toast.LENGTH_SHORT).show();
        return;
    }
}
// 再创建PDF文件
File pdfFile = new File(pdfDir, "questions.pdf");

3. 适配Android 10+的分区存储政策

从Android 10开始,直接写入外部公共目录(比如/storage/emulated/0/下的自定义文件夹)会被限制,更推荐使用应用专属外部存储路径,这个路径不需要申请WRITE_EXTERNAL_STORAGE权限,而且不会被分区存储影响:

// 获取应用专属的文档目录,路径类似/storage/emulated/0/Android/data/你的包名/files/Documents
File pdfDir = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "MyPDFDocument");
if (!pdfDir.exists()) {
    pdfDir.mkdirs();
}
File pdfFile = new File(pdfDir, "questions.pdf");

用这个路径的话,你甚至可以移除Manifest里的WRITE_EXTERNAL_STORAGE权限(如果只针对Android 10+),兼容性更好。

4. 检查PDFDocument的写入逻辑是否正确

最后,确保你在写入PDF的时候,是正确打开了文件输出流:

try {
    PdfDocument document = new PdfDocument();
    // 这里添加你的PDF页面、绘制RecyclerView内容的逻辑...
    
    // 写入文件
    document.writeTo(new FileOutputStream(pdfFile));
    document.close();
    Toast.makeText(this, "PDF保存成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
    e.printStackTrace();
    Toast.makeText(this, "保存失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}

按照这几步排查下来,应该就能解决那个文件找不到的异常了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:00:36