Android 存储概览
存储区
Android 一开始就将存储区分为内部存储和外部存储,对应手机自带的存储和可插拔的 sd 卡(可类比于 PC 的硬盘和 U盘)。
内部存储容量有限,Google 建议 App 数据尽量存储于外部存储中。
随着硬件技术发展,自带大容量空间的手机开始出现,关于内部存储的描述逐渐偏离现实了,于是从 Android 4.4(API 19)开始,官方不再将机身存储等同于内部存储,而是从逻辑上将其一部分划到外部存储,限制剩下那部分的容量,也就是现在所谓的内部存储。这一操作,使得原本内部存储和外部存储的特性和使用场景得以延续。
当然,如果在 4.4 系统及以上的手机上插了 sd 卡,那么 sd 卡也属于外部存储。
我们可以使用如下代码打印出所有的外部存储:
File[] files;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
files = getExternalFilesDirs(Environment.MEDIA_MOUNTED);
for(File file:files){
Log.e("main",file);
}
}
对于 4.4 以上的插了 sd 卡的大容量手机,应该会打印出如下信息:
/storage/emulated/0/Android/data/packname/files/mounted
/storage/B3E4-1711/Android/data/packname/files/mounted
文件
应用专属文件
仅供应用使用的文件,可以存储到内部存储或外部存储中的本应用专属目录,本应用访问时不需要任何权限。在数据安全方面,虽然都是专属目录,但是内部存储可以保证其它应用访问不到,而外部存储就比较复杂了。
在较低版本的 Android 系统中,只要声明READ_EXTERNAL_STORAGE权限就能访问位于外部存储空间中应用专属目录之外的任何文件;只要声明WRITE_EXTERNAL_STORAGE权限就能向应用专属目录以外的任何文件写入数据。
这实在是相当危险,谁也不希望自家应用中的数据被抓取或篡改。于是从Android 10(API 29)开始有了分区存储的概念,应用在默认情况下就能访问外部存储空间上自己的专属目录,以及本应用所创建的特定类型的媒体文件(使用MediaStore API,下面会讲到)。如此,除非特殊情况,应用不再需要声明上述权限了。
此时,如果应用在运行时请求与存储相关的权限,将会弹出请求对话框(动态申请)表明应用正在请求对外部存储空间的广泛访问权限。
Android 11(API 30)开始更进一步,干脆将 WRITE_EXTERNAL_STORAGE 权限的作用抹除(即使声明了该权限也没用)。这将应用的写权限完全限制在了本应用相关目录(专属目录和本应用创建的媒体文件)中。
ps:Android 11 引入了_MANAGE_EXTERNAL_STORAGE_权限,该权限替代 WRITE_EXTERNAL_STORAGE,提供对应用专属目录和 MediaStore 之外文件的写入权限,但对使用的要求更严格。如需了解详情,请参阅有管理存储设备上所有文件。
共享文件
存储您的应用打算与其它应用共享的文件,包括媒体(图片、音频文件、视频)、其它类型文件。
媒体文件
使用 MediaStore API 访问。注意:即使您的应用已卸载,作为共享文件(保存在媒体库中)的媒体文件仍会保留在用户的设备上。
除访问自己的媒体文件外,访问其它应用的媒体文件需要权限——在 Android 11(API 30)或更高版本中,需要 READ_EXTERNAL_STORAGE;在 Android 10(API 29)中,需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE;在更低版本中,访问所有文件均需要相关权限。——不过这也不是绝对的。
比如照片选择器,它提供了一个可浏览界面,为用户提供了一种安全的内置授权方式,让用户可以向应用授予限于所选图片和视频的访问权限,而非整个媒体库的访问权限,该权限保留至设备重启或应用停止运行。使用照片选择器可以看作定制的动态申请权限的界面,至少从Android 13(API 32)开始,无需事先声明 READ_EXTERNAL_STORAGE。
其它文件
自 Android 4.4(API 19)始,官方提供了存储访问框架,便于应用与外部存储卷和云端存储空间在内的文档提供器互动。此框架支持用户与系统选择器互动,从而选择文档提供器以及供您的应用创建、打开或修改的特定文档和其它文件。
同照片选择器类似,由于用户参与选择您的应用可以访问的文件或目录,因此该机制无需任何系统权限,同时用户控制和隐私保护也得到了增强。
这些文件存储在应用专属目录和媒体库之外,且在应用卸载后仍会保留在设备上。
使用存储访问框架涉及以下步骤:
- 应用调用包含存储相关操作的 intent(
ACTION_CREATE_DOCUMENT保存文件;ACTION_OPEN_DOCUMENT打开文件;ACTION_OPEN_DOCUMENT_TREE授予应用对该目录中所有文件和子目录的访问权限)。 - 用户看到一个系统选择器,供其浏览文档提供器并选择将执行存储相关操作的位置或文档。
- 应用获得对代表用户所选位置或文档的 URI 的读写访问权限。利用该 URI,应用可以在选择的位置执行操作。
数据
应用配置项
不赘述,就是简单的键值对。值得一提的是,之前都是使用SharedPreferences进行应用配置项的操作,现在官方建议使用Jetpack DataStore,允许您使用协议缓冲区存储键值对或类型化对象。DataStore 基于Kotlin 协程和Kotlin.Flow以异步、一致的事务方式存储数据。
数据库
基于SQLite的数据存储,一般选择Jetpack.Room这个半 ORM 简化数据 CRUD 操作。卸载应用时数据库会跟着删除。
Android 存储概览的更多相关文章
- Android存储访问及目录
Android存储访问及目录 Android的外部存储 Android支持外部存储(case-insensitive filesystem with immutable POSIX permissio ...
- Android存储之SQLite数据库
Android存储之SQLite数据库数据库 创建数据库 package --; import android.content.Context; import android.database.sql ...
- Android存储路径你了解多少?
在了解存储路径之前,先来看看Android QQ的文件管理界面,了解一下QQ的数据文件路径来源,到底是来源于什么地方? 手Q文件管理对应存储目录 我的文件:是指放在QQ指定目录下的文件:/tencen ...
- 【转】Android系统概览
这篇文章其实原文叫 <老罗的Android之旅>导读PPT 是罗升阳的博客,我觉得用“Android系统概览”作为标题更贴切些,对于在应用层已经开发了一段时间的人来说,读完之后会有很多体会 ...
- Android 存储(本地存储 SD卡存储 SharedPreference SQLite ContentProvider)
本文出自:http://blog.csdn.net/dt235201314/article/details/73176149 源码下载欢迎Star(updating):https://github.c ...
- 一篇文章搞懂android存储目录结构
前言 前两天因为开发一个app更新的功能,我将从服务器下载的apk文件放在了内部存储目录(测试手机为小米,路径为:data/user/0/packagename/files)下面,然后安装的时候一直安 ...
- android存储方式的应用场景
作为一个完整的应用程序,数据存储操作是必不可少的.因此,Android系统一共提供了四种数据存储方式.分别是:SharePreference.文件存储.SQLite. Content Provider ...
- Android开发学习——android存储
Android的存储 内部存储空间RAM内存:运行内存,相当于电脑的内存ROM内存:存储内存,相当于电脑的硬盘外部存储空间 SD卡:相当于电脑的移动硬盘 * 2.2之前,sd卡路径:sdcard ...
- Android存储
Android的四种数据存储方式: 1.SharedPrefrences 2.SQLite 3.Content Provider 4.File SharedPrefrences: 1.是一种轻型的数据 ...
- 利用反射得到android存储路径
获得android手机的存储路径: public String getPrimaryStoragePath(){ try{ StorageManager sm = (StorageManager) c ...
随机推荐
- 开发一个题库系统App和小程序的心得
序言 对于一名开发者来说,独自开发一款小程序与App,也许总会有一些疑问: 1. 需要掌握哪些技术? 答:java.vue.及常规Linux命令 2. 需要多少成本? 答:服务器购买,云服务器新人50 ...
- AJAX基础+Axios快速入门+JSON使用+综合案例
目录 1. AJAX 1.1 概述 1.1.1 作用 1.1.2 同步和异步 1.2 快速入门 1.2.1 服务端实现 1.2.2 客户端实现 1.3 案例 1.3.1 需求 1.3.2 分析 1.3 ...
- 解锁网络无限可能:揭秘微软工程师力作——付费代理IP池深度改造与实战部署指南
基于付费代理的代理IP池 项目来源 此项目为微软某个工程师构建的代理IP池,我对此进行了改造.可以用于生产环境中的爬虫项目 阅读前建议 阅读我之前发布的爬虫基础的文章,了解代理如何获取.使用等. 分为 ...
- Pybind11和CMake构建python扩展模块环境搭建
使用pybind11的CMake模板来创建拓展环境搭建 从Github上下载cmake_example的模板,切换分支,并升级pybind11子模块到最新版本 拉取pybind11使用cmake构建工 ...
- redis如何实现主从同步
redis实现主从同步分为两种:全量同步和增量同步:第一次连入集群的slave需要进行全量同步,那些断开后重连的slave需要进行增量同步 每个redis都有自己的replid,他们是master的标 ...
- 关于visual studio的一个bug
本人初学链表,如有错误多多包涵 快马加鞭,这期只写一个问题.我好像在vs里面发现了一个bug 不管是vs2022还是vs2010都无法正常运行.关于cin.string.链表的问题 #include& ...
- SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴
开心一刻 一大早,她就发消息质问我 她:你给我老实交代,昨晚去哪鬼混了? 我:没有,就哥几个喝了点酒 她:那我给你打了那么多视频,为什么不接? 我:不太方便呀 她:我不信,和你哥们儿喝酒有啥不方便接视 ...
- Jmeter函数助手33-split
split函数用于根据分隔符拆分传递给它的字符串,并返回原始字符串. String to split:填入需要转换的字符串 函数名称.用于存储在测试计划中其他的方式使用的值:存储结果的变量名 Stri ...
- Python+selenium编写第一个UI自动化脚本
python UI自动化前提:①python需要安装selenium模块 ②下载浏览器驱动 1.安装selenium模块 先确认本地是否安装selenium模块,没有的话点击右边的添加按钮" ...
- Jmeter大小断言
Jmeter大小断言是用来判断返回的消息体大小的,组件路径[HTTP请求右键添加->断言->大小断言] 我们来了解一下大小断言组件里面包含什么内容 1.Apply to: Main sam ...