Android数据存储及权限问题梳理
一、存储空间
1、APP专属空间
访问方式
1.1、内部存储空间访问方式:
//使用到的方法及得到的路径,其中com.example.demo2不是固定的
getFilesDir() -> /data/user/0/com.example.demo2/files
getCacheDir() -> /data/user/0/com.example.demo2/cache
通过adb shell查找对应的目录
emu64a:/data/user/0/com.example.demo2 # pwd
# 当前目录
/data/user/0/com.example.demo2
emu64a:/data/user/0/com.example.demo2 # ls -l
# 当前目录下有3个文件夹
total 24
drwxrws--x 2 u0_a206 u0_a206_cache 4096 2024-12-01 13:24 cache
drwxrws--x 2 u0_a206 u0_a206_cache 4096 2025-01-13 11:44 code_cache
drwxrwx--x 2 u0_a206 u0_a206 4096 2024-12-01 14:23 files
1.2、外部存储空间访问方式:
//使用到的方法及得到的路径,其中com.example.demo2不是固定的
getExternalFilesDir(null) -> /storage/emulated/0/Android/data/com.example.demo2/files
getExternalCacheDir() -> /storage/emulated/0/Android/data/com.example.demo2/cache
通过adb shell查找对应的目录
emu64a:/storage/emulated/0/Android/data/com.example.demo2 # pwd
# 当前目录
/storage/emulated/0/Android/data/com.example.demo2
emu64a:/storage/emulated/0/Android/data/com.example.demo2 # ls -l
# 该目录下的文件夹
total 16
drwxrws--- 2 u0_a206 ext_data_rw 4096 2024-12-01 14:23 cache
drwxrws--- 4 u0_a206 ext_data_rw 4096 2024-12-01 14:27 files
getExternalFilesDir()参数不为null时,获取到的路径/storage/emulated/0/Android/data/com.example.demo2/files/xx,最后的xx与参数对应
getExternalFilesDir(Environment.DIRECTORY_DCIM);
getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
getExternalFilesDir(Environment.DIRECTORY_PICTURES);
getExternalFilesDir(Environment.DIRECTORY_ALARMS);
getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
getExternalFilesDir(Environment.DIRECTORY_MOVIES);
getExternalFilesDir(Environment.DIRECTORY_MUSIC);
getExternalFilesDir(Environment.DIRECTORY_NOTIFICATIONS);
getExternalFilesDir(Environment.DIRECTORY_PODCASTS);
getExternalFilesDir(Environment.DIRECTORY_RINGTONES);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getExternalFilesDir(Environment.DIRECTORY_SCREENSHOTS);
getExternalFilesDir(Environment.DIRECTORY_AUDIOBOOKS);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
getExternalFilesDir(Environment.DIRECTORY_RECORDINGS);
}
通过adb shell查找对应的目录
emu64a:/storage/emulated/0/Android/data/com.example.demo2/files # pwd
# 当前目录
/storage/emulated/0/Android/data/com.example.demo2/files
emu64a:/storage/emulated/0/Android/data/com.example.demo2/files # ls -l
#该目录下的文件夹,和getExternalFilesDir()参数有关
total 104
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Alarms
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Audiobooks
drwxrws--- 2 u0_a206 ext_data_rw 4096 2024-12-01 14:23 DCIM
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Documents
drwxrws--- 2 u0_a206 ext_data_rw 4096 2024-12-01 14:27 Download
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Movies
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Music
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Notifications
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 11:58 Pictures
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Podcasts
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Recordings
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Ringtones
drwxrws--- 2 u0_a206 ext_data_rw 4096 2025-01-13 12:03 Screenshots
备注:adb root:解决adb命令行报错Permission denied
是否需要申请权限
1、getFilesDir()、getCacheDir() 方法不需要申请权限。
2、getExternalFilesDir()、getExternalCacheDir() 方法,在Android 4.4(API 级别 19)或更高版本不需要申请权限,否则需要申请。
其他应用是否可以访问
内部存储空间,其它App不能访问该空间
外部存储空间,在具有适当权限的情况下访问
卸载应用时是否移除文件
卸载应用时,会移除这些文件夹
2、共享存储空间
共享存储空间包含三块,媒体、文档和其他文件
本次主要分享一下媒体共享存储空间
2.1 、媒体共享存储空间
访问方式
照片选择器
暂时不做详解
MeidaStore Api
使用ContentProvider技术进行实现。大致原理就是把图片、音频、视频放到特定的文件夹里,然后系统会扫描这些文件夹里的文件,并把文件的属性信息添加到不同的数据库表中(此处是个人理解,如有问题欢迎指正)。
emu64a:/storage/emulated/0 # pwd
# 当前目录
/storage/emulated/0
emu64a:/storage/emulated/0 # ls -l
# 该目录下的文件夹
# 1、存到DCIM、Pictures文件夹下的图片或者屏幕截图,会保存到MediaStore.Images表中
# 2、存到DCIM、Movies、Pictures文件夹下的视频,会保存到MediaStore.Video表中
# 3、存到Alarms、Audiobooks、Music、Notifications、Podcasts、Ringtones文件夹下的音频,会保存到MediaStore.Audio表中
# 4、存到Download文件夹下文件,会保存到MediaStore.Downloads表中。注意:只有大于等于Android 10(API 29)才会保存到该表中,低版本不可用
# 5、还有个MediaStore.Files的集合。如果你的App使用分区存储(适用于以 Android 10 或更高版本为目标平台的应用),集合只会显示你的App创建的照片、视频和音频文件。如果分区存储不可用或未使用,集合将显示所有类型的媒体文件。
total 104
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Alarms
drwxrws--x 5 media_rw media_rw 4096 2024-12-01 13:24 Android
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Audiobooks
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 DCIM
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Documents
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Download
drwxrws--- 3 u0_a198 media_rw 4096 2024-12-01 13:24 Movies
drwxrws--- 3 u0_a198 media_rw 4096 2024-12-01 13:24 Music
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Notifications
drwxrws--- 3 u0_a198 media_rw 4096 2024-12-01 15:09 Pictures
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Podcasts
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Recordings
drwxrws--- 2 u0_a198 media_rw 4096 2024-12-01 13:24 Ringtones
是否需要权限
1、在 Android 9(API 级别 28)或更低版本中,新增和读取文件均需要READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE权限
下图是使用MediaStore Api新增图片时,未给WRITE_EXTERNAL_STORAGE权限时的错误
下图是使用MediaStore Api读取图片时,未给READ_EXTERNAL_STORAGE权限时的错误
2、在Android 10(API 级别 29)至 Android 12(API 级别 32)之间,通过MediaStore Api新增图片、音频、视频不需要任何权限,读取自己应用新增的图片、音频、视频也不要任何权限,但是读取别的应用新增的图片、音频、视频则需要READ_EXTERNAL_STORAGE权限
下图是app未声明任何文件权限的情况下,使用MedidaStore Api成功新增图片
下图是app未声明任何文件权限的情况下,使用MedidaStore Api读取图片资源,能成功获取到自己App增加的图片。
下图是app声明并授权READ_EXTERNAL_STORAGE权限的情况下,使用MedidaStore Api读取图片资源,能成功获取到所有图片。
3、在Android 13(API 级别 33)或更高的版本中,通过MediaStore Api新增图片、音频、视频不需要任何权限,读取自己应用新增的图片、音频、视频也不要任何权限,但是读取别的应用新增的图片、音频、视频则需要READ_MEDIA_IMAGES或者READ_MEDIA_VIDEO或者READ_MEDIA_AUDIO权限
新增和读取图片就不截图了,参考上面第2项的截图,唯一的差异,我截一下图
其他应用是否可以访问
是,但是需要注意权限申请
卸载应用时是否移除文件
卸载时,不会删除这些文件