Android 12使用FileProvider分享PDF遇权限拒绝异常求解决
问题排查与修正
核心问题分析
异常中的uid=1000对应Android系统进程(如媒体扫描服务或分享选择器的系统组件),它尝试访问你通过FileProvider暴露的URI,但临时权限未正确覆盖该进程,或是Intent.createChooser未将权限传递给最终目标应用,导致权限拒绝。
具体修正方案
方案1:完善权限授予逻辑,覆盖所有目标应用
获取所有可处理分享请求的应用包名,逐个为其授予URI读取权限,同时保留Intent的权限标记:
val pdfFile = File(requireContext().cacheDir, pdfFileName) val fileUri: Uri = FileProvider.getUriForFile( requireContext().applicationContext, "${BuildConfig.APPLICATION_ID}.provider", // 用BuildConfig确保与Manifest的authorities完全一致 pdfFile ) val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_STREAM, fileUri) type = "application/pdf" addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } // 获取所有能处理该Intent的应用信息 val resolveInfoList = requireContext().packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY) resolveInfoList.forEach { info -> requireContext().grantUriPermission( info.activityInfo.packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION ) } // 启动分享选择器 startActivity(Intent.createChooser(intent, "Share Document"))
方案2:添加Android 12+专属权限标记
Android 12新增Intent.FLAG_GRANT_PREFIX_URI_PERMISSION,可让权限覆盖URI的前缀路径,解决系统进程访问时的权限问题:
val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_STREAM, fileUri) type = "application/pdf" // 组合两个权限标记 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) }
方案3:确保配置一致性
替换代码中requireContext().packageName.toString() + ".provider"为BuildConfig.APPLICATION_ID + ".provider",避免多渠道打包等场景下packageName与applicationId不一致的问题,保证和Manifest中配置的authorities完全匹配。
额外注意事项
- 绝对不要将FileProvider设置为
android:exported="true",这会引发严重安全风险,违背FileProvider的设计初衷。 - 若PDF文件体积较大,建议在后台线程中完成文件准备操作,避免阻塞UI线程。
内容的提问来源于stack exchange,提问作者Ollie
相关产品推荐
相关产品推荐

