Android 分区存储(沙盒存储)适配总结

目录

一、分区存储概念

1.外部存储分类

2.分区存储如何影响文件访问

二、分区适配方案

1. 应用分区存储的文件访问规定

(1).应用专属目录--私有目录

(2).共享目录文件--公有目录

2.MediaStore API介绍

3.Storage Access Framework介绍

三、所有文件访问权限

四、总结


一、分区存储概念

1.外部存储分类

可以分为两大类:私有存储和共享存储。

分类路径特点

私有存储(私有目录)

/storage/emulated/0/Android/data/包名1)每个应用在内部存储种都拥有自己的私有目录,其它应用看不到,彼此也无法访问到该目录;2)私有目录存放 app 的私有文件,会随着 App的卸载而删除。
共享存储(公有目录)/storage/emulated/0/Downloads(Pictures))1)除了私有存储以外,其他的一切都被认定是共享存储,比如:Downloads、Documents、Pictures 、DCIM、Movies、Music 等;2)公有目录下的文件不会跟随 APP 卸载而被删除

     

               

        在 Android 10 以前,只要程序获得了 READ_EXTERNAL_STORAGE 权限,就可以随意读取外部的存储公有目录;同时只要程序获得了WRITE_EXTERNAL_STORAGE权限,就可以随意在写入外部存储的公有目录上新建文件或文件夹。 

        Android 10 开始引进的 Android 系统存储管理机制-- 分区存储,意在限制APP对外部存储中公有目录的使用;APP可以查看外部存储设备内以下类型的文件,无需请求任何与存储相关的用户权限:

应用外部特定目录中(私有目录)的文件(使用getExternalFilesDir()访问)。
应用自己创建的照片、视频和音频(通过MediaStore访问)。

2.分区存储如何影响文件访问

类型位置访问应用自己生成的文件访问其他应用生成的文件访问方法卸载是否删除文件
私有存储应用特定的目录(私有目录)无需权限无法直接访问getExternalFilesDir()获取到属于应用自己的文件路径
共享存储Photo/ Video/Audio/无需权限需要权限
READ EXTERNAL STORAGE
MediaStore Api
共享存储Downloads无需权限无需权限通过存储访问框架SAF,加载系统文件选择器

二、分区适配方案

1. 应用分区存储的文件访问规定

(1).应用专属目录--私有目录

每个应用向自己的私有目录读写文件,不需要读写权限。
应用即使获取了读写权限,也无法访问其他应用的私有目录。
私有文件目录具体路径:storage/emulated/0/android/data/packageName/…

访问方式:
this.getExternalCacheDir() this.getExternalFilesDir(Environment.DOWNLOADS)

(2).共享目录文件--公有目录

共享目录文件需要通过MediaStore API或者Storage Access Framework方式访问

①MediaStore API 在共享目录指定目录下创建文件或者访问应用自己创建文件,不需要申请任何存储权限
②MediaStore API访问其他应用在共享目录创建的媒体文件(图片、音频、视频),
需要申请存储权限,未申请存储权限,通过ContentResolver查询不到文件Uri,即使通过其他方式获取到文件Uri,读取或创建文件会抛出异常;
③MediaStore API不能够访问其他应用创建的非媒体文件(pdf、office、doc、txt等), 只能够通过Storage Access Framework方式访问。

2.MediaStore API介绍

       Android 系统会自动扫描外部存储空间,将媒体文件按类型添加到系统预定义的 Images、Videos、Audio files、Downloaded files 集合中。

       Android 10 通过 MediaStore.Images、MediaStore.Video、MediaStore.Audio、MediaStore.Downloads 访问相对应共享目录文件资源。

MediaStore API创建文件

       Android 10版本 MeidaStore API只允许在共享目录指定目录创建文件, 非指定目录创建文件会抛出IllegalArgumentException, 创建文件目录汇总如下:

