使用 SAF,我选择了一个用于 R/W 媒体文件的文件夹。
对于
MediaStore.Audio.Media.getContentUri(volumeName)
(29+ API),我需要指定一个卷名称(可以是主存储或外部 SD 卡),然后使用 at: 指定相对路径
val contentValues = ContentValues().apply {
put(
MediaStore.Audio.Media.RELATIVE_PATH,
relativePath
)
}
例如,我有以下 URI (
uriFolder
):
content://com.android.externalstorage.documents/tree/primary%3AMUSIC
(主存储)content://com.android.externalstorage.documents/tree/18F0-2D1C%3AMusic
(外接 SD 卡)所以基本上卷名称可以是
"external_primary"
(主要内置存储)或 "18F0-2D1C"
(外部 SD 卡)
我可以解析这个字符串并获取卷名称:
a) 如果
"primary"
那么它将是 "external_primary"
(我们在 public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
类也有以下常量 MediaStore
)
b) 如果是外部 SD 卡,则只需从字符串中获取
"18F0-2D1C"
。
但是还有以下功能:
MediaStore.getVolumeName(uri)
(29+ API)
我认为它会给我相同的结果,而不是手动解析 URI 路径字符串:
val volumeName = MediaStore.getVolumeName(uriFolder)
但是我遇到以下异常:
java.lang.IllegalArgumentException: Missing volume name: content://com.android.externalstorage.documents/tree/primary%3AMUSIC
虽然对于
relativePath
我仍然需要手动解析 URI 路径字符串以在 "MUSIC"
之后获取
%3A
因此,将
MediaStore
和 SAF
一起使用并完全停止使用 File
类 是相当棘手的
MediaStore.getVolumeName(uri) 仅适用于您从媒体商店获取的 uri。
此类内容以 content://media/... 开头
MediaStore.getVolumeName(uri):外部:content://media/external/file/1000469026
MediaStore.getVolumeName(uri): 28ef-1de5 for: content://media/28ef-1de5/file/391988