当前位置: 首页 > news >正文

Android系统不同版本存储权限

一、Android存储简介

Android系统分为内部存储和外部存储

从Android6.0开始不断在更新存储(读写)权限,除了在AndroidManifest.xml文件里声明,app运行时也要动态申请使用对应的权限

提醒:应用私有存储不需要动态申请权限

  1. Context.getFileDir();获取内置存储下的文件目录,可以用来保存不能公开给其他应用的一些敏感数据如用户个人信息。
    路径为:/data/data/应用包名/files/
  2. Context.getCacheDir();获取内置存储下的缓存目录,可以用来保存一些缓存文件如图片,当内置存储的空间不足时将系统自动被清除。
    路径为: /data/data/应用包名/cache/

点击查看数据和文件存储概览

二、Android系统不同版本访问存储权限

点击查看安全准则
点击查看Android中的权限
点击查看权限清单列表

2.1 Android 6.0

点击查看Android6.0 变更

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

2.2 Android 7.0

点击查看Android7.0变更

2.2.1 权限更改
2.2.1.1系统权限更改

为了提高私有文件的安全性,以 Android 7.0 或更高版本为目标平台的应用的私有目录限制了访问权限 (0700)。此设置可防止私有文件的元数据泄露,如其大小或存在。此权限更改具有多种副作用:

  1. 私有文件的文件权限不应再由所有者放宽,如果尝试使用 MODE_WORLD_READABLE 和/或 MODE_WORLD_WRITEABLE 放宽文件权限,将会触发 SecurityException。
  2. 传递软件包网域外的 file:// URI 可能会给接收器留下无法访问的路径。因此,尝试传递 file:// URI 会触发 FileUriExposedException。建议使用 FileProvider 来共享非公开文件的内容。
  3. DownloadManager 无法再按文件名分享私密存储的文件。旧版应用在访问 COLUMN_LOCAL_FILENAME 时可能最终采用无法访问的路径。以 Android 7.0 或更高版本为目标平台的应用在尝试访问 COLUMN_LOCAL_FILENAME 时会触发 SecurityException。使用 DownloadManager.Request.setDestinationInExternalFilesDir() 或 DownloadManager.Request.setDestinationInExternalPublicDir() 将下载位置设置为公开位置的旧版应用仍然可以访问 COLUMN_LOCAL_FILENAME 中的路径,但我们强烈建议不要使用此方法。访问 DownloadManager 公开的文件的首选方法是使用 ContentResolver.openFileDescriptor()。
2.2.1.2在应用间共享文件

对于以 Android 7.0 为目标平台的应用,Android 框架会强制执行 StrictMode API 政策,该政策禁止在应用外部公开 file:// URI。如果包含文件 URI 的 intent 离开您的应用,应用会失败,并出现 FileUriExposedException 异常。
如需在应用之间共享文件,您应发送 content:// URI 并授予对该 URI 的临时访问权限。如需授予此权限,最简单的方法是使用 FileProvider 类。如需详细了解权限和共享文件,请参阅共享文件。

在Android 7.0之前不需要授予临时权限直接使用以下代码:
Uri.fromFile( File file );

Android 7.0 之后,如果通过uri使用未被授权的其他应用的文件,会报错误“FileUriExposedException 异常

Android 7.0之后就需要使生成具有临时权限uri,需要借助Android FileProvider 组件,Android FileProvider 组件会根据一个xml配置文件中指定的内容生成文件的内容 URI。

具体步骤

  1. 在res目录里定义xml文件,然后创建一个provider.xml文件,示例如下图
    在这里插入图片描述
  2. 在AndroidManifest.xml里添加provider配置信息,示例如下
    在这里插入图片描述

