前言
Android 10 已经发布了很长一段时间了,并且 Android 11 已经有很大一部分人在使用了,那么你的程序对他做了适配吗?
在 10.0 中,作用域存储变得非常重要,这个新的功能颠覆了我们一直惯用外置存储的方式,因此大量的 app 都面临着代码的适配
本篇文章对作用域存储,以及如何进行适配,做了比较详细的介绍
在 7.0 以前我们访问内存卡中的文件时可以通过 Uri.fromFile ,将 File 转换成 Uri 对象,这个 uri 对象表示这本地真实路径。
在 7.0 后,这种通过真实路径来获取的 Uri 被认为是不安全的,所以提供了一种新的解决方案,就是通过 FileProvide 来实现文件的访问,FileProvider 是一种比较特殊的内容提供器,他使用了类似于内容提供器的机制来对数据进行保护。
在7.0以前,访问一个图片如下所示:
String fileName = "defaultImage.jpg";
File file = new File("文件路径", fileName);
Uri uri = Uri.fromFile(file);
7.0后,访问如下所示:
File file = new File(CACHE_IMG, fileName);
Uri imageUri=FileProvider.getUriForFile(activity,"com.sandan.fileprovider", file);//这里进行替换uri的获得方式
android:name="android.support.v4.content.FileProvider"
android:authorities="com.sandan.fileprovider"//这里需要和上面部分字符串相同
android:exported="false"
android:grantUriPermissions="true">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
name="images"
path="" />
//path 表示共享的具体路径,这里为空表示整个SD卡进行共享
然而上面这种真的好吗,对用开发者而且这算是好处吧,但是对用用户而言,上述的无疑一些流氓作用,因为开发者完全可以访问的内存中的所有位置,并作出一些改变,导致 SD 卡中的空间变得非常乱,即使卸载了 app,但是一些垃圾文件却还在内存中。
作用域存储
10.0 中,为了解决上述问题, google 在 Android 10 中加入了作用域功能
什么是作用域呢?就是 Android 系统对 SD 卡做了很大的限制,从 10.0 开始,每个程序只能有权在自己的外置存储空间关联的目录下读取和创建相应的文件,也称作沙箱。获取改目录的代码是:getExternalFilesDir() ,关联的目录路径大致如下:
/storage/emulated/0/Android/data//files
将数据放在这个目录下,你可以使用之前的方法对文件进行读写,不需要作出任何变更和适配。但是这个文件夹中的文件会随着应用卸载而被随之删除。
那如果需要访问其他目录怎么办呢,比如获取相册中的图片,向相册中添加一张图片。为此,Android 系统针对系统文件类型进行了分类:图片,音频,视频 这三类文件可以通过 MediaStore API 来进行访问,这种称为共享空间,其他的系统文件需要使用 系统的文件选择器来进行访问,
另外,如果程序向媒体库写入图片,视频,音频,将会自动用于读写权限,不需要额外申