/files数据存储空间,contet.getFilesDir() 获取
一般的,一个应用的内部存储路径未 /data/data/{packageName}/ 。但是对于特殊机型比如华为,小米可能为 /data/user/0/{packageName}/
|
1 2 3 4 5
|
/data/data/{packageName}/files/
context.getFilesDir().getAbsolutePath();
/data/data/{packageName}/cache/
context.getCacheDir().getAbsolutePath();
|
storage 分区(External Storage/Shared Storage)
External Storage/Shared Storage,不需要 root 权限就可以操作。可能包含可移除的存储介质,在使用之前需要判断是否挂载(mounted)
查看方式
|
1 2 3
|
/storage/emulated/0 @Deprecated Android10 版本上不再推荐使用该 Api Environment.getExternalStorageDirectory()
|
主要目录
storage/emulated/0/Android/media/{packageName},以包名的形式区分,app的私有多媒体空间,5.0 Api可用obb/{packageName},以包名的形式区分,游戏 obb 数据文件data/{packageName}以包名的形式区分,app的私有存储空间/cache缓存空间,可通过context.getExternalCacheDir()获取/files数据存储空间,可通过context.getExternalFilesDir()获取, Android 10 通过以下方法进一步操作/Music, 通过context.getExternalFilesDirs(Environment.DIRECTORY_MUSIC)获取/Podcasts, 通过context.getExternalFilesDirs(Environment.DIRECTORY_PODCASTS)获取/Ringtones, 通过context.getExternalFilesDirs(Environment.DIRECTORY_RINGTONES)获取/Alarms, 通过context.getExternalFilesDirs(Environment.DIRECTORY_ALARMS)获取/Notifications, 通过context.getExternalFilesDirs(Environment.DIRECTORY_NOTIFICATIONS)获取/Pictures, 通过context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES)获取/Movies, 通过context.getExternalFilesDirs(Environment.DIRECTORY_MOVIES)获取media,obb,dataAndroid10及以上 按包名为应用划分 沙盒目录,跟随 app 卸载而删除,外部无法访问storage/emulated/0/Music/Android 10及以上 无法通过路径访问,SAF,MediaStore 可行storage/emulated/0/Pictures/访问同上storage/emulated/0/Ringtones/访问同上storage/emulated/0/Alarms/访问同上storage/emulated/0/Notifications/访问同上storage/emulated/0/Podcasts/访问同上storage/emulated/0/Movies/访问同上storage/emulated/0/Download/访问同上storage/emulated/0/DCIM/访问同上storage/emulated/0/Documents/访问同上storage/emulated/0/Screenshots/访问同上storage/emulated/0/Audiobooks/访问同上
Android 逻辑角度看
-
App-specific storage
-
存储类型:应用专用存储,私有目录
-
使用方法:
getFilesDir(),getCacheDir(),getExternalFilesDir(),getExternalCacheDir(),getExternalMediaDirs() -
操作权限:内部存储不需要权限,外部存储从 Android4.4 之后也不需要
-
外部应用访问:无法访问内部存储,Android 10及以后无法外部存储
-
卸载是否移除:移除
-
Preferences
-
存储类型:内部私有存储,键值对存在
-
使用方法:Jetpack Preferences library
-
操作权限:不需要
-
外部应用访问:不可以访问
-
卸载是否移除:移除
-
Databases
-
存储类型:内部私有存储,持久化结构
-
使用方法:Room persistence library
-
操作权限:不需要
-
外部应用访问:不可以访问
-
卸载是否移除:移除
-
Shared storage - Media
-
存储类型:共享存储,比如一些图片,视音频
-
使用方法:MediaStore API
-
操作权限:Android9或者更低版本都需要
READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE。Android10或更高版本在访问外部app才需要 -
外部应用访问:可以访问,但是需要
READ_EXTERNAL_STORAGE权限 -
卸载是否移除:不移除
-
Shared storage - Documents、files
-
存储类型:共享存储,比如文档,文件
-
使用方法:Storage Access Framework
-
操作权限:不需要
-
外部应用访问:可以访问,文件选择器可以扫描到
-
卸载是否移除:不移除
一些重要的建议
- 存储作用域 scoped-storage
针对 Android10 及以上设备,可通过 requestLegacyExternalStorage 来控制,默认false。低版本设备可以通过设置为false来开启这个特性。以下观点均默认 Andriod 10及以上版本默认支持该特性。 - 考虑到专用存储空间会随着 app 的卸载而被移除,针对那些用户希望独立于 app 而存在的文件,比如照片,多媒体等,不希望卸载 app 之后被删除则就应该使用共享存储来保留。
- 如果希望外部应用可以访问到内部存储的文件,应该使用 FileProvider 结合 FLAG_GRANT_READ_URI_PERMISSION 使用。
getCacheDir()可能因为设备内部存储空间不足而删除部分缓存文件,确保在读取之前检测文件是否存在- 如果 app 仅在应用内部为用户提供有价值的多媒体信息,则应使用
getExternalFilesDir来保存这些多媒体信息,例如选择getExternalFilesDir(Environment.DIRECTORY_PICTURES)。 - 使用 MediaStore 时,系统会自动扫描外部存储并针对媒体进行,目录为
/storage/emulated/0/
- MediaStore.Images,被存储在
DCIM/和Picture/ - MediaStore.Video,被存储在
DCIM/,Picture/和Movies/ - MediaStore.Audio,被存储在
Alarms/,Audiobooks/,Music/,Notifications/,Podcasts/和Ringtones/ - MediaStore.Downloads,被存储在
Download/, 这类型是 Android10 及以上可用 - MediaStore.Files,只有 Andriod10及以上可用
- 如果尝试使用外部存储的文件原始路径去访问,即使你有
READ_EXTERNAL_STORAGE权限,在 android 10 及以上也会收到FileNotFoundException。应该改成使用 MediaStore API 来访问。 - Android 10及以上版本的设备,每一个多媒体文件都有一个应用归属属性,非归属应用访问时需要授权
READ_EXTERNAL_STORAGE权限。当应用卸载重装之后,访问之前保存的文件也会需要权限,原因是该保存的文件属于之前安装的应用。
Android10及以上实践建议
- 通过控制 [android:requestLegacyExternalStorage] (https://developer.android.com/training/data-storage/compatibility) 属性来决定要不要开启新特性 scoped-storage
|
1 2 3 4 5 6 7
|
|
-
读取非共享外部存储已经不需要
READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE,因为整体是一个 沙箱 涉及,减少权限请求。只有读取其他app的共享外部存储数据才需要,代码向下兼容。 -
读取共享数据需要请求必要的权限,使用 MediaStore API 进行文件访问
-
针对其他应用创建的共享文件
-
访问:请求必要权限 -> ContentResoler 查找并打开文件
-
写入:当且仅当你的应用是系统某个功能的默认应用才可以,比如照片管理应用,默认音乐应用等。被设置默认角色之后 -> ContentResoler 查找并打开文件,执行编辑、变更操作。
最后
愿你有一天,真爱自己,善待自己。










