在 Android 10 及更高版本中,通过 MediaStore 访问以下 外部存储公共目录 时,如果操作的是应用自己创建的文件,则无需申请存储权限。这些目录属于系统明确定义的媒体集合,具体包括:
1. 媒体类型目录
1. 图片(Images) MediaStore.Images.Media /DCIM/、/Pictures/
应用可自由读写自己创建的图片文件,无需权限;读取其他应用的图片需 READ_MEDIA_IMAGES 权限。
2. 视频(Video) MediaStore.Video.Media /DCIM/、/Movies/、/Pictures/
应用可自由读写自己创建的视频文件,无需权限;读取其他应用的视频需 READ_MEDIA_VIDEO 权限。
3. 音频(Audio) MediaStore.Audio.Media /Music/、/Alarms/、/Podcasts/ 等
应用可自由读写自己创建的音频文件,无需权限;读取其他应用的音频需 READ_MEDIA_AUDIO 权限。
4. 下载文件(Downloads) MediaStore.Downloads (仅 Android 10+) /Download/
应用可自由读写自己创建的下载文件,无需权限;无法直接访问其他应用的非媒体文件(需通过 SAF)。
2. 关键说明
1. 权限豁免条件
仅当文件由当前应用创建时,通过 MediaStore 访问上述目录无需任何权限。例如:相机应用保存照片到 /DCIM/ 无需申请 WRITE_EXTERNAL_STORAGE。
若需访问其他应用创建的媒体文件(如图库中的照片),仍需动态申请 READ_MEDIA_IMAGES 等细粒度权限。
2. 非媒体文件限制
MediaStore 不支持直接操作非媒体文件(如 PDF、TXT 等)。若需访问 /Download/ 中的非媒体文件,必须使用 Storage Access Framework (SAF)。
3. 卸载与权限变化
应用卸载后,其创建的公共目录文件会变为“无主文件”。重新安装后访问这些文件时,需要申请 READ_EXTERNAL_STORAGE 权限,视为访问其他应用的文件。
3. 目录路径与代码示例
// 写入图片到 Pictures 目录(无需权限)
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "my_image.jpg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri != null) {
try (FileOutputStream fos = (FileOutputStream)
getContentResolver().openOutputStream(uri)) {
if (fos != null) {
fos.write("Java MediaStore Test my_image.jpg".getBytes());
Log.d("StorageTest", "Java MediaStore写入 my_image.jpg 成功: " + uri.toString());
}
} catch (Exception e) {
Log.e("StorageTest", "Java MediaStore写入 my_image.jpg 失败", e);
}
}
// 写入文件到 Download 目录(无需权限)
ContentValues downloadValues = new ContentValues();
downloadValues.put(MediaStore.Downloads.DISPLAY_NAME, "my_file.txt");
downloadValues.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);
Uri downloadUri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, downloadValues);
if (downloadUri != null) {
try (FileOutputStream fos = (FileOutputStream)
getContentResolver().openOutputStream(downloadUri)) {
if (fos != null) {
fos.write("Java MediaStore Test my_file.txt".getBytes());
Log.d("StorageTest", "Java MediaStore写入 downloadUri 成功: " + downloadUri.toString());
}
} catch (Exception e) {
Log.e("StorageTest", "Java MediaStore写入 downloadUri 失败", e);
}
}
4. 总结
通过 MediaStore 访问以下目录时,应用对自己创建的文件无需权限:
图片:DCIM/、Pictures/
视频:DCIM/、Movies/
音频:Music/、Alarms/ 等
下载文件:Download/(仅限媒体文件)