Android11(30)/Android10(29)分区存储-适配方案

2,763 阅读3分钟

在这里插入图片描述

适配Android10分区存储

Android10是分区存储的过度版本,不建议开启分区存储。我们可以android:requestLegacyExternalStorage="true"来关闭Andorid10的分区存储。

<application
    android:requestLegacyExternalStorage="true">
</application>

Android11适配

Android11分区存储强制开启,分区存储开启后,存在两个问题 一个是比如文件管理器咋搞,二是应用的原来的文件如何迁移。

针对第一个问题我们可以申请所有文件的访问权限解决。

针对第二个问题我们可以preserveLegacyExternalStorage标记来解决。

我们一一来分析。

所有文件访问权限

使用所有文件访问权限MANAGE_EXTERNAL_STORAGE,代码基本不需要改动。

MANAGE_EXTERNAL_STORAGE 权限会授予以下权限:

  • 对共享存储空间中的所有文件的读写访问权限。注意/sdcard/Android/media⁠ 目录是共享存储空间的一部分。
  • MediaStore.Files 表的内容的访问权限。
  • 对 USB On-The-Go (OTG) 驱动器和 SD 卡的根目录的访问权限。
  • /Android/data//sdcard/Android/sdcard/Android 的大多数子目录外,对所有内部存储目录⁠的写入权限。此写入权限包括文件路径访问权限。

获得此权限的应用仍然无法访问属于其他应用的应用专用目录,因为这些目录是 Android/data/ 的子目录。

但并不是所用应用都可以申请此权限,如果应用包含与以下示例类似的情形,是允许应用请求MANAGE_EXTERNAL_STORAGE权限的:

  1. 文件管理器
  2. 备份和恢复
  3. 防病毒应用
  4. 文档管理应用

非上述应用类型,申请此权限不一定能被Google Play审核通过。

申请此权限方式:

  1. manifest中声明MANAGE_EXTERNAL_STORAGE
  2. 在代码中检测是否有此权限。Environment.isExternalStorageManager()接口检测。
  3. 检测到没有此权限时,可以通过下列代码,跳转到设置界面,让用户开启此权限。
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.setData(Uri.parse("package:$packageName"));
startActivityForResult(intent, REQUEST_SETTINGS_CODE)

当应用具有 MANAGE_EXTERNAL_STORAGE 权限时,应用就可以使用 MediaStore API 或文件路径访问文件和目录。

数据迁移

在Android11中,因为无法访问sdcard/根目录下的非公共目录的文件,而以前应用喜欢在这里乱搞,而为了让应用迁移数据,Android11提供了preserveLegacyExternalStorage标记,使用此标记后,应用可以使用旧的存储模型,但是此标记只适用于升级,一旦卸载了此标记就失效了。

如果想让用户在卸载应用情况下,也可以迁移数据,可以使用存储访问框架(SAF)选择文件。至于如何使用SAF可以查看下一篇文章。

代码地址:github.com/wfeii/Andro…

参考文档

Android 11 中的存储机制更新

访问应用专属文件

共享存储空间

使用存储访问框架打开文件

管理存储的所有文件

FileProvider的使用

代码地址:github.com/wfeii/Andro…

限于个人水平,有错误请指出,大家共同学习进步!

扫码关注公众号,查看更多内容。 img