如何打开通过ContentResolver保存的PDF文件?执行代码后显示空白页
问题分析与修复方案
你的代码存在几个关键问题,导致PDF文件保存后打开显示空白:
- 临时读取权限未授予:通过
Intent.ACTION_VIEW打开Uri时,没有给目标PDF阅读器应用授予临时读取权限,对方无法访问文件内容 - IS_PENDING状态更新错误:更新待处理状态时误用了
MediaStore.Downloads.IS_PENDING,但插入文件时用的是MediaStore.Files的列,列名不匹配会导致文件可能仍处于锁定状态 - 文件读取不完整:
fis.read(bytes)无法保证一次性读取全部文件内容,大文件会出现写入截断的情况 - Intent未明确MIME类型:系统可能无法精准识别文件类型,导致启动的应用不兼容
修正后的完整代码
public void saveToExternalStorage(File file, Context context) { ContentValues cv = new ContentValues(); String fileName = "order" + new Date().getTime() + ".pdf"; cv.put(MediaStore.Files.FileColumns.DISPLAY_NAME, fileName); cv.put(MediaStore.Files.FileColumns.MIME_TYPE, "application/pdf"); cv.put(MediaStore.Files.FileColumns.RELATIVE_PATH, "Documents"); cv.put(MediaStore.Files.FileColumns.IS_PENDING, 1); ContentResolver resolver = context.getContentResolver(); Uri uri = resolver.insert(MediaStore.Files.getContentUri("external"), cv); if (uri != null) { InputStream fis = null; OutputStream outputStream = null; try { outputStream = resolver.openOutputStream(uri); fis = new FileInputStream(file); // 循环读写避免大文件读取不完整 byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } Log.e("file", "saved " + uri); // 修正IS_PENDING列名,与插入时保持一致 cv.clear(); cv.put(MediaStore.Files.FileColumns.IS_PENDING, 0); resolver.update(uri, cv, null, null); // 构建Intent时添加权限并明确MIME类型 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri, "application/pdf"); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 非Activity环境下需添加新任务标记 if (!(context instanceof Activity)) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } context.startActivity(intent); } catch (Exception e) { Log.e("error", Log.getStackTraceString(e.fillInStackTrace())); } finally { // 确保流关闭,避免资源泄漏 try { if (fis != null) fis.close(); if (outputStream != null) outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
额外注意事项
- Android 10及以上无需申请
WRITE_EXTERNAL_STORAGE权限,低版本需确保已申请并授权 - 模拟器若未安装PDF阅读器应用,也会显示空白,建议安装Adobe Acrobat等测试应用
- 避免使用
(int) file.length(),文件超过2GB会出现整数溢出问题,循环读写方式可规避此风险
内容的提问来源于stack exchange,提问作者Sahil Manchanda
相关产品推荐
相关产品推荐

