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
相关产品推荐
相关产品推荐

