一、总结(Android10之前)

路径取得方法 APP专用 非root用户可见 APP卸载时
内部数据空间 Context.getFilesDir() yes no 消失
内部缓存空间 Context.getCacheDir() yes no 消失
外部数据空间 Context.getExternalFilesDir(String type) yes yes 消失
外部缓存空间 Context.getExternalCacheDir() yes yes 消失
外部公开空间 Environment.getExternalStorageDirectory() no yes 不消失
外部公开共享空间 Environment.getExternalStoragePublicDirectory(String type) no yes 不消失

内部空间 只有APP自己可以访问,其他APP和手机用户都不可以见。卸载消失。

外部私有空间 APP自己,手机用户,其他授权APP可以访问。卸载消失

外部公开空间,所有APP和用户都可以访问。卸载不消失。

测试:

Context.getFilesDir()                           :/data/data/com.example/files
Context.getCacheDir()                           :/data/data/com.example/cache
Context.getExternalCacheDir()                   :/storage/emulated/0/Android/data/com.example/cache
Context.getExternalFilesDir()                   :/storage/emulated/0/Android/data/com.example/files
Environment.getExternalStorageDirectory()       :/storage/emulated/0
Environment.getExternalStoragePublicDirectory() :/storage/emulated/0/

其中,除了外部存储公共空间以外,其他目录无需存储权限就可访问。


1.内部存储空间中的应用私有目录

路径取得方法 APP专用 非root用户可见 APP卸载时
内部数据空间 Context.getFilesDir() yes no 消失
内部缓存空间 Context.getCacheDir() yes no 消失

对于设备中每一个安装的 App,系统都会在内部存储空间的 data/data 目录下以应用包名为名字自动创建与之对应的文件夹。这个文件夹用于 App 中的 WebView 缓存页面信息,SharedPreferences 和 SQLiteDatabase 持久化应用相关数据等。

对于没有 Root 过的手机,普通用户是无法查看 data/data 目录内容的。不过开发人员可以使用模拟器调试应用,并通过 DDMS(Dalvik Debug Monitor Server)提供的 File Explorer 工具查看模拟器设备的存储空间。

当设备的内部存储空间不足时,Android 可能会删除Context.getCacheDir()下的文件以回收空间。

当用户卸载 App 时,系统自动删除 data/data 目录下对应包名的文件夹及其内容。

2.外部存储空间中的应用私有目录

路径取得方法 APP专用 非root用户可见 APP卸载时
外部数据空间 Context.getExternalFilesDir() yes yes 消失
外部缓存空间 Context.getExternalCacheDir() yes yes 消失

考虑内部存储空间容量有限,普通用户不能直接直观地查看目录文件等其他原因,Android 在外部存储空间中也提供有特殊目录供应用存放私有文件,文件路径为:

/storage/emulated/0/Android/data/app包名目录

值得注意的是,与内部存储空间的应用私有目录不同的是:

  • 默认情况下,系统并不会自动创建外部存储空间的应用私有目录。只有在应用需要的时候,开发人员通过 SDK 提供的 API 创建该目录文件夹和操作文件夹内容。
  • 自 Android 7.0 开始,系统对应用私有目录的访问权限进一步限制。其他 App 无法通过 file:// 这种形式的 Uri 直接读写该目录下的文件内容,而是通过 FileProvider 访问。
  • 系统媒体扫描程序不会读取这些目录中的文件,但是其他应用依然可以对该目录下的文件读写,普通用户可以自由修改和删除,开发人员在使用时,一定要做好判空处理和异常捕获,防止应用崩溃退出!
  • Context.getExternalCacheDir()当内置存储的空间不足时将系统自动被清除
  • Android 4.4以后访问该目录不再需要权限了

而相同点在于:同属于应用私有目录,当用户卸载 App 时,系统也会自动删除外部存储空间下的对应 App 私有目录文件夹及其内容。

3.外部存储空间中的公共目录

路径取得方法 APP专用 非root用户可见 APP卸载时
外部公开空间 Environment.getExternalStorageDirectory() no yes 不消失
外部公开共享空间 Environment.getExternalStoragePublicDirectory() no yes 不消失

从访问权限上来说,应用无关数据应该是宿主应用希望与其他应用共享这些数据,应该存放在外部存储空间的公共目录文件夹下。

外部存储空间已经为用户默认分类出一些公共目录。开发人员可以通过 Environment 类提供的方法直接获取相应目录的绝对路径,传递不同的 type 参数类型即可:

Environment.getExternalStoragePublicDirectory(String type);

Envinonment 类提供诸多 type 参数的常量,比如:

  • DIRECTORY_MUSIC:/storage/emulated/0/Music
  • DIRECTORY_MOVIES:/storage/emulated/0/Movie
  • DIRECTORY_PICTURES:/storage/emulated/0/Pictures
  • DIRECTORY_DOWNLOADS: /storage/emulated/0/Download
  • DIRECTORY_DOCUMENTS: /storage/emulated/0/Documents

还可以在外部存储空间自由创建其他目录,通过这个方式获取外部存储空间的绝对路径,然后操作文件:

Environment.getExternalStorageDirectory();

有个小技巧,无论外部内部,只要路径中有包名,那么就是私有的,而且是随着程序的卸载而被删除的,有包名的路径均是Context中的方法,而公有的路径均是Environment调用的,卸载不会删除。

二、Android 10和Android 11

Android 10之前,外部存储区的内容主要以两种形式存在,一种是由应用的包名命名,归属于特定应用目录下的内容,另一种是存储在公共存储区域的内容。

