Android使用Intent通过Uri打开PDF显示空白 问题求助
安卓调用系统Intent打开PDF显示空白排查方案
核心问题排查点
- 补充FileProvider临时读取权限
你当前代码没有给目标PDF阅读器授予Uri的临时访问权限,这是最常见的空白原因,需要给Intent添加FLAG_GRANT_READ_URI_PERMISSION标签:
- 补充FileProvider临时读取权限
pdfIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_GRANT_READ_URI_PERMISSION
- 校验Base64解码逻辑
确认后端返回的PDF Base64编码格式和你解码使用的flag匹配:
当前你使用的android.util.Base64.DEFAULT会自动处理换行符,如果后端返回的是URL Safe格式的Base64,需要改为Base64.URL_SAFE解码,否则解码后的字节流会损坏,生成的PDF本身就是无效文件。
你可以在写入文件后,把内部存储的对应PDF文件导出到电脑,手动打开验证文件本身是否正常,排除文件生成环节的问题。
- 校验Base64解码逻辑
- 校验FileProvider配置
检查res/xml/provider_paths.xml中是否配置了当前PDF文件的存储路径:
你存在应用内部filesDir/documents目录下,需要确保配置里有对应规则:
- 校验FileProvider配置
<paths> <files-path name="documents" path="documents/" /> </paths>
同时确认AndroidManifest.xml里FileProvider的声明配置正确,authority值和你代码中BuildConfig.APPLICATION_ID + ".provider"完全一致。
- 补充空值拦截逻辑
你当前参数pdfFile是可空类型,没有做空校验就直接读取filename和file字段,若参数为空会生成无效空白文件,建议在方法开头先做判空拦截:
- 补充空值拦截逻辑
if (pdfFile == null || pdfFile.file.isNullOrEmpty() || pdfFile.filename.isNullOrEmpty()) { Toast.makeText(requireContext(), "PDF文件无效", Toast.LENGTH_SHORT).show() return }
- 排除阅读器兼容性问题
部分系统自带的PDF阅读器兼容性较差,可以先安装第三方PDF阅读器测试打开是否正常,排除是阅读器本身的适配问题。
- 排除阅读器兼容性问题
修复后参考代码
private fun pdfConverter(pdfFile: DtoSymptomCheckerPdf?) { // 先做参数校验 if (pdfFile == null || pdfFile.file.isNullOrEmpty() || pdfFile.filename.isNullOrEmpty()) { Toast.makeText(requireContext(), "PDF文件无效", Toast.LENGTH_SHORT).show() return } val context = requireContext() val documentsPath = File(context.filesDir, "documents") if(!documentsPath.exists()){ documentsPath.mkdirs() // 建议用mkdirs,避免父目录不存在的问题 } val file = File(documentsPath, pdfFile.filename) try { val pdfAsBytes: ByteArray = android.util.Base64.decode(pdfFile.file, Base64.DEFAULT) FileOutputStream(file,false).use { os -> // use自动关流,不用手动flush close os.write(pdfAsBytes) } // 校验文件大小,过小大概率是无效文件 if (file.length() < 100) { Toast.makeText(requireContext(), "PDF文件生成失败", Toast.LENGTH_SHORT).show() return } val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file) val pdfIntent = Intent(Intent.ACTION_VIEW) pdfIntent.setDataAndType(uri, "application/pdf") // 补充读权限 pdfIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_GRANT_READ_URI_PERMISSION startActivity(pdfIntent) } catch (e: Exception) { when(e) { is ActivityNotFoundException -> Toast.makeText(context, "设备未安装PDF阅读器", Toast.LENGTH_SHORT).show() is IllegalArgumentException -> Toast.makeText(context, "Base64解码失败", Toast.LENGTH_SHORT).show() else -> Toast.makeText(context, "打开PDF失败:${e.message}", Toast.LENGTH_SHORT).show() } } }
内容的提问来源于stack exchange,提问作者Mario Muresean
相关产品推荐
相关产品推荐

