Android11适配

1.分区存储

1.1.背景

Android 11 进一步增强了平台功能,为外部存储设备上的应用和用户数据提供了更好的保护。作为这项工作的一部分,平台引入了进一步的改进,以简化向分区存储的转换。
为了让用户更好地控制自己的文件,保护用户隐私数据,并限制文件混乱情况,Android 11在分区存储基础上限制了应用访问其他应用的文件。

分区存储将存储空间分为两部分:

●  公共目录:Downloads、Documents、Pictures 、DCIM、Movies、Music、Ringtones等

    ■ 公共目录的文件在App卸载后,不会删除
    ■ 可以通过SAF、MediaStore接口访问
    ■ 拥有权限,也能通过路径直接访问
●  应用专属目录
    ■ 应用专属目录只能自己直接访问
    ■ App卸载,数据会清除。

1.2兼容影响

当您将应用更新为以 Android 11 为目标平台后,您将无法使用requestLegacyExternalStorage,而且也没有其他标记可以提供停用分区存储。
分区存储对于App访问存储方式、App数据存放以及App间数据共享,都产生很大影响。
而Environment.getExternalStorageDirectory() 在 API Level 29 开始已被弃用,开发者应迁移至 Context#getExternalFilesDir(String), MediaStore, 或Intent#ACTION_OPEN_DOCUMENT。

1.3 适配

1.3.1应用targetSdkVersion

应用targetSdkVersion >= 30,都会强制打开分区存储,同时requestLegacyExternalStorage将会无效。如果您需要对已安装的应用进行适配分区存储的数据迁移,则可以在应用更新到目标平台为Android 11版本后仍暂时保留原有的存储模式。请在应用的manifest中设置preserveLegacyExternalStorage属性为true,应用更新到android 11可以保留存储继承模式。

1.3.2应用私有目录访问

对于运行在Android 11的应用,无论targetSdkVersion是什么都无法访问Emulated存储中的其他应用私有目录(Android/data)。SAF(Storage Access Framework)同样也禁止访问应用私有目录。
某些应用的核心用例需要访问大量的文件,如文件管理操作或备份和恢复操作。这些应用可通过执行以下操作获取“所有文件访问权限”:

●  声明 MANAGE_EXTERNAL_STORAGE 权限。
●  使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent 操作将用户引导至一个系统设置页面,在该页面上,用户可以为您的应用启用以下选项:授予所有文件的管理权限。

●  注意:获得此权限的应用仍然无法访问属于其他应用的应用专用目录。这些目录在存储卷上显示为 Android/data/ 的子目录。

1.3.3 直接路径访问

注意:使用直接路径和原生库保存媒体文件时,应用的性能会略有下降。请尽可能改用MediaStore API。

数据和文件存储概览  |  Android 开发者  |  Android Developers
Android 11 中的存储机制更新  |  Android 开发者  |  Android Developers

1.3.4App运行模式

在Android 11版本上,系统会根据App targetSdkVersion决定运行模式:
●  App targetSdkVersion >= 30,默认为分区存储,并且无法取消。

●  App targetSdkVersion < 29,默认为分区存储,可通过requestLegacyExternalStorage更改

应用可以通过AndroidManifest.xml设置requestLegacyExternalStorage, 选择对应的方式:
 


●  App targetSdkVersion < 29,声明了READ_EXTERNAL_STORAGE,默认Legacy Mode
●  App在下列条件都成立时
   ■  声明 MANAGE_EXTERNAL_STORAGE 权限。
   ■  使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent 操作将用户引导至一个系统设置页面,在该页面上,用户可以为您的应用启用以下选项:授予所有文件的管理权限。
App拥有外置存储空间Read、Write权限。但是通过Environment.isExternalStorageLegacy接口判断,返回不一定是Legacy Mode。
判断当前App运行什么模式,可以通过这个API判断:
Environment.isExternalStorageLegacy() (added in api 29);

true表示以传统的兼容方式运行,false表示以分区存储运行

1.3.5 读写公共目录

App启动分区存储后,只能直接访问自身专属目录,所以Android 11,提供了两种访问公共目录的方法(通过MediaStore定义的Uri、通过SAF接口)

1.3.5.1. 通过MediaStore定义的Uri
MediaStore提供了下列几种类型的访问Uri,通过查找对应Uri数据,达到访问的目的。
下列每种类型又分为三种Uri,Internal、External、可移动存储:

●Audio
   ■  Internal: MediaStore.Audio.Media.INTERNAL_CONTENT_URI

       content://media/internal/audio/media。

   ■  External: MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

       content://media/external/audio/media。

   ■  可移动存储: MediaStore.Audio.Media.getContentUri

       content://media/<volumeName>/audio/media。
