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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:06:23