provider_paths.xml文件代码

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-pathname="beta_external_path"path="Download/" /><external-pathname="beta_external_files_path"path="Android/data/" /><external-pathname="download"path="." /><external-pathname="sdcard_files"path="Android/data/com/exemple/app/images" /><external-files-pathname="camera_has_sdcard"path="Android/data/com/exemple/app/images" /><files-pathname="camera_no_sdcard"path="Android/data/com/exemple/app/other" /><external-pathname="files_root"path="Android/data/com/exemple/app" /><external-pathname="external_storage_root"path="." />
</paths>

点击查看官网提供的FileProvider
点击查看provider

file_paths.xml文件

<paths xmlns:android="http://schemas.android.com/apk/res/android"><files-path name="my_images" path="images/"/>...
</paths>

自定义FileProvider
MyFileProvider.java代码

public class MyFileProvider extends FileProvider {public MyFileProvider() {super(R.xml.file_paths)}
}
<manifest>...<application>...<providerandroid:name="com.sample.MyFileProvider"android:authorities="com.mydomain.fileprovider"android:exported="false"android:grantUriPermissions="true">...</provider>...</application>
</manifest>
2.2.2 从授权的URI获取文件

使用 FileProvider生成 URI
Android FileProvider 组件提供了 getUriForFile() 方法生成URI,代码:

FileProvider.getUriForFile(@NonNull Context context, @NonNull String authority,@NonNull File file) {}
 File imagePath = new File(Context.getFilesDir(), "my_images"); File newFile = new File(imagePath, "default_image.jpg"); Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile); 

使用示例代码