●  Video
   ■    Internal: MediaStore.Video.Media.INTERNAL_CONTENT_URI
         content://media/internal/video/media。
   ■    External: MediaStore.Video.Media.EXTERNAL_CONTENT_URI
         content://media/external/video/media。
   ■    可移动存储: MediaStore.Video.Media.getContentUri
         content://media/<volumeName>/video/media。
●  Image
   ■    Internal: MediaStore.Images.Media.INTERNAL_CONTENT_URI
         content://media/internal/images/media。
   ■    External: MediaStore.Images.Media.EXTERNAL_CONTENT_URI
         content://media/external/images/media。
   ■    可移动存储: MediaStore.Images.Media.getContentUri
         content://media/<volumeName>/images/media。
●  File
   ■    MediaStore. Files.Media.getContentUri
         content://media/<volumeName>/file。
●  Downloads
   ■    Internal: MediaStore.Downloads.INTERNAL_CONTENT_URI
         content://media/internal/downloads。
   ■    External: MediaStore.Downloads.EXTERNAL_CONTENT_URI
content://media/external/downloads。
   ■    可移动存储: MediaStore.Downloads.getContentUri
content://media/<volumeName>/downloads。

1.3.5.1.1. 获取所有的Volume

1.3.5.2.通过SAF接口
SAF,即Storage Access Framework,通过选择不同的DocumentsProvider,提供给用户打开、浏览文件。在Android 11上,无法通过SAF选择外部存储器External Storage根目录、Downloads目录以及App专属目录(Android/data、Android/obb)。

Android默认提供了下列DocumentsProvider:
MediaDocumentsProvider、ExternalStorageProvider、 DownloadStorageProvider。
他们之间差异是:

1.3.6访问应用的专属目录

访问应用专属目录分为两种情况,第一是访问App自身专属目录,第二是访问其他App的专属目录。
1.3.6.1.App自身专属目录
   Android 11获取应用专属目录
   ■  获取Media接口:getExternalMediaDirs
   ■  获取Cache接口:getExternalCacheDirs
   ■  获取Obb接口:getObbDirs
   ■  获取Data接口:getExternalFilesDirs
   应用专属目录App本身可以直接访问。
1.3.6.2.其他App的专属目录
Android 11,App无法访问其他App的专属目录(Android/data)。如果需要访问其他应用专属目录数据,需要被访问者按照下列方法来提供:
1.3.6.2.1.通过SAF文件
●  共享App自定义DocumentsProvider
    App自定义DocumentsProvider需要做以下步骤:
    a)指定DocumentsProvider

1.3.6.2.其他App的专属目录
Android 11,App无法访问其他App的专属目录(Android/data)。如果需要访问其他应用专属目录数据,需要被访问者按照下列方法来提供:
1.3.3.2.1.通过SAF文件
●  共享App自定义DocumentsProvider
    App自定义DocumentsProvider需要做以下步骤:
    a)指定DocumentsProvider

   b)DocumentsProvider实现基本接口

●  访问App通过ACTION_OPEN_DOCUMENT,启动浏览

1.3.3.2.2.共享App实现FileProvider

1.3.3.2.3.App自定义私有Provider

1.3.7.App Scopted Storage,访问权限总结
App访问不同目录的权限总结如下:

1.3.8.直接路径访问
Android 11上,App可以直接通过路径访问拥有权限的文件。例如,可以通过路径访问自己通过MediaStore新建的Images。

因为现在分区存储公共区域,是基于FUSE来实现,通过直接路径访问会经过下列路程:访问者 →  FUSE →  KERNEL---->MediaProvider(得到真实数据)--->KERNEL →  FUSE→访问者,比之前SDCARDFS多了几个步骤,所以会导致一些性能问题。建议通过MediaStore访问。

1.3.9.宽泛权限
Android 11,提供了两种宽泛权限,需要注意的是这两种宽泛权限是无法访问其他应用的专属目录:
●  MANAGE_EXTERNAL_STORAGE
    App拥有此权限,能够读写公共区域内所有文件,并且可以访问MediaStore.Files里面的所有文件。此权限能够满足清理、手机搬家、杀毒、文件管理这些类型应用需求。
    App可以通过下列方式申请:

配置文件中先添加该权限

●  System Gallery Role
    Gallery Role只能是预装的系统应用,通过系统配置才能成为Gallery Role。拥有Gallery Role,通过MediaStore读写多媒体文件不用弹框用户交互

