Android文件存储及权限解析

Android中常见的存储方式有SharedPreferences、Sqlite、文件IO存储、云存储、ContentProvider等。

其中IO存储最为灵活,适用场景也多。这里就不同文件路径和其对应的权限进行分析。

Android系统分区

首先我们需要知道Android的系统分区结构,熟悉Android系统和刷机爱好者应该知道,Android中主要分为以下几个区:

  • /sdcard

    请注意只有sdcard是所有Android设备都有的,我们平时用户在文件管理里面看到的内容就是该分区下的,不要被名字误导了,不是特指我们常说的Sd卡,而是代表普通用户可操作分区,这是你个人存储大文件的地方。

  • /boot

    这个分区上有Android的引导程序,包括内核和内存操作程序。没有这个分区设备就不能被引导。恢复系统的时候会擦除这个分区,并且必须重新安装引导程序和ROM才能重启系统。

  • /system

    这个分区上是除了内核和内存操作之外的整个操作系统。里面包含了Android用户接口和预先安装的系统应用。擦除了这个分区就会删除掉Andorid系统,所以你需要进入recovery模式或者bootloader模式去安装一个新的ROM。

  • /recovery

    recovery分区被认为是另一个启动分区,你可以启动设备进入recovery控制台去执行高级的系统恢复和管理操作。

  • /data

    这个分区保存着用户数据。通讯录、短信、设置和你所有安装的App都在这个分区上。擦除这个分区相当于恢复出厂设置,当你第一次启动设备的时候或者在安装了官方或者客户的ROM之后系统会自动重建这个分区。当你执行恢复出厂设置时,就是在擦除这个分区。

  • /cache

    这个分区是Android系统存储频繁访问的数据和app的地方。擦除这个分区不影响你的个人数据,当你继续使用设备时,被擦除的数据就会自动被创建。

  • /misc

    这个分区包含各种复杂的类似于on/off的系统设置。这些设置可能是USB配置和某些硬件配置信息。这是一个重要的分区,如果该分区损坏或者丢失,设备的功能可能就工作不正常。

内部包路径

我们知道每个应用都是根据其包名唯一性进行安装的,在软件安装时,Android系统会在data分区上为每个App创建其对应包名的目录,该目录可以由我们自由控制的。

  • 安全性

    该目录位于data分区,权限为包私有,也就是仅有该包目录对应程序具有读写权限,对普通用户和应用不可见。安全性相对较高,但是私密数据还是需要进行加密保存,因为系统Root后依然可以被别有用心之人查看和修改。

  • 权限

    在私有包目录下进行读写操作均不需要额外申请权限。

  • 持久化

    伴随应用卸载一起删除。

  • 获取途径

    val file = context.getFilesDir()val cacheDir = context.getCacheDir()...

外部包路径

外部包路径内部包路径类似,同样是以应用包名来进行命名,但是不同点在于它位于sdcard分区上。通常路径为0/Android/data/包名

  • 安全性

    该目录位于sdcard分区,权限为公有,对普通用户和应用可见。安全性相对较低,不建议存放私密数据。

  • 权限

    在包目录下进行读写操作均不需要额外申请权限。

  • 持久化

    伴随应用卸载一起删除。

  • 获取途径

    val file = context.getExternalFilesDir(type:String)val cacheDir = context.getExternalCacheDir()

外部路径

和外部包路径一样位于sdcard分区上,是最灵活的一种存储方式,平时用的也很多。

  • 安全性

    该目录位于sdcard分区,权限为公有,对普通用户和应用可见。安全性相对较低,不建议存放私密数据。

  • 权限

    需要额外申请读写权限。

  • 持久化

    不会伴随应用卸载删除,如果没有人为干涉会一直保存,会造成系统垃圾残留,控制不好会很流氓,需要谨慎使用。

  • 获取途径

    val rootDirectory = Environment.getExternalStorageDirectory()val publicDirectory = Environment.getExternalStoragePublicDirectory(type:String)

注意事项

  • 使用外部路径时需要注意权限获取,在target23以前仅需要在Manifest.xml中申请即可,之后需要在代码中动态判断。

  • 使用存在sdcard分区上目录时,需要先判断sdcard分区状态是否可用。

    /* Checks if external storage is available for read and write */fun isExternalStorageWritable(): Boolean {    return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED}/* Checks if external storage is available to at least read */fun isExternalStorageReadable(): Boolean {     return Environment.getExternalStorageState() in        setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)}
  • 在创建新目录时,一定先判断其父目录是否存在,如果不存在需要先创建。

    fun createFile(parentFile: File, name: String) {    if (!parentFile.exists()) {        parentFile.mkdirs()    }    File(parentFile, name)}

更多相关文章

  1. Android 面试必备 - 系统、App、Activity 启动过程
  2. Linux/Android——input系统之 kernel层 与 frameworks层交互 (
  3. Android系统简介
  4. 腾讯面试官:了解Java Binder中的系统服务吗?
  5. Android图形系统分析与移植--五、Android FrameBuffer简介
  6. Android系统自带主题样式(android:theme),Android Dialog 系统样式
  7. android系统中“关于设备”中android版本和android安全补丁信息
  8. 从零开始--系统深入学习android(实践-让我们开始写代码-Android框
  9. [Android 新特性] 改进明显 Android 4.4系统新特性解析

随机推荐

  1. Android 定时器真机测试
  2. Android错误之HAX is not installed on t
  3. Android Menu 用法
  4. NanoHttpd 构建android 手机端的HttpServ
  5. AlarmManagerService(一)
  6. 使用jenkins自动化构建Android(安卓)app
  7. Android(安卓)网易云音乐图片高斯模糊
  8. IPC与Binder,Binder线程池,AIDL demo - And
  9. Android(安卓)volley封装实践其二
  10. Android FlexboxLayout使用方式