public void takePicture() {
//        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Intent takePictureIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);// 打开系统相机连续拍多张图片if (takePictureIntent.resolveActivity(getPackageManager()) != null) {File cameraFile = FileUtils.createCameraFile(this);cameraPath = cameraFile.getAbsolutePath();mUri = Uri.fromFile(new File(cameraPath));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(MainActivity.this, fileprovider, cameraFile));takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);} else {takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);}startActivityForResult(takePictureIntent, REQUEST_CODE_TAKEPICTURES);}}

2.3 Android 8.0

点击查看Android 8.0 行为变更

2.4 Android 9.0

点击查看Android9.0 行为变更

2.5 Android 10.0

点击查看Android 10 中的隐私权变更

Android 10(API 级别 29)引入了多项功能和行为变更,以更好地保护用户隐私。这些变更让用户更清楚地了解并更好地控制其数据及为应用提供的功能。这些功能可能意味着,应用所依赖的特定行为或数据的行为方式可能与旧版平台不同。如果您的应用遵循当前处理用户数据的最佳实践,那么对应用的影响应该微乎其微。

2.5.1 外部存储访问权限范围限定为应用文件和媒体

默认情况下,以 Android 10 及更高版本为目标平台的应用在访问外部存储空间时被分区访问(即分区存储)。此类应用可以查看外部存储设备中的以下类型的文件,而无需请求任何与存储相关的用户权限:

  • 应用专属目录中的文件(使用 getExternalFilesDir() 访问)。
  • 应用创建的照片、视频和音频片段(通过媒体库访问)。

application中通过添加android:requestLegacyExternalStorage="true"的配置
来兼容使用低版本的存储.。
在Android11上面是无效了,只能添加动态申请权限。

2.6 Android 11

点击查看Android 11 中的隐私权
点击查看Android 11 中的存储更新

2.6.1强制执行分区存储

在 Android 11 上运行但以 Android 10(API 级别 29)为目标平台的应用仍可请求 requestLegacyExternalStorage 属性。应用可以利用此标记暂时停用与分区存储相关的变更,例如授予对不同目录和不同类型的媒体文件的访问权限。当您将应用更新为以 Android 11 为目标平台后,系统会忽略 requestLegacyExternalStorage 标记。

2.6.2保持与 Android 10 的兼容性

如果应用在 Android 10 设备上运行时选择退出分区存储,建议您继续在应用的清单文件中将 requestLegacyExternalStorage 设为 true。这样,应用就可以在运行 Android 10 的设备上继续按预期运

2.6.3将数据迁移到使用分区存储时可见的目录

如果您的应用使用旧版存储模型且之前以 Android 10 或更低版本为目标平台,您可能会将数据存储到启用分区存储模型后您的应用无法访问的目录中。在以 Android 11 为目标平台之前,请将数据迁移到与分区存储兼容的目录。

2.6.4权限

Android 11 引入了与存储权限相关的以下变更。
以任何版本为目标平台
不管应用的目标 SDK 版本是什么,以下变更均会在 Android 11 中生效:

  • 存储运行时权限已重命名为文件和媒体。
  • 如果您的应用未停用分区存储并且请求 READ_EXTERNAL_STORAGE 权限,用户会看到不同于 Android 10 的对话框。该对话框表明您的应用正在请求访问照片和媒体,如图 下图 所示。
    在这里插入图片描述
    用户可以在系统设置中查看哪些应用具有 READ_EXTERNAL_STORAGE 权限。在设置 > 隐私 > 权限管理器 > 文件和媒体页面上,具有该权限的每个应用都列在允许存储所有文件下。如果您的应用以 Android 11 为目标平台,请记住,对“所有文件”的这种访问权限是只读访问权限。如需使用此应用读取和写入共享的存储空间中的所有文件,需要具有所有文件访问权限。

以 Android 11 为目标平台

如果应用以 Android 11 为目标平台,那么 WRITE_EXTERNAL_STORAGE 权限和 WRITE_MEDIA_STORAGE 特许权限将不再提供任何其他访问权限。

请注意,在搭载 Android 10(API 级别 29)或更高版本的设备上,您的应用可以提供明确定义的媒体集合,例如 MediaStore.Downloads,而无需请求任何存储相关权限。详细了解如何在处理应用中的媒体文件时仅请求必要的权限。

所有文件访问权限

绝大多数需要共享存储空间访问权限的应用都可以遵循共享媒体文件和共享非媒体文件方面的最佳做法。但是,某些应用的核心用例需要广泛访问设备上的文件,但无法采用注重隐私保护的存储最佳做法高效地完成这些操作。对于这些情况,Android 提供了一种名为“所有文件访问权限”的特殊应用访问权限。如需了解详情,请参阅有关如何管理存储设备上的所有文件的指南。

注意 :如果您要将应用发布到 Google Play,请仔细阅读通知。如果您的应用以 Android 11 为目标平台并声明了所有文件访问权限,那么您在 Google Play 上发布和更新应用会受到影响。

2.7 Android 12

点击查看Android 12行为变更:所有应用
性能

2.7.1 受限应用待机模式存储分区

Android 11(API 级别 30)引入了受限存储分区作为应用待机模式存储分区。从 Android 12 开始,此存储分区默认处于活跃状态。在所有存储分区中,受限存储分区的优先级最低(限制最高)。存储分区按优先级从高到低的顺序排列如下:

  1. 活跃:应用目前正在使用中,或者最近刚刚使用过。
  2. 工作集:会定期使用应用。
  3. 常用:会经常使用应用,但不是每天都使用。
  4. 极少使用:不经常使用应用。
  5. 受限:应用会消耗大量的系统资源,或表现出不良行为。

除了使用模式之外,系统还会考虑应用的行为,以决定是否要将您的应用放在受限存储分区中。

如果您的应用更负责地使用系统资源,就不太可能被放在受限存储分区中。此外,如果用户直接与您的应用互动,系统会将其放在一个限制较少的存储分区中。

2.7.2 检查您的应用是否在受限存储分区中

如需检查系统是否已将您的应用放在受限存储分区中,请调用 getAppStandbyBucket()。如果此方法的返回值为 STANDBY_BUCKET_RESTRICTED,则您的应用在受限存储分区中。

2.8 Android 13

点击查看Android 13行为变更:所有应用
点击查看Android 13 功能和变更列表

2.9 Android 14

点击查看Android 14 功能和变更列表
点击查看点击查看Android 14 行为变更:所有应用

2.10 Android 15

点击查看Android 15 功能和变更列表
点击查看Android 15 行为变更:所有应用

三、推荐阅读

Android存储文件路径的区别

相关文章:

Android系统不同版本存储权限

一、Android存储简介 Android系统分为内部存储和外部存储 从Android6.0开始不断在更新存储&#xff08;读写&#xff09;权限&#xff0c;除了在AndroidManifest.xml文件里声明&#xff0c;app运行时也要动态申请使用对应的权限 提醒&#xff1a;应用私有存储不需要动态申请权…...

ue引擎游戏开发笔记(41)——行为树的建立(2)--丰富ai行为:巡逻后返回原处

1.需求分析&#xff1a; 就敌人ai而言&#xff0c;追踪到敌人有可能丢失目标&#xff0c;丢失目标后应该能返回原来位置&#xff0c;实现这一功能。 2.操作实现&#xff1a; 1.思路&#xff1a;利用clear value函数&#xff0c;禁用掉当前的追踪功能&#xff0c;执行之后的返…...

Linux quotacheck命令教程:如何检查和修复文件系统的磁盘配额(附案例详解和注意事项)

Linux quotacheck命令介绍 quotacheck命令是用于扫描文件系统以检查磁盘配额的一致性。它生成、检查和修复配额文件。这个命令通常在系统引导时运行&#xff0c;或者在手动更改了配额设置后运行。 Linux quotacheck命令适用的Linux版本 quotacheck命令在大多数Linux发行版中…...

Response对象的学习

Response对象在Web开发中是一个重要的概念&#xff0c;它代表了服务器对客户端请求的响应。当客户端&#xff08;如浏览器&#xff09;向服务器发送一个请求后&#xff0c;服务器会生成一个Response对象&#xff0c;其中包含了服务器返回给客户端的数据、状态码、响应头等信息。…...

QCustomplot---动态图

QCustomplot绘制动态曲线图-游标及鼠标跟踪显示数值_qcustomplot 游标-CSDN博客 m_timer new QTimer(this);connect(m_timer,SIGNAL(timeout()),this,SLOT(slotTimeout()));m_timer->start(50); void MainWindow::slotTimeout() {static int p0;static int i0;double m,m1…...

蛋白聚乙二醇化修饰检测试剂盒

蛋白多肽因其高生物活性、高特异性等优点备受药物开发商和研究者的青睐。但分子量大、亲水性强、稳定性差等劣势限制了蛋白多肽在临床上的应用&#xff0c;特别是蛋白多肽作为一种异源蛋白具有很强的免疫原性&#xff0c;容易被机体免疫系统识别并清除&#xff0c;导致药物的血…...

[Algorithm][回溯][字母大小写全排列][优美的排列][N皇后]详细讲解

目录 1.字母大小写全排列1.题目链接2.算法原理详解3.代码实现 2.优美的排列1.题目链接2.算法原理详解3.代码实现 3.N 皇后1.题目链接2.算法原理详解3.代码实现 1.字母大小写全排列 1.题目链接 字母大小写全排列 2.算法原理详解 本题逻辑与子集大致相同 思路一&#xff1a;每…...

.NET_NLog

步骤 1. 添加依赖 ①Microsoft.Extensions.DependencyInjection ②NLog.Extensions.Logging&#xff08;或Microsoft.Extensions.Logging.___&#xff09; Tutorial NLog/NLog Wiki GitHub 2.添加nlog.config文件(默认名称, 可改为其他名称, 但需要另行配置) 文件的基础…...

Linux查看进程命令ps和top

Linux 是一种自由和开放源代码的操作系统&#xff0c;它的使用在全球范围内非常广泛。在 Linux 中&#xff0c;进程是操作系统中最重要的组成部分之一&#xff0c;它代表了正在运行的程序。了解如何查看正在运行的进程是非常重要的&#xff0c;因为它可以帮助你了解系统的运行状…...

深入解析Wireshark1:从捕获到分析,一网打尽数据包之旅

目录 1 认识 Wireshark 1.1 选择网卡界面 1.2 捕获数据包界面 1.3 常用按钮功能介绍 1.4 数据包列表信息 1.5 数据包详细信息 2 数据包案例分析 Frame: 物理层的数据帧概况 Ethernet II: 数据链路层以太网帧头部信息 Internet Protocol Version 4 (IPv4): 互联网层IP…...

C++语法|指向类成员(成员变量和成员方法)的指针及其相关应用场景

文章目录 1.基本语法指向成员变量的指针示例 指向成员函数的指针示例 注意事项 2.应用场景泛型编程和模板&#xff1a;通用成员访问打印函数回调机制和事件处理&#xff1a;基于简单GUI框架的事件处理 1.基本语法 指向类成员的指针是一种特殊的指针类型&#xff0c;用于指向类…...

【C语言】通讯录系统实现

目录 1、通讯录系统介绍 2、代码分装 3、代码实现步骤 3.1制作菜单函数以及游戏运行逻辑流程 3.2、封装人的信息PeoInfo以及通讯录Contact结构体类型 3.3、初始化通讯录InitContact函数 3.4、增加联系人AddContact函数 3.5、显示所有联系人ShowContact函数 3.6、删除联系人D…...

(delphi11最新学习资料) Object Pascal 学习笔记---第12章第1节 ( 类静态方法与Windows API回调)

12.1.4 类静态方法与Windows API回调 ​ 静态类方法没有隐藏的Self参数意味着静态类方法可以作为回调函数传递给操作系统&#xff08;例如&#xff0c;在Windows上&#xff09;。实际上&#xff0c;您可以声明一个具有stdcall调用约定的静态类方法&#xff0c;并将其用作直接的…...

第一个Rust程序

在安装好Rust以后&#xff0c;我们就可以编写程序了。 首先&#xff0c;我们执行下面的命令&#xff0c;尽量让你的rust版本和我的版本相同&#xff0c;或者比我的版本大。 zhangdapengzhangdapeng:~$ cargo --version cargo 1.78.0 (54d8815d0 2024-03-26) zhangdapengzhangd…...

【LInux】<基础IO> 文件操作 | 文件描述符 | 重定向

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…...

MySQL--增、删、改、查,

数据库的概述、发展、现状、历史、分类 MySQL关系型数据库、架构&#xff08;C/S&#xff09; window系统安装MySQL数据库 Linux系统【选学】 数据库对象——数据库&#xff08;database&#xff09; show、create、drop命令 数据库对象——表&#xff08;table&#xff…...

5.12学习总结

一.JAVA聊天室项目 文件发送 使用 Java Socket 实现聊天内容或文件的传输的原理如下&#xff1a; 服务器端启动&#xff1a;聊天室的服务器端在指定的端口上监听客户端的连接。它创建一个 ServerSocket 对象&#xff0c;并通过调用 accept() 方法等待客户端的连接请求。客户…...

ansible利用playbook 部署lamp架构

搭建参考&#xff1a;ansible批量运维管理-CSDN博客 定义ansible主机清单 [rootansible-server ~]# vim /etc/hosts 192.168.200.129 host01 192.168.200.130 host02 [rootansible-server ~]# vim /etc/ansible/hosts [webserver] host01 host02 在ansible端编写index.html…...

SPI通信(使用SPI读写W25Q64)

SPI通信协议 • SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线 • 四根通信线&#xff1a; SCLK:串行时钟线&#xff0c;用来提供时钟信号的。 MOSI:主机输出&#xff0c;从机输入 MISO:从机输出&#xff0c;主机输入 SS:…...

<sa8650>QCX Usecase 使用详解—拓扑图 XML 定义

<sa8650>QCX Usecase 使用详解—拓扑图 XML 定义 一 、前言二、拓扑图 XML 定义2.1 <Node, port, link>2.2 < XML prolog >2.3 < UsecaseDef >2.4 < Usecase>2.5 < Targets>2.5.1 < Target>2.5.2 < Range>2.6 < Pipeline>2.…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...