1.3.10.应用卸载
●  如果App在AndroidManifest.xml中声明:android:hasFragileUserData="true"
    卸载应用会有提示是否保留App数据:

●  App存放到公共目录下的文件,卸载后,如果需要修改,需要用户重新授予权限

1.3.11.App数据迁移
App打开分区存储,会涉及到数据的迁移,不然会导致旧数据无法使用。可以从下面几方面着手数据迁移:
●  App对于可以存放到公共目录的文件,可以通过MediaStore接口存放到对应类型的公共目录中。
●  对于私有数据,可以存放到App私有目录。
●  迁移后数据的共享访问
    ■  对于存放到公共目录的文件,其他App可以通过MediaStore访问。
    ■  对于无法存放在公共目录文件,可以放置在私有目录,通过Uri共享给其他App访问。

1.3.12.MediaStore Queries
在使用MediaStore进行query动作的时候,使用Projection时,Column Name要在MediaStore中定义好的。

1.3.13.新建测试使用可移动存储
如果一个设备没有可移动的存储,可以使用下面的方法新建虚拟存储设备:
●  adb shell sm set-virtual-disk true
●  在设置 -> 存储 -> Virtual SD,进行初始化

1.4.规范愿景
我们希望三方应用,尤其是TOP应用,能够按照分区存储的规范,将用户数据(例如图片、视频、音频等)保存在公共目录,把应用数据保存在SDCARD私有目录,以更好地保护外部存储上的应用和用户数据。而Google正在更新 Google Play 政策,以确保应用只在其真正需要获取位置信息时才请求授权。

2.1.2应用缓存

1 背景
在Android 11上,应用默认不能删除其他应用的缓存文件,即使申请了MANAGE_EXTERNAL_STORAGE权限。
Google官网特性介绍:
Android 11 中的存储机制更新  |  Android 开发者  |  Android Developers
2 兼容性影响
文件管理类,清理类或其他具有缓存清理功能应用,清除其他应用缓存功能失效。
3 适配指导
1 使用intent action - ACTION_MANAGE_STORAGE 检查可用存储空间大小。
2 如果可用的存储空间不足,使用 intent action —ACTION_CLEAR_APP_CACHE 呈现UI界面让用户确认后,触发所有应用的缓存清理。
注意:执行 ACTION_CLEAR_APP_CACHE 触发的缓存清理,会清理所有应用的缓存,同时大量的IO操作也会加剧电量消耗,如非必要,请不要使用。

2.1.3文件访问限制
1 背景
如果您的应用以 Android 11 为目标平台并使用存储访问框架 (SAF),则您无法再使用ACTION_OPEN_DOCUMENT和ACTION_OPEN_DOCUMENT_TREE操作访问某些目录,具体限制如下:
1 访问目录
您无法再使用ACTION_OPEN_DOCUMENT_TREE 操作来请求访问以下目录:
Downloads根目录。
设备制造商认为可靠的各个 SD 卡根目录,无论该卡是模拟卡还是可移除的卡。
内部存储根目录
2 访问文件
您无法再使用 ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT操作来请求用户从以下目录中选择单独的文件:
Android/data/ 目录及其所有子目录。
Android/obb/ 目录及其所有子目录。

2 兼容性影响
如果应用指定AndroidR为运行平台,则不再能使用SAF访问上述指出的目录,可能导致您的业务逻辑异常。
3 适配指导
执行以下操作来确认行为变更是否已对应用生效:
1 将targetSdkVersion指向Android 11
2 确保已经打开RESTRICT_STORAGE_ACCESS_FRAMEWORK 兼容性开关(使用方法见文档兼容性调试工具部分) 。
3 使用 intent action - ACTION_OPEN_DOCUMENT_TREE ,检查Downloads目录是否显示并呈灰显状态。
4 使用intent action - ACTION_OPEN_DOCUMENT检查Android/data/和Android/obb/目录是否都不显示。

2.1.4存储权限变更
1 背景
Android 11 引入了与存储权限相关的以下变更。
1 不管应用的目标 SDK 版本是什么,以下变更均会在 Android 11 中生效:
●  存储运行时权限已重命名为文件和媒体。
●  如果应用未选择停用分区存储,并且请求 READ_EXTERNAL_STORAGE 权限,则用户会看到不同于 Android 10 的对话框。该对话框会指示应用正在请求访问相册和多媒体。如下图所示

在系统设置的设置 > 隐私 > 权限管理器 > 文件和媒体 页面中,用户可以查看已授予权限READ_EXTERNAL_STORAGE应用,应用会列在允许存储所有文件下。
注意:如果您的应用以Android 11 为目标运行平台,上述允许存储所有文件代表的是对文件的只读权限。

