MediaStore查询指定文件夹音频无结果,求排查Selection问题
解决MediaStore查询多文件夹音频文件无结果的问题
我一眼就揪出了几个导致你查询空结果的关键问题,咱们一步步来修正:
1. 核心逻辑错误:IN匹配文件夹路径完全不对
你当前用MediaStore.Audio.Media.DATA IN (文件夹路径列表),但DATA字段存的是音频文件的完整绝对路径(比如/storage/emulated/0/Music/abc.mp3),不是文件夹路径。用IN去匹配文件夹路径,自然找不到任何匹配的文件——毕竟没有文件的完整路径会等于文件夹路径。
正确的思路应该是匹配文件路径以目标文件夹路径开头,也就是用LIKE结合通配符%,多个文件夹就用OR串联条件。
2. Android版本兼容性提示
从Android 10(API 29)开始,MediaStore.Audio.Media.DATA被标记为废弃,虽然部分老设备还能凑合用,但更规范的方式是用MediaStore.Audio.Media.RELATIVE_PATH(存储相对外部根目录的路径,比如Music/),不过如果要兼容低版本,继续用DATA也没问题。
修复后的代码示例
方案1:兼容全版本的多文件夹查询(基于DATA字段)
List<String> folderPaths = storage.loadFolderPaths(); if (folderPaths.isEmpty()) { // 处理空文件夹列表的情况 return; } Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; String[] projection = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA }; // 构建多个LIKE条件,用OR连接 StringBuilder selectionBuilder = new StringBuilder(); List<String> selectionArgs = new ArrayList<>(); for (int i = 0; i < folderPaths.size(); i++) { String folderPath = folderPaths.get(i); // 强制文件夹路径以"/"结尾,避免误匹配类似"/storage/emulated/0/Music1"的路径 if (!folderPath.endsWith("/")) { folderPath += "/"; } if (i > 0) { selectionBuilder.append(" OR "); } selectionBuilder.append(MediaStore.Audio.Media.DATA).append(" LIKE ?"); selectionArgs.add(folderPath + "%"); } String selection = selectionBuilder.toString(); String[] whereVal = selectionArgs.toArray(new String[0]); // 执行查询 Cursor cursor = getContentResolver().query( uri, projection, selection, whereVal, null );
方案2:API 29+推荐写法(基于RELATIVE_PATH)
如果你的应用只针对Android 10及以上,可以用相对路径简化逻辑:
List<String> folderRelativePaths = storage.loadFolderRelativePaths(); // 比如传入["Music/", "Recordings/"] StringBuilder selectionBuilder = new StringBuilder(); List<String> selectionArgs = new ArrayList<>(); for (int i = 0; i < folderRelativePaths.size(); i++) { String relPath = folderRelativePaths.get(i); if (i > 0) { selectionBuilder.append(" OR "); } selectionBuilder.append(MediaStore.Audio.Media.RELATIVE_PATH).append(" LIKE ?"); selectionArgs.add(relPath + "%"); } // 后续查询逻辑和方案1一致
额外要注意的细节
- 权限:确保已经申请了对应权限——Android 12及以下用
READ_EXTERNAL_STORAGE,Android 13+用READ_MEDIA_AUDIO。 - 路径格式:必须保证文件夹路径以
/结尾,否则会出现奇怪的误匹配。 - 空列表处理:一定要先判断文件夹列表是否为空,避免构建出无效的查询条件。
内容的提问来源于stack exchange,提问作者Rektirino




