Q Android 10/11(R) 分区存储适配

作者:连续三届村草
Android 10(Q)/11(R) 分区存储适配大部分应用都会请求 ( READ_EXTERNAL_STORAGE ) ( WRITE_EXTERNAL_STORAGE ) 存储权限 , 来做一些诸如在 SD 卡中存储文件或者读取多媒体文件等常规操作 。这些应用可能会在磁盘中存储大量文件 , 即使应用被卸载了还会依然存在 。另外 , 这些应用还可能会读取其他应用的一些敏感文件数据 。
为此 , google 终于下定决心在 Android 10 中引入了分区存储 , 对权限进行场景的细分 , 按需索取 , 并在 Android 11 中进行了进一步的调整 。
Android 存储分区情况Android 中存储可以分为两大类:私有存储和共享存储
  • 私有存储 (Private Storage) : 每个应用在都拥有自己的私有目录 , 其它应用看不到 , 彼此也无法访问到该目录:内部存储私有目录 (/data/data/packageName) ;外部存储私有目录 (/sdcard/Android/data/packageName) , 
  • 共享存储 (Shared Storage) : 存储其他应用可访问文件 ,  包含媒体文件、文档文件以及其他文件 , 对应设备DCIM、Pictures、Alarms、Music、Notifications、Podcasts、Ringtones、Movies、Download等目录 。
Android 10(Q) :Android 10 中主要对共享目录进行了权限详细的划分 , 不再能通过绝对路径访问 。
受影响的接口:
Q Android 10/11(R) 分区存储适配

文章插图
 
访问不同分区的方式:
  1. 私有目录:和以前的版本一致 , 可通过 File() API 访问 , 无需申请权限 。
  2. 共享目录:需要通过MediaStore和Storage Access Framework API 访问 , 视具体情况申请权限 , 下面详细介绍 。
其中 , 对共享目录的权限进行了细分:
  1. 无需申请权限的操作:
    通过 MediaStore API对媒体集、文件集进行媒体/文件的添加、对 自身App 创建的 媒体/文件 进行查询、修改、删除的操作 。
  2. 需要申请READ_EXTERNAL_STORAGE 权限:
    通过 MediaStore API对所有的媒体集进行查询、修改、删除的操作 。
  3. 调用 Storage Access Framework API :
    会启动系统的文件选择器向用户申请操作指定的文件
新的访问方式:
Q Android 10/11(R) 分区存储适配

文章插图
 
Android 11 (R):Android 11 (R) 在 Android 10 (Q) 中分区存储的基础上进行了调整
1. 新增执行批量操作
为实现各种设备之间的一致性并增加用户便利性 , Android 11 向 MediaStore API 中添加了多种方法 。对于希望简化特定媒体文件更改流程(例如在原位置编辑照片)的应用而言 , 这些方法尤为有用 。
MediaStore API 新增的方法
Q Android 10/11(R) 分区存储适配

文章插图
 
系统在调用以上任何一个方法后 , 会构建一个 PendingIntent 对象 。应用调用此 intent 后 , 用户会看到一个对话框 , 请求用户同意应用更新或删除指定的媒体文件 。
2. 使用直接文件路径和原生库访问文件
为了帮助您的应用更顺畅地使用第三方媒体库 , Android 11 允许您使用除 MediaStore API 之外的 API 访问共享存储空间中的媒体文件 。不过 , 您也可以转而选择使用以下任一 API 直接访问媒体文件:
File API 。
原生库 , 例如 fopen() 。
简单来说就是 , 可以通过 File() 等API 访问有权限访问的媒体集了 。
性能:
通过 File () 等直接通过路径访问的 API 实际上也会映射为MediaStore API。
按文件路径顺序读取的时候性能相当;随机读取和写入的时候则会更慢 , 所以还是推荐直接使用 MediaStoreAPI 。
3. 新增权限
MANAGE_EXTERNAL_STORAGE : 类似以前的 READ_EXTERNAL_STORAGE + WRITE_EXTERNAL_STORAGE  , 除了应用专有目录都可以访问 。
应用可通过执行以下操作向用户请求名为所有文件访问权限的特殊应用访问权限:
  1. 在清单中声明 MANAGE_EXTERNAL_STORAGE 权限 。
  2. 使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent 操作将用户引导至一个系统设置页面 , 在该页面上 , 用户可以为您的应用启用以下选项:授予所有文件的管理权限 。