媒体类型Uri默认创建目录允许存储文件
lmagecontent://media/external/images/mediaPictures只能放图片
Audiocontent://media/external/audio/mediaMusic只能放图片
Videocontent://media/external/video/mediaMovies只能放视频
Downloadcontent://media/external/downloadsDownload任意类型

             MediaStore.Downloads.EXTERNAL_CONTENT_URI是Android10版本新增API,用于创建、访问非媒体文件,需要注意的是:虽然获取了存储权限,但是依然不能够删除和修改其他应用的文件。

MediaStore API 文件访问

3.Storage Access Framework介绍

      Android 10 里唯一一种访问其他应用创建的非媒体文件的途径是使用存储访问框架 (Storage Access Framework) 提供的文档选择器。SAF 访问外部存储空间的共享目录的文件不需要申请任何权限,原因很简单,它需要启动系统的文件选择器向用户申请操作指定的文件,有用户交互过程的动作本身就是权限管控了,自然也就可以不用预先申请权限。

 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
 intent.setType("*/*");//设置类型--任意类型
 intent.addCategory(Intent.CATEGORY_OPENABLE);
 startActivityForResult(intent, READ_REQUEST_CODE);

三、所有文件访问权限

       分区存储机制很好地规范了 Android App 的存储行为,让它们读自己该读的,写自己该写的。但是有的应用天生就需要对 SD 卡进行全方位的访问,比如各种文件浏览器、垃圾清理软件等等,

      对此,Android 11 引入了一个新的权限:

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

   同时如果要申请此权限,需要打开设置界面,让用户手动设置: 

Intent intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
startActivityForResult(intent, 10010)

      这个权限就是用来获取所有文件的管理权限,那么是不是可以直接申请这个权限就可以了呢?是可以的,不过应用市场不让上架…所以大部分 App 是不允许使用这个权限的。

      如果是文件管理器、备份及存储类的应用。你需要在 Google Play Developer Console 上填写声明表格说明为什么需要 MANAGE_EXTERNAL_STORAGE 权限,提交之后会被审核是否加入白名单,一旦加入成功以后,您的应用就可以向用户索要权限了,如果用户也同意您应用的访问权限请求,MadiaStore 访问将不再过滤,包括非媒体库文件。但是获得此权限的应用仍然无法访问这些目录在存储卷上显示为 Android/data/ 的子目录,也就是属于其他应用的应用专属目录。

四、总结

Android10分区存储之后:

①特定于应用的目录(私有目录) –> 无需权限 –> 访问方法 getExternalFilesDir () –> 卸载应用时移除文件
②访问其他应用创建的--媒体集合 (照片、视频、音频) –> 需要权限 READ_EXTERNAL_STORAGE –> 访问方法 MediaStore –> 卸载应用时不移除文件
③访问其他应用创建的非media文件--下载内容(文档和电子书籍)–> 无需权限 –> 存储访问框架(加载系统的文件选择器)–> 卸载应用时不移除文件

Android11又将READ_EXTERNAL_STORAGE 细化为三个权限

 总结下 Android 10 之后分区存储机制带来的数据访问的特点和区分:

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据引用中提到的Android Q的文件存储机制修改,Android Q之后的版本将应用程序限制在自己的盒目录和公共媒体文件中进行访问,而无法直接操作非盒路径下的数据。引用中提到,Android Q提供了requestLegacyExternalStorage机制来帮助应用程序继续读写存储卡,但这是一个过渡期的解决方案。所以根据引用中给出的解决方法,如果您想在Android Q及以上版本中继续访问非盒路径下的数据,可以在AndroidManifest.xml文件的application标签中添加android:requestLegacyExternalStorage="true"来进行临时解决。因此,根据以上信息,storage/emulator/0/Android属于非盒路径。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [解决Android10读取不到/sdcard/、/storage/emulated/0/文件的问题](https://blog.csdn.net/a518618718/article/details/127777692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [处理Android SDK 29及以上版本,读取不到/storage/emulated/0/(/storage/sdcard/)路径下文件问题](https://blog.csdn.net/SDDY_xiao/article/details/121054399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值