Android 14适配实战:5个必知的存储权限变更与迁移方案

随着 targetSdk 提升至 34,Android 14 对媒体文件(图片、视频)的访问权限体系进行了重构。最核心的变化是:用户不再被强制授予“全部访问”权限,而是可以只选择部分照片或视频授权给应用。如果不能妥善处理新逻辑,很容易出现媒体读取失败或权限弹窗被系统频繁拦截的问题。下面结合实战,梳理 5 个必知的存储权限变更及迁移方案。

Android 14适配实战:5个必知的存储权限变更与迁移方案
Android 14适配实战:5个必知的存储权限变更与迁移方案

一、READ_EXTERNAL_STORAGE 彻底失效

从 Android 13 开始,系统已用 READ_MEDIA_IMAGESREAD_MEDIA_VIDEOREAD_MEDIA_AUDIO 取代 READ_EXTERNAL_STORAGE。到 Android 14,targetSdk 为 34 的 App 继续依赖旧权限将完全无法读取媒体文件。

迁移做法:在 AndroidManifest.xml 中声明细粒度权限:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />

运行时按需申请:

val permissions = arrayOf(
    Manifest.permission.READ_MEDIA_IMAGES,
    Manifest.permission.READ_MEDIA_VIDEO
)

注意:READ_MEDIA_VISUAL_USER_SELECTED 必须同步声明,它是处理部分授权逻辑的关键。

二、新增部分授权权限

这是 Android 14 最重要的变更。请求读取图片或视频权限时,系统弹窗会提供两个选项:

  • 全部允许:授予 READ_MEDIA_IMAGES / READ_MEDIA_VIDEO。
  • 选择照片和视频:仅授予 READ_MEDIA_VISUAL_USER_SELECTED,应用只能访问用户勾选的媒体。

迁移做法:申请权限后,需分别判断完整授权与部分授权:

val hasFullAccess = checkSelfPermission(
    Manifest.permission.READ_MEDIA_IMAGES
) == PackageManager.PERMISSION_GRANTED
val hasPartialAccess = checkSelfPermission(
    Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
) == PackageManager.PERMISSION_GRANTED

仅有部分授权时,应用可遍历 MediaStore,但只能看到被勾选的媒体。此时不要重复弹窗请求完整权限,应引导用户到系统设置中手动调整。

三、授权弹窗次数受限

在 Android 14 上,如果用户连续两次忽略或拒绝权限请求,系统将不再弹出授权对话框,后续 requestPermissions() 会直接回调 DENIED。应用将失去主动申请权限的机会。

迁移做法:申请前先检查 shouldShowRequestPermissionRationale();若已处于永久拒绝状态,则直接跳转系统设置页。同时,将权限申请放在真正需要读取媒体的时机,避免首次弹窗过早被用户拒绝。

四、Photo Picker 成为首选

Android 14 进一步强化了 Photo Picker 的地位,用户可在独立选择界面中挑选照片或视频,应用无需申请任何存储权限。这既保护隐私,也简化适配。

迁移做法:使用 ActivityResultContracts.PickVisualMedia

val pickMedia = registerForActivityResult(
    ActivityResultContracts.PickVisualMedia()
) { uri ->
    // 通过 ContentResolver 读取 uri
}
pickMedia.launch(PickVisualMediaRequest(
    ActivityResultContracts.PickVisualMedia.ImageAndVideo
))

Photo Picker 在 Android 13+ 为原生支持,Android 11–12 可通过 Google Play 服务回传。面向海外市场时,可将 Photo Picker 作为核心接入方案。

五、MediaStore 访问需动态调整

部分授权模式下,MediaStore 仅返回用户勾选的子集,且结果会随用户在设置中增减勾选而变化。如果应用长期缓存 Uri 或依赖固定路径,极易出现“图片打不开”的问题。

迁移做法:每次读取媒体时,通过 ContentResolver.openFileDescriptor() 实时校验可读性;不要长期缓存媒体 Uri。需要长期使用的文件,应复制到应用私有目录,避免因权限动态变化导致访问失败。

小结

Android 14 的存储权限变更,本质是推动“最小权限”原则落地。适配时应优先使用 Photo Picker,确实需要权限则必须处理部分授权分支,同时谨慎对待弹窗次数限制。按照上述 5 个方案逐步改造,就能平稳兼容 Android 14。

阅读剩余
THE END