Android系统不同版本存储权限

news2024/9/22 17:30:43

一、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-path
        name="beta_external_path"
        path="Download/" />
    <external-path
        name="beta_external_files_path"
        path="Android/data/" />

    <external-path
        name="download"
        path="." />

    <external-path
        name="sdcard_files"
        path="Android/data/com/exemple/app/images" />

    <external-files-path
        name="camera_has_sdcard"
        path="Android/data/com/exemple/app/images" />

    <files-path
        name="camera_no_sdcard"
        path="Android/data/com/exemple/app/other" />

    <external-path
        name="files_root"
        path="Android/data/com/exemple/app" />

    <external-path
        name="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>
       ...
       <provider
           android: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存储文件路径的区别

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

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

相关文章

100m/s高速轧制钢材 八轴测径仪检测毫无压力

关键词&#xff1a;八轴测径仪,在线测径仪,钢材测径仪,高速轧制 随着技术的提升&#xff0c;钢材的生产速度越来越快&#xff0c;一些高速生产的钢材&#xff0c;生产速度甚至达到了100m/s&#xff0c;这是一个非常快的速度。 如果汽车以120公里/小时的速度行驶&#xff0c;那么…

Shell之高效文本处理命令

目录 一、排序命令—sort 基本语法 常用选项 二、去重命令—uniq 基本语法 常用选项 三、替换命令—tr 基本语法&#xff1a; 常用选项 四、裁剪命令—cut 基本语法&#xff1a; 常用选项 字符串分片 五、拆分命令—split 基本语法&#xff1a; 六、 文件…

Pathlib,一个不怕迷路的 Python 向导

大家好&#xff01;我是爱摸鱼的小鸿&#xff0c;关注我&#xff0c;收看每期的编程干货。 一个简单的库&#xff0c;也许能够开启我们的智慧之门&#xff0c; 一个普通的方法&#xff0c;也许能在危急时刻挽救我们于水深火热&#xff0c; 一个新颖的思维方式&#xff0c;也许能…

手机怎么下载别人直播间视频

手机下载直播视频&#xff0c;您需要按照以下步骤进行操作&#xff1a; 1. 打开直播平台&#xff0c;获取正在直播的链接&#xff0c;就是直播间的地址&#xff0c;然后粘贴在直接视频解析工具里&#xff0c;就可以同步下载直播视频画面。 2. 获取直播视频解析工具方法&#…

张驰咨询:六西格玛黑带项目的成功关键

六西格玛黑带项目通常被认为是比较难的&#xff0c;因为它们涉及的问题通常比较复杂&#xff0c;可能需要较长时间的分析、实验和协调。然而&#xff0c;通过遵循一定的步骤和方法&#xff0c;可以有效地实施六西格玛黑带项目。 以下是实施六西格玛黑带项目的基本步骤&#x…

字符串_字符函数和字符串函数

C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在常量字符串中或者字符数组中。 字符串常量适用于那些对它不做修改的字符串函数。 目录 1.函数介绍 1.1strlen 1.1.1strlen函数的模拟实现 1.2strcpy 1.2.1st…

【ARMv8/v9 系统寄存器 6 -- EL 异常等级判定寄存器 CurrentEL 使用详细将介绍】

文章目录 ARMv8/v9 EL 等级获取EL 等级获取函数实现EL 等级获取测试 ARMv8/v9 EL 等级获取 下面这个宏定义是用于ARMv8/v9架构下&#xff0c;通过汇编语言检查当前执行在哪个异常级别&#xff08;Exception Level&#xff0c;EL&#xff09;并据此跳转到不同的标签。 异常级别…

【ARMv8/v9 系统寄存器 5 -- ARMv8 Cache 控制寄存器 SCTRL_EL1 使用详细介绍】

关于ARM Cache 详细学习推荐专栏&#xff1a; 【ARM Cache 专栏】 【ARM ACE Bus 与 Cache 专栏】 文章目录 ARMv8/v9 Cache 设置寄存器ARMv8 指令 Cache 使能函数测试代码 ARMv8/v9 Cache 设置寄存器 关于寄存器SCTRL_EL1 的详细介绍见文章&#xff1a;【ARMv8/v9 异常模型入…

Linux---编辑器vim的认识与简单配置

前言 我们在自己的电脑上所用的编译软件&#xff0c;就拿vs2022来说&#xff0c;我们可以在上面写C/C语言、python、甚至java也可以在上面进行编译&#xff0c;这种既可以用来编辑、运行编译&#xff0c;又可以支持很多种语言的编译器是一种集成式开发环境&#xff0c;集众多于…