2 以 Android 11 为目标平台
如果应用以 Android 11 为目标平台,则WRITE_EXTERNAL_STORAGE 权限和 WRITE_MEDIA_STORAGE 特许权限将不再提供任何其他访问权限。
2 兼容性影响
1 存储运行时权限UI发生变更。
2 WRITE_EXTERNAL_STORAGE 权限和 WRITE_MEDIA_STORAGE 在targetSdkVersion 指定为30时,发生变更。

2.1.5所有文件访问
1背景
有些应用主要功能就是访问手机存储文件,例如文件管理器、备份&恢复出厂操作。在Android 11 版本上,需要通过声明MANAGE_EXTERNAL_STORAGE权限来获取“Allowed for all files(允许存储所有文件)”权限,进行功能实现。
此权限被授予后,拥有以下权限:
1.“共享存储”上的所有文件的读写权限
共享存储说明:
共享存储空间概览  |  Android 开发者  |  Android Developers
2. MediaStore.Files表内容
注意:即便授予了所有文件访问权限,应用也不能获取其他app的应用专属的文件。
应用专属目录:
访问应用专属文件  |  Android 开发者  |  Android Developers
2兼容性影响
文件管理类应用或其他需要对较多存储文件进行扫描和处理的应用,可能会功能失效。
3 适配指导
Google适配指导:
Android 11 中的存储机制更新  |  Android 开发者  |  Android Developers

1 AndroidManifest.xml中声明MANAGE_EXTERNAL_STORAGE权限。
2 使用intent action - ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 跳转到系统设置页面,引导用户开启“Allowed for all files(允许存储所有文件)”权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/828672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(C++) share_ptr 之循环引用

文章目录 &#x1f6a9;前言&#x1f6a9;循环引用&#x1f579;️例子1Code&#x1f62d;shared_ptr &#xff08;错误&#xff09;&#x1f602;weak_ptr &#xff08;正确&#xff09;&#x1f62d;unique_ptr &#xff08;错误&#xff09; &#x1f579;️例子2Code &…

Vu3+QuaggaJs实现web页面识别条形码

一、什么是QuaggaJs QuaggaJS是一个基于JavaScript的开源图像识别库&#xff0c;可用于识别条形码。 QuaggaJs的作用主要体现在以下几个方面&#xff1a; 实时图像处理与识别&#xff1a;QuaggaJs是一款基于JavaScript的开源库&#xff0c;它允许在Web浏览器中实现实时的图像…

LORA详解

参考论文&#xff1a; low rank adaption of llm 背景介绍&#xff1a; 自然语言处理的一个重要范式包括对一般领域数据的大规模预训练和对特定任务或领域的适应处理。在自然语言处理中的许多应用依赖于将一个大规模的预训练语言模型适配到多个下游应用上。这种适配通常是通过…

DiT论文精读Scalable Diffusion Models with Transformers CVPR2023

Scalable Diffusion Models with Transformers CVPR2023 Abstract idea 将UNet架构用Transformer代替。并且分析其可扩展性。 并且实验证明通过增加transformer的宽度和深度&#xff0c;有效降低FID 我们最大的DiT-XL/2模型在classconditional ImageNet 512、512和256、256基…

小程序AI智能名片S2B2C商城系统:四大主流商业模式深度解析与实战案例分享

在私域电商迅速崛起的大背景下&#xff0c;小程序AI智能名片S2B2C商城系统以其独特的商业模式和强大的功能&#xff0c;正成为品牌商们争相探索的新领域。在这一系统中&#xff0c;拼团模式、会员电商、社区团购和KOC营销等四种主流模式&#xff0c;为品牌商提供了多样化的营销…

【文章转载】Lance Martin的关于RAG的笔记

转载自微博黄建同学 从头开始学习 RAG&#xff0c;看Lance Martin的这篇笔记就行了&#xff0c;包含了十几篇论文和开源实现&#xff01; —— 这是一组简短的&#xff08;5-10 分钟视频&#xff09;和笔记&#xff0c;解释了我最喜欢的十几篇 RAG 论文。我自己尝试实现每个想…

C# GetField 方法应用实例

目录 关于 C# Type 类 GetField 方法应用 应用举例 心理CT设计题 类设计 DPCT类实现代码 小结 关于 C# Type 类 Type表示类型声明&#xff1a;类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义&#xff0c;以及开放或封闭构造的泛型类型。调用 t…

WPS-EXCEL:快速删除多个线条对象

