在之前的开发过程中,对于应用存储目录存在一些模糊的观念,在AndroidQ版本中,Google对应用存储空间又做了调整,借此机会梳理一下。
移动设备存储空间大致可划分为内部存储 与 外部存储,而外部存储又可细分为外部私有存储与外部共享存储,具体区别如下
内部存储
存储结构
访问方式
/**
*获取应用内部存储的files路径
*/
String filesPath = context.getFilesDir().getAbsolutePath();
filesPath = /data/data/{应用包名}/files
//或者(Android4.2以后增加多用户,更改了用户数据挂载结构,但是文件还是按照上述data/data/结构存储)
filesPath = /data/user/0/{应用包名}/files
/**
*获取应用内部存储的cache路径
*/
String cachePath = context.getCacheDir().getAbsolutePath();
cachePath = /data/data/{应用包名}/cache
//或者(原因同上)
cachePath = /data/user/0/{应用包名}/files
/**
*获取应用内部存储根目录下指定目录路径,如果目录不存在,系统则会自动创建
*@param name:目录名称
*@param mode:目录操作模式-私有(默认)仅自己可访问
*/
String targetPath = context.getDir(name,Context.MODE_PRIVATE).getAbsolutePath();
targetPath = /data/data/{应用包名}/{name}
//或者
targetPath = /data/user/0/{应用包名}/{name}
扩展:在内部存储files目录下创建自定义目录
/**
*在应用内部存储files目录下创建子文件夹
*/
String customDirPath = context.getFilesDir().getAbsolutePath() + "/customDir"
File customDirFile = new File(customDirPath);
//如果文件不存在,则创建
if(!customDirFile.exists()){
customFile2.mkdir();
}
customDirPath = /data/data/{应用包名}/files/customDir
//或者
customDirPath = /data/user/0/{应用包名}/files/customDir
存储特点
- 应用访问无需(静态&动态)申请权限(如果访问目录不存在,系统会自动创建)
- 存储区域内的文件私有,仅有自己可访问,其他App无权访问
- 应用卸载后,数据也同步删除
- 存储空间有限
由于内部存储大小有限制的,因此我们用来保存比较重要的数据,例如用户信息资料,口令秘码等不需要与其他应用程序共享的数据。
外部存储
注意,由于用户可以弹出外部存储,因此外部存储可能并不总是可用。可以使用Environment#getExternalStorageState(File)
检查媒体状态。
私有目录
存储结构
访问方式
/**
*获取应用外部存储私有files下指定目录路径,如果不指定type则获取的是files根路径
*type:系统默认提供内部存储目录类型,有如下(也可自定目录):
* {@link android.os.Environment#DIRECTORY_MUSIC}
* {@link android.os.Environment#DIRECTORY_PODCASTS}
* {@link android.os.Environment#DIRECTORY_RINGTONES}
* {@link android.os.Environment#DIRECTORY_ALARMS}
* {@link android.os.Environment#DIRECTORY_NOTIFICATIONS}
* {@link android.os.Environment#DIRECTORY_PICTURES}
* {@link android.os.Environment#DIRECTORY_MOVIES}
*提示:目录如果不存在,则系统会自动创建
*/
String externalFiles = context.getExternalFilesDir(type).getAbsolutePath();
externalFiles = /mnt/sdcard/Android/data/{应用包名}/files/{type}
//或者
externalFiles = /storage/emulated/0/Android/data/{应用包名}/files/{type}
/**
*获取应用外部存储私有cache路径
*/
String externalCache = context.getExternalCacheDir().getAbsolutePath();
externalCache = /mnt/sdcard/Android/data/{应用包名}/cache
//或者
externalFiles = /storage/emulated/0/Android/data/{应用包名}/cache
存储特点
- Android4.4以后,应用自身访问无需(静态&动态)申请权限(如果访问目录不存在,系统会自动创建)
- 文件公开,第三方应用可以访问
- 应用卸载后数据同步删除
公共(共享)目录
存储结构
访问方式
注意:
-
从AndoridQ开始,此方法已经过时。为了改善用户隐私,不推荐直接访问设备的外部公共存储目录,应使用外部私有目录(context.getExternalFilesDir(type)方案来替代。
-
在开发中,Google官方建议App数据存储在外部存储的私有目录中对应App的包名下
storage/sdcard/Android/data/包名/
,这样当用户卸载掉App之后,相关的数据会一并删除!
/**
*获取外部存储根目录
*/
String externalRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
externalRoot = /mnt/sdcard
//或者
externalRoot = /storage/emulated/0
/**
*获取外部存储根目录下指定目录
*type:系统默认提供的外部存储目录类型,有如下(也可自定目录):
* {@link #DIRECTORY_MUSIC},
* {@link #DIRECTORY_PODCASTS},
* {@link #DIRECTORY_RINGTONES},
* {@link #DIRECTORY_ALARMS},
* {@link #DIRECTORY_NOTIFICATIONS},
* {@link #DIRECTORY_PICTURES},
* {@link #DIRECTORY_MOVIES},
* {@link #DIRECTORY_DOWNLOADS},
* {@link #DIRECTORY_DCIM},
* {@link #DIRECTORY_DOCUMENTS}
*提示:返回目录的文件路径。注意,这个目录可能还不存在,所以在使用之前必须确保它存在
*。 例如使用{@link File#mkdirs File.mkdirs()}
*/
String targetPath = Envrionment.getExternalStoragePublicDirectory(type).getAbsolutePath();
File targetFile = new File(targetPath);
//如果不存在,则创建
if(!targetFile.exists()){
targetFile.mkdir();
}
targetPath = /mnt/sdcard/{type}
//或者
targetPath = /storage/emulated/0/{type}
存储特点
- 访问需要申请(静态&动态)权限(如果目录不存在需要提前判断并创建)
- 文件公开,任何应用都可访问
- 应用卸载,数据不会清除
参考文章