目录
android手机存储分类
分为:内部存储和外部存储
如何区分内部存储和外部存储:可以从物理和逻辑区分
从物理的角度区分,内部存储就是手机自带存储空间,外部存储就是外部接入的存储空间例如SD卡
从逻辑意义上区分,data,system 目录就是手机的内部存储,而 mnt 或者 storage目录下的sdcard0指向的sdcard目录就是外部存储。如果是手机自带的外部存储被称为机身外部存储,外置的SD卡则称之为外部存储。当然两者都称为外部存储也没关系。这里描述的内部存储和机身外部存储都属于机身存储;
逻辑区分是从4.4以上版本开始的;
二,内部存储
获取内部存储路径和api对应关系
1,通过Environment
Environment.getDataDirectory() /data
Environment.getRootDirectory() /system
Environment.getDownloadCacheDirectory() /data/cache
2,通过上下文Context
getCacheDir() /data/user/0/包名/cache
getFilesDir() /data/user/0/包名/files
Build.VERSION_CODES.LOLLIPOP及以上版本新增的API
getDir(“靓仔”, MODE_PRIVATE) /data/user/0/包名/app_靓仔
getNoBackupFilesDir() /data/user/0/包名/no_backup
getCodeCacheDir() /data/user/0/包名/code_cache
Build.VERSION_CODES.N及以上版本新增的API
getDataDir() /data/user/0/包名
特点:
1、内部存储路径中的文件是分类存储的,我们无法干涉,除了cache目录,别的目录系统不会自动创建
2、除了files目录,别的目录我们几乎都是无法手动操作的
3、别的App几乎无法访问内部存储中的数据,除了用非法手段或者我们主动暴露
4、内部存储目录下的文件夹及文件会随着app的卸载而被系统自动删除
三,外部存储
外部存储又可分为共有目录和私有目录;
私有目录
私有目录:不需要访问权限
Android 在外部存储空间中也提供了特殊目录供App存放私有文件,该路径为:/storage/emulated/0/Android/data/包名/
注意:应用安装之后/storage/emulated/0/Android/data/是没有对应的应用文件夹的,需要手动调用对应的API创建;
获取私有目录路径
getObbDir() /storage/emulated/0/Android/obb/包名
getExternalCacheDir() /storage/emulated/0/Android/data/包名/cache
getExternalFilesDir(null) /storage/emulated/0/Android/data/包名/files
公有目录
公有目录:需要申请权限才能访问
权限:6.0以上需要动态申请
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>
获取共有目录的API 29中已过时:
Api | 路径 |
Environment.getExternalStorageDirectory() | /storage/emulated/0 |
Environment.getExternalStoragePublicDirector(Environment.DIRECTORY_DOWNLOADS) 获取共有目录,例如Download共有目录 |
/storage/emulated/0/Download |
官方的解释:
在API级别29中不赞成使用此方法。为了提高用户隐私,不建议直接访问共享/外部存储设备。当应用定位到时
Build.VERSION_CODES.Q
,此方法返回的路径不再可供应用直接访问。应用程序可以继续访问内容通过迁移到替代品,如存储在共享/外部存储
Context#getExternalFilesDir(String)
,
MediaStore
或
Intent#ACTION_OPEN_DOCUMENT
。
注意:如果手机插入SD卡,可通过getExternalFilesDirs或getExternalCacheDirs遍历来获取路径;
四,数据删除
CLEAR DATA(删除数据): 清除的是 data/data/对应程序包名 的文件夹下的所有的文件全都会被删除,mnt/sdcard/Android/对应程序包名 下的所有的数据也都会被删除。
CLEAR CACHE(清空缓存): 清除的数据是 data/data/对应程序包名/catch 目录下的数据,还有 mnt/sdcard/Android/对应程序包名/catch目录下的数据
五,权限相关
在android 6.0以前,你可以只关注外置存储是否挂载即可,但是从6.0以后,也就是M系统后,还需要判断是否有读写权限,只有具备这些权限才可以读写外置存储。
1,Context.getRootDirectory
获取路径:/system
默认存在,不可读写(除非具备root权限)
2,Environment.getDownloadCacheDirectory
获取路径:/cache
默认存在,声明权限则可读写(6.0和以后系统还需要向用户申请同意才可以)
3,Context.getFilesDir
获取路径:/data/user/0/包名/files
该目录是应用的文件存储目录,应用被卸载时,该目录一同被系统删除。默认存在,默认具备读写权限(6.0系统可以不用向用户申请)
4,Context.getCacheDir
获取路径:/data/user/0/包名/cache
该目录是应用的文件缓存目录,应用被卸载时,该目录一同被系统删除。默认存在,默认具备读写权限。不同于getFileDir,该目录下的文件在系统内存紧张时,会被清空文件,来腾出空间供系统使用,著名的图片加载库ImageLoader就是在没有外置存储读写权限时使用此文件夹。getFileDir,不会因为系统内存不足而被清空。(6.0系统可以不用向用户申请)
5,Context.getDir
获取路径:/data/user/0/应用包名/app_参数名
默认存在,可读写。分为Private等三个权限,private代表仅能自己访问。(6.0系统可以不用向用户申请)
6,Context.getCodeCacheDir
获取路径:/data/user/0/包名/code_cache
默认存在,可读写。(6.0系统可以不用向用户申请)
7,getNoBackupFilesDir()
获取路径: /data/user/0/包名/no_backup
默认存在,可读写。(6.0系统可以不用向用户申请)
8,Context.getObbDir
获取路径:/storage/emulated/0/Android/obb/包名
该目录是应用的数据存放目录,一般被用来存放游戏数据包obb文件。默认存在,可读写(6.0系统可以不用向用户申请)
9,Context.getExternalCacheDir
获取路径:/storage/emulated/0/Android/data/应用包名/cache
默认存在,可读写。(6.0系统可以不用向用户申请)
10,Context.getExternalFilesDir
获取路径:(以下载目录为准) /storage/emulated/0/Android/data/应用包名/files/Download
默认存在,可读写。(6.0系统可以不用向用户申请)
11,Environment.getExternalStorageDirectory
获取路径:/storage/emulated/0
默认存在,声明权限则可读写(6.0和以后系统还需要向用户申请同意才可以)
12,Environment.getExternalStoragePublicDirectory
获取路径:/storage/emulated/0/Download(以下载目录为例)
默认存在,声明权限则可读写(6.0和以后系统还需要向用户申请同意才可以)
13,Context.getDatabasePath
获取路径:/data/user/0/包名/databases/参数名
默认不存在,可读写。(6.0系统可以不用向用户申请)
14,Context.getPackageCodePath
获取路径:/data/app/包名-1/base.apk
默认存在,获取apk包路径
15,Context.getFileStreamPath
获取路径:/data/data/包名/files/download(示例download)
该目录是应用的文件存储目录,应用被卸载时,该目录一同被系统删除。默认存在,默认具备读写权限(6.0系统可以不用向用户申请)
附注:
a)上述路径是通过getAbsulotePath方法获得,一般情况下等同于getPath
b)在6.0系统上,一般Java层实现对外置存储的文件操作需要向用户申请,如果用C层实现,则可以越过这种限制
c)配置compilesdk,targetsdk低于23,可以避免在6.0手机上的权限限制