在Android 10 中,Google首次引入了分区存储,将公共区域划分成了不同的集合,并且在媒体文件和其他文档之间建立了清楚的分割。经过划分之后应用不可以随意访问外部存储区中的文件,而只能访问媒体文件。如果想访问包含更多细节数据的其他文档,应用专门向用户申请有关文档的访问权限。

分区存储是需要以 Android 10 为目标平台的,系统默认强制执行。如果在 AndroidManifest 中添加了 requestLegacyExternalStorage=true 标志,就可以不受此限制。但是当 target API 更新为 30 后,系统会忽略该配置。

如果有数据需要迁移,可以在 AndroidManifest 中将 preserveLegacyExternalStorage 属性设为 true ,当用户升级到以 Android 11 为目标平台时,这个配置就会生效。具体而言,这个配置在用户重新安装该应用前都是有效的。

针对以 Android 11 为目标平台的应用 (targetSdkVersion = 30) ,WRITEEXTENRNALSTORAGE 和 WRITEMEDIASTORAGE 不再提供其他任何访问权限 。

某些应用的核心功能可能需要访问大量的文件,例如文件管理操作、备份和恢复操作等等,此时就需要申请 MANAGEEXTERNALSTORAGE 权限。我们可以通过使用 ACTIONMANAGEALLFILESACCESS_PERMISSION intent 操作将用户引导至一个系统设置页面,让用户为应用授予所有文件的管理权限。


Android 10分区存储介绍及百度APP适配实践
你有一份安卓11适配攻略,请注意查收

Android存储空间及路径总结相关推荐

  1. Android存储空间讲解

    http://blog.fidroid.com/post/android/ru-he-zheng-que-huo-de-androidnei-wai-sdqia-lu-jing 如何正确获得Andro ...

  2. Android 存储空间访问方法

    Android 数据持久化学习笔记 -- 内外部存储空间访问方法 Android 提供两类物理存储位置:内部存储空间和外部存储空间. 默认情况下,应用本身存储在内部存储空间中.不过,如果 APK 很大 ...

  3. android assets绝对路径,Android 获取assets的绝对路径

    第一种方法: String path = "file:///android_asset/文件名"; 第二种方法: InputStream abpath = getClass().g ...

  4. android动画框架,GitHub - azhengyongqin/CustomAnimationFramework: Android自定义曲线路径动画框架...

    Android自定义曲线路径动画框架 最近在一个项目中需要一个像QQ打开个人爱好那样的动画效果如下图: 可以看出每个小球都是以顺时针旋转出来的,说明像这样的曲线动画用Android中自带的平移动画是很 ...

  5. android7 编译配置摄像头,MTK平台新增摄像头指南 -- 已更新android 7.0路径的更改。...

    增加驱动及配置到Kernel 层: 增加驱动文件夹到如下目录: mediatek\custom\common\kernel\imgsensor\ mediatek\custom\mt6582[mt81 ...

  6. Android定义的路径全局变量

    Android定义的路径全局变量 ifeq (,$(strip $(OUT_DIR))) OUT_DIR := $(TOPDIR)out endif DEBUG_OUT_DIR := $(OUT_DI ...

  7. Android:获取存储卡路径的方式

    Android获取存储卡路径的方式 Android Lint 有个关于在代码中硬编码"sdcard"路径的警告,内容为: 不要硬编码(hardcode) "/sdcard ...

  8. android 各个存储路径及获取方法总结

    1.各个路径 最长用到的就这三个位置 /data/data/包名/ /sdcard/Android/data/包名/ /sdcard/xxx 前两个是应用内部存储, 会随着app的卸载而自动删除, s ...

  9. android 相册分组,Android获取相册路径

    Android获取相册路径 (2015-10-14 16:14:38) 标签: android 开发 源代码 freetheory 相册路径 private void getPhotoThumbnai ...

最新文章

  1. 【青少年编程】【三级】 魔术表演“开花”
  2. 远程监控 – 数据采集管道
  3. signature=9742dbe4d0ffb25ecc6661da5a37550e,Die Griechische Volkswirtschaft in den siebziger Jahren
  4. AngularJS:在Windows上安装Yeoman
  5. (十)HTTP协议【前后端分离的时代,网络请求是前端的生命线】
  6. java uuid静态方法_Java UUID timestamp()方法与示例
  7. [BZOJ1502]月下柠檬树(自适应辛普森积分)
  8. Tensorflow练习题
  9. Spring的DI(Ioc) - 利用构造器注入
  10. 中控考勤机无线连接不上服务器,中控考勤机安装及常见问题【图解】
  11. oracle下载安装教程
  12. 如何在系统设置mysql环境变量(win11)
  13. overleaf表格_Latex中插入表格
  14. 数据中台POC演示流程
  15. 记下js dom动态添加事件的解决方法
  16. JPA ERROR: value too long for type character varying(100)
  17. python signal处理
  18. 面试大全 | C语言高级部分总结,2.6万字长文
  19. MySQL的my-innodb-heavy-4G.ini配置文件的翻译
  20. 上海职称不用考计算机和英语翻译,英语翻译专业资格考试替代职称评定

热门文章

  1. html选择本地文件视频并播放器,使HTML5视频播放器播放不同的文件(Make a HTML5 video player play a different file)...
  2. 网站图标开发指南(精)
  3. 46、微信-群聊列表
  4. loglog()函数
  5. requirejs的用法
  6. 游戏辅助小助手框架构想
  7. ebs 编译无效对象——adutlrcmp.sql not giving promt
  8. resultful规范使用
  9. pyttsx3设置男性声音
  10. Android JetPack架构篇,一个实战项目带你学懂JetPack