Android 10 Scoped Storage

以前在知乎看到一个问题: 为何安卓系统的文件夹如此凌乱?

相信全部使用 Android 手机的用户都会有这个疑问,打开自带的文件管理器,简直是一脸懵,十万个为何瞬间涌上心头。数据库

为何会有这么多文件夹?缓存

这些文件夹究竟是干吗的?app

这个 app 我明明已经卸载了,为何还有残留文件?设计

这些我看不懂的文件夹,到底能不能删除?3d

万一删除后我手机变砖了怎么办?code

......cdn

在该问题下面,得票最高的回答中的第一句话直中要害:由于开发者不遵照规范视频

今年发布的 Android 10 引入了全新的 Scoped Storage,恰巧 Android Dev Simmit 上面也提到了相关的内容,我会结合大会中的讲解以及我本身的理解,为你们带来 Scoped Storage 的介绍,以及做为开发者来讲,哪些变化是须要咱们注意的。没关注的小伙伴记得关注订阅鸭!若是以为这些文章有点意思,记得分享转发评论点赞鸭!blog

咱们回到最开头的问题:为何 Android 系统文件夹如此混乱?那是由于一旦 App 拿到了 WRITE_EXTERNAL_STORAGE 这个权限以后,就能够在你的根目录下面肆意妄为的创建无数文件夹,根本缘由就是由于开发者不遵照规范。图片

正确的规范

根据官方文档上面的介绍,咱们有四种方式存储数据和文件:内部存储、外部存储、SharedPreferences 和数据库。今天咱们所关注的地方是上图中画红框的两个,即内部存储和外部存储。为了防止有些同窗不清楚这两个存储的定义和目的,我帮你们简单回顾一下。

内部存储

内部存储目录主要分为 4 部分,如上图所示。但咱们经常使用的是文件目录和缓存目录,在 Kotlin 中能够分别经过 filesDir 和 cacheDir 得到。

内部存储用来存储应用的私有文件,且一般是应用的功能相关的必要文件。

其余应用(和用户)不能访问这些文件(除非拥有 Root 访问权限)。如此一来,内部存储便很是适合保存用户无需直接访问的内部应用数据。在文件系统中,系统会为每一个应用提供私有目录,您能够在该目录中整理应用所需的任何文件。当用户卸载您的应用时,保存在内部存储中的文件也将随之移除。

同时内部存储中的缓存目录,帮咱们暂时保留而非永久存储某些数据。系统会在内部存储空间不足时,经过删除这些缓存文件以回收空间。

内部存储目录对应的路径为 /data/data/<包名>/files

内部存储缓存目录对应的路径为 /data/data/<包名>/cache

外部存储

存储于外部存储中的文件意味着,这些文件不是应用程序中功能运行时的必要文件,但从技术上讲用户和其余应用程序均可以访问这些文件,但它们没法为应用程序外部的用户提供价值,此目录可视为内部存储的补充方案。

外部存储对应的路径为 /storage/Android/data/<包名>/files

根据上面的定义,不管内部存储或者外部存储都应该只保存与咱们本身的 App 有关联的数据。例如使用内部存储保存用户信息、使用外部存储保存只有本 App 才能打开的专门格式的文件。须要注意当用户卸载 App 的时候,内部存储和外部存储都会被自动删除。

针对用户行为产生的文件,例以下载的图片、保存的视频等。Google 要求咱们保存在系统公共目录中,这样别的 App 也能访问到这些文件,例如 Pictures、Downloads。这里咱们把用户行为产生的文件分为两大类:多媒体文件和其余文件,官方推荐多媒体文件存放在系统中有专门的目录:Music、Movies、Pictures等,其余文件一概保存在下载目录中:Downloads。

因此到这里我想问一下那些 App 的开发者,大家在开发的时候有读过官方文档吗?

前面我也讲到了在 Android 10.0 以前,存储文件须要获取 WRITE_EXTERNAL_STORAGE 权限,获得这个权限以后,App 就能够经过 Environment.getExternalStorageDirectory() 在根目录下面随意建立文件了,可是(划重点!)Android 10.0 以后就不行了,没想到吧?

Android 10 Scoped Storage

在 Android 10 上面,上图中的两个访问根目录的 API 已经被弃用了。

执行上面这段建立文件夹的代码根本不会其任何做用,这样 App 就再也没法肆意建立文件夹了。咱们以前说了存储文件须要 WRITE_EXTERNAL_STORAGE 权限,在 Android Q 中咱们操做内部和外部存储时,再也不须要声明任何权限,能够直接使用。

同时文档中也明确规定了,多媒体文件须要经过 MediaStore API 访问,其余文件经过系统内置文件管理器访问(Storage Access Framework API)。

由于官方意识到,大多数 App 申请了权限以后,仅是为了操做外部存储目录,因此他们不须要这么多的访问空间,同时也正是由于以前的存储权限逻辑,给了其余 App 漏洞去肆意的乱建文件夹,从而引起了用户数据泄漏。因此 Google 取消了外部存储权限限制,同时也增长了公共目录的访问限制。

因此 Scoped Storage 的设计原则就是:更好的管理文件、保护 App 的数据、保护用户的数据。

说了这么多,咱们来看一下 Scoped Storage 具体有哪些修改,以及咱们须要注意的地方,这里我列出来一些重要的点供你们参考:

固然 Scoped Storage 也不是立刻强制执行,Google 给了必定的缓冲期让开发者们有时间充分适配。

  1. targetSDK = 29, 默认开启 Scoped Storage, 但可经过在 manifest 里添加 requestLegacyExternalStorage = true 关闭

  2. targetSDK < 29, 默认不开启 Scoped Storage, 但可经过在 manifest 里添加requestLegacyExternalStorage = false 打开

若是你所作的 App 属于文件管理器或数据备份应用,你须要在 Google Play 提交申请信息,得到白名单权限以后才能够访问除本身应用之外的文件。

这是官方依据 Scoped Storage 所划分的存储区域访问图。目前 Scoped Storage 部份内容还在调整,因此在如今的 Android 10 上面并无强制执行,这一切调整会在 Android 下一个 Release 上完善并开启。

关于 Scoped Storage 的信息很杂也很碎,可是咱们只须要关注两点就行了:

  1. 多媒体文件须要使用 MediaStore API 访问

  2. 其余文件须要使用 Storage Access Framework API 访问

因此咱们 App 以后的适配工做也须要密切关注这两个 API 的变化和更新,因为我尚未仔细阅读这两个 API 的文档作适配,因此暂时也就没有多余的适配代码分享给你们,避免错误使用误导你们,若是有哪些同窗已经开始了适配工做,欢迎写一篇文章并私信我,和你们一块儿分享你在适配过程当中的心得。

明天的推送中,我会为你们带来关于【Fragment 的如今以及将来】的最近进展,没关注的小伙伴记得关注我以及个人公众号【Android丨Kotlin】鸭!若是以为这些文章有点意思,记得分享转发评论点赞鸭!!

我是 wanbo 你们加油!

相关文章
相关标签/搜索