You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动