问题图 我需要将线条快速删除 方法一:使用定位对象功能 使用定位功能&#xff1a;按Ctrl G打开定位对话框。在对话框中&#xff0c;点击“定位条件”。 定位对象&#xff1a;在定位条件对话框中&#xff0c;勾选“对象”选项&#xff0c;然后点击“确定”。这样&#xff0c;…

CTF之变量1

拿到题目发现是一个php代码&#xff0c;意思是用get方式获取args参数。 至于下面那个正则表达式怎么绕过暂且不知&#xff0c;但是题目最上面告诉我们lag In the variable ! &#xff08;意思是flag就在变量中&#xff09;。 那我们就传入全局变量globals&#xff08;&#xf…

户外指南——时代产物

分类 一级分类&#xff1a; 衣&#xff1a;除了上述提到的&#xff0c;还包括衣物的材质、款式多样性、与身份地位的关联等。 食&#xff1a;还包括饮食的文化内涵、地域特色、对特殊饮食需求的满足等。 住&#xff1a;还包括居住空间的合理布局、智能家居的应用、与自然环境…

B2B企业如何做好谷歌Google广告推广营销布局?

当今全球化的商业环境中&#xff0c;B2B企业要想在激烈的市场竞争中脱颖而出&#xff0c;拓展海外市场成为了必经之路。而谷歌Google广告&#xff0c;作为全球最大的在线广告平台&#xff0c;无疑是企业触达全球潜在客户的黄金钥匙。云衔科技通过专业服务助力企业轻松开户与高效…

Java苍穹外卖01-开发环境搭建(Git、nginx)-Swagger-员工管理

一、开发环境搭建 1.项目架构 2.Git版本管理 在IDEA中可以一键搭建并commit&#xff0c;当Git远程仓库搭建后就可以push 3.前后端联调 Builder注解&#xff1a; 加了注解后就可以通过这样的方式创建对象 接收传入的是dto对象&#xff0c;传出去的对象为vo对象 4.nginx反向…

4.18.2 EfficientViT:具有级联组注意力的内存高效Vision Transformer

现有Transformer模型的速度通常受到内存低效操作的限制&#xff0c;尤其是MHSA&#xff08;多头自注意力&#xff09;中的张量整形和逐元素函数。 设计了一种具有三明治布局的新构建块&#xff0c;即在高效FFN&#xff08;前馈&#xff09;层之间使用单个内存绑定的MHSA&#x…

【STM32HAL库】外部中断

目录 一、中断简介 二、NVIC 1.寄存器 2.工作原理 3.优先级 4.使用NVIC 三、EXTI 1.简介 2.AFIO&#xff1a;复用功能IO&#xff0c;主要用于重映射和外部中断映射配置​编辑 3. 中断使用 4.HAL库配置使用 一、中断简介 中断的意义&#xff1a;高效处理紧急程序&#xff0c;不会…

SPRD Android 14 通过属性控制系统设置显示双栏或者单栏

SPRD Android 14 通过属性控制系统设置显示双栏或者单栏 第一步 确认有添加静态库第二步 验证第三步 修改源码在合适的地方配置 ro.product.is_support_SettingsSplitEnabled 即可。第一步 确认有添加静态库 --- a/packages/apps/Settings/Android.bp +++ b/packages/apps/Set…

php反序列化逃逸

php反序列化逃逸 逃逸是php中反序列化时的恶意利用&#xff0c;以ctf为例演示 第一段演示 逃逸为ctf反序列化的内容&#xff0c;主要是对序列化对象进行过滤&#xff0c;其中替换串长度不一致&#xff0c;造成字符逃逸。攻击者可以构造恶意的payload&#xff0c;改变对象中的…

MATLAB循环语句

MATLAB 循环语句 在某些情况下&#xff0c;您需要多次执行一个代码块。通常&#xff0c;语句是按顺序执行的。首先执行函数中的第一条语句&#xff0c;然后执行第二条&#xff0c;依此类推。 编程语言提供了各种控制结构&#xff0c;允许更复杂的执行路径。 循环语句允许我们…

猫头虎分享已解决Bug || **Error: ‘Promise‘ is undefined**

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

3.8设计模式——State 状态模式(行为型)

意图 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 结构 Context&#xff08;上下文&#xff09;定义客户感兴趣的接口&#xff1b;维护一个ConcreteState子类的实例&#xff0c;这个实例定义当前状态。State&#xff08;状态&#xff09;定义…

4 -25

1 100个英语单词两篇六级阅读 2 cf补题&#xff1b; 3 仿b站项目看源码 debug分析业务。 上了一天课&#xff0c;晚上去健身。 物理备课&#xff0c;周六去上课腻。 五一回来毛泽东思想期末考试&#xff0c;概率论期中考试。