Android 存读取权限说明(适配到android 14)

3,511 阅读3分钟

Android 读写权限变更详解:从运行时权限到分区存储

随着 Android 系统不断升级,为了更好地保护用户隐私,Google 对应用读写存储权限的控制越来越严格。尤其从 Android 10 起,“分区存储”(Scoped Storage)成为默认机制,彻底改变了传统文件访问方式。本文将系统梳理 Android 各版本中读写权限的演变,并给出实际开发建议。


一、权限演进时间线

📌 Android 6.0(API 23)— 引入运行时权限机制

首次需要开发者在运行时请求敏感权限,例如:

  • READ_EXTERNAL_STORAGE
  • WRITE_EXTERNAL_STORAGE

开发者必须动态请求权限,才能访问外部存储的公共目录(如 DCIM、Download)。


📌 Android 10(API 29)— 引入 Scoped Storage

  • 默认启用“分区存储”:应用仅能访问自己的沙盒目录。
  • 公共目录访问受限,必须通过 MediaStore 或 SAF。
  • requestLegacyExternalStorage="true" 可临时回退至旧行为(仅在 Android 10 生效)。

📌 Android 11(API 30)— 强制分区存储,新增“全部文件访问”权限

  • requestLegacyExternalStorage 彻底失效。

  • 若应用需要访问整个外部存储,必须申请:

    xml
    复制编辑
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    

    并引导用户前往设置页面授权:

    kotlin
    复制编辑
    if (!Environment.isExternalStorageManager()) {
        val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
        startActivity(intent)
    }
    
  • 此权限适用于文件管理器、杀毒类 App,Google Play 上架需说明充分理由。


📌 Android 13(API 33)— 精细化媒体权限控制

将媒体访问权限拆分为三类:

  • READ_MEDIA_IMAGES
  • READ_MEDIA_VIDEO
  • READ_MEDIA_AUDIO

开发者根据访问类型申请对应权限,而非笼统的 READ_EXTERNAL_STORAGE


📌 Android 14(API 34)— 权限使用透明化

  • 系统增强权限审计,用户可查看 App 权限访问历史。
  • 后台访问媒体的行为进一步限制。
  • SAF 仍然是访问文档类、非媒体文件的推荐方式。

二、常见场景应对策略

需求推荐方式是否需权限
访问 App 私有目录context.getExternalFilesDir()
读取媒体文件(图片/视频/音频)MediaStore + READ_MEDIA_* 权限
读取非媒体文件(如 PDF、ZIP)SAF(文档选择器)
管理整个外部存储MANAGE_EXTERNAL_STORAGE 权限是(Play 审核严格)

三、实践建议

  1. 避免不必要的存储权限,尽量使用 App 专属目录。
  2. 使用 MediaStore 替代传统文件 API 访问媒体资源。
  3. 通过 SAF 让用户主动选择文件/目录,提升安全性与兼容性。
  4. 注意系统版本差异,通过 Build.VERSION.SDK_INT 做兼容处理。

四、处理

  • 低于android 清单声明直接用
  • android 6 到android 12 声明+动态授权
  • android 13到android 14 细分为图片喝适配
  • android 14及以上 需要增加'android.permission.READ_MEDIA_VISUAL_USER_SELECTED'
 fun getMediaPermissions(): MutableList<String> {
    return if (Build.VERSION.SDK_INT >= 34) {
        // Android 14+ 需要全部三个权限
        mutableListOf<String>(
            android.Manifest.permission.READ_MEDIA_IMAGES,
            android.Manifest.permission.READ_MEDIA_VIDEO,
            "android.permission.READ_MEDIA_VISUAL_USER_SELECTED"
        )
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        // Android 13-14 需要两个细分权限
        mutableListOf<String>(
            android.Manifest.permission.READ_MEDIA_IMAGES,
            android.Manifest.permission.READ_MEDIA_VIDEO
        )
    } else {
        // Android 12 及以下只需旧权限
        mutableListOf<String>(android.Manifest.permission.READ_EXTERNAL_STORAGE)
    }
}

五、结语

Android 存储权限的变更是不可逆的趋势。对于开发者而言,虽然这增加了开发复杂度,但也是对用户隐私的尊重。理解这些权限机制,并合理选择数据存储与访问方式,是每个 Android 开发者的必修课。