Java入门基础学习笔记24——While循环和do-while循环

1、While循环&#xff1a; 例1&#xff1a; package cn.ensource.loop;public class WhileDemo3 {public static void main(String[] args) {// 目标&#xff1a;掌握while循环的书写格式&#xff0c;以及理解其执行流程// 需求&#xff1a;打印多行Hello Worldint i 0;while…

【python量化交易】—— Alpha选股策略 - Qteasy自定义交易策略【附源码】

使用qteasy创建并回测Alpha选股交易策略 使用qteasy创建并回测Alpha选股交易策略策略思想第一种自定义策略设置方法&#xff0c;使用持仓数据和选股数据直接生成比例交易信号PS信号&#xff1a;第二种自定义策略设置方法&#xff0c;使用PT交易信号设置持仓目标&#xff1a;第三…

springboot004网页时装购物系统

springboot004网页时装购物系统 亲测完美运行带论文&#xff1a;获取源码&#xff0c;私信评论或者v:niliuapp 运行视频 包含的文件列表&#xff08;含论文&#xff09; 数据库脚本&#xff1a;db.sql其他文件&#xff1a;ppt.pptx论文/文档&#xff1a;开题报告.docx论文&…

yolov9训练自定义数据

1.训练yolov9&#xff0c;先准备好一份自定义数据.。到roboflow下载一份数据&#xff0c;数据格式是yolo格式。 2.到github下载yolov9源码 https://github.com/WongKinYiu/yolov9 3.为了方便配置环境&#xff0c;把代码上传到矩池云上面&#xff0c;使用云服务器 4.执行 pip i…

【软件测试】需求概念|软件的⽣命周期|开发模型|测试模型

目录 推荐 一、什么是需求 1.1 ⽤⼾需求 1.2 软件需求 二、开发模型 2.1 什么是“模型” 2.2 软件的⽣命周期 2.3 常⻅开发模型 2.3.1 瀑布模型 2.3.2 螺旋模型 2.3.3 增量模型、迭代模型 2.3.4 敏捷模型 2.4 测试模型 2.4.1 V模型 2.4.2 W模型(双V模型&#xff0…

2024年5月13号刷题相关事项个人总结

01.01.03 LeetCode 入门及攻略&#xff08;第 01 ~ 02 天&#xff09; 1. LeetCode 是什么 「LeetCode」 是一个代码在线评测平台&#xff08;Online Judge&#xff09;&#xff0c;包含了 算法、数据库、Shell、多线程 等不同分类的题目&#xff0c;其中以算法题目为主。我们…

Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)

Linux文件&#xff1a;重定向底层实现原理&#xff08;输入重定向、输出重定向、追加重定向&#xff09; 前言一、文件描述符fd的分配规则二、输出重定向&#xff08;>&#xff09;三、输出重定向底层实现原理四、追加重定向&#xff08;>>&#xff09;五、输入重定向…

一文说通用户故事点数是什么?

一文说通用户故事点数是什么&#xff1f; 第26期&#xff1a;一文说通用户故事点数是什么&#xff1f; 用户故事点数是一种采用相对估算法进行估算的一种工具&#xff0c;一般采用斐波那契数列表征用户故事里说的大小&#xff0c;采用0 1 2 3 5 8 13这样的一些数字来表征用户…

xxljob分片广播+多线程实现高效定时同步elasticsearch索引库

需求&#xff1a;为了利用elasticsearch实现高效搜索&#xff0c;需要将mysql中的数据查出来&#xff0c;再定时同步到es里&#xff0c;同时在同步过程中通过分片广播多线程提高同步数据的效率。 1. 添加映射 使用kibana添加映射 PUT /app_info_article {"mappings&quo…

维护表空间中的数据文件

目录 向表空间中添加数据文件 从表空间中删除数据文件 删除users表空间中的users02.dbf数据文件 对数据文件的自动扩展设置 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 维护表空间中的数据文件主要包括向表空间中添…

服务网格 SolarMesh v1.13 重磅发布

SolarMesh是行云创新推出的流量治理平台&#xff0c;它基于Istio&#xff0c;为部署在K8s集群上的应用提供全面的流量治理能力。 在之前的版本中&#xff0c;SolarMesh提供的能力有&#xff1a;流量视图&#xff0c;流量控制策略批量配置&#xff0c;API级别的流量数据采集和展…