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

Android 13(API 33)文档/PDF细粒度权限:卸载重装后文件访问问题

解决方案与说明

核心原因

Android 10及以上的分区存储机制下,应用卸载后新安装的实例会被视为完全独立的主体,失去对旧实例在公共目录中创建文件的直接访问权。图片能通过READ_MEDIA_IMAGES访问,是因为该权限针对媒体库中的图片资源,系统会自动将公共目录下的图片纳入媒体库管理;但PDF等文档类文件不在这个权限的覆盖范围内,因此无法直接读取。

一、文档类文件的访问处理方案

针对卸载重装后访问旧存PDF的需求,有三种可行方向:

  • 方案1:使用SAF持久化目录权限(推荐)
    这是Android官方针对分区存储下跨生命周期访问公共目录文件的标准方案。引导用户通过SAF选择Documents/MyAppName目录,调用getContentResolver().takePersistableUriPermission()将访问权限持久化。重装后,只要用户再次授权(或系统保留权限记录),就能通过保存的Uri直接访问该目录下的所有文件,无需遍历整个公共目录。
  • 方案2:利用MediaStore索引文档
    Android 13及以上可申请READ_MEDIA_DOCUMENTS权限,通过MediaStore查询公共目录下的PDF文件。但该权限是全局的(允许访问所有媒体库中的文档),且旧实例创建的PDF需被系统媒体库索引才能被查到——你可以在旧版本应用中添加代码,将创建的PDF插入MediaStore;不过此方案无法精准限制到MyAppName目录,权限范围较宽。
  • 方案3:存储到应用专属外部目录(补充说明)
    若不需要卸载后保留文件,可使用getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)存储,但该目录会随应用卸载被删除,不符合你的场景。

二、是否必须实现SAF?

不是强制,但如果要精准、可靠地访问你之前创建的MyAppName目录下的文件,SAF是最优选择。其他方案要么权限范围过大,要么无法保证文件的可访问性(比如MediaStore索引失败的情况)。

三、验证指定文件夹的权限

1. 基于持久化Uri的权限检查

用户通过SAF授权后,将授权Uri保存到SharedPreferences中。重装后,通过以下代码检查权限:

Uri savedUri = Uri.parse(sharedPreferences.getString("MY_APP_DIR_URI", ""));
int permissionCheck = getContentResolver().checkUriPermission(
    savedUri,
    android.os.Process.myPid(),
    android.os.Process.myUid(),
    Intent.FLAG_GRANT_READ_URI_PERMISSION
);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
    // 拥有该目录的读取权限
} else {
    // 需要重新引导用户授权
}

2. 实际访问验证

直接尝试读取目录下的文件或列出目录内容,若抛出SecurityException则说明无权限:

DocumentFile dir = DocumentFile.fromTreeUri(this, savedUri);
if (dir != null && dir.exists() && dir.canRead()) {
    // 有权限
} else {
    // 无权限
}

内容的提问来源于stack exchange,提问作者akLab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:57:49