You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Cursor与getContentResolver().query MediaStore无法获取最新音频文件

解决MediaStore无法获取新增音频文件的问题

我帮不少开发者排查过类似的问题,你遇到的核心痛点其实是MediaStore的媒体索引机制和你的数据更新逻辑没匹配上。咱们一步步拆解解决:

一、最常见原因:MediaStore未实时扫描新增文件

当你手动录制并保存音频到指定文件夹后,Android系统的媒体扫描器不会立刻感知到这个文件——除非你主动触发扫描,或者用系统推荐的方式写入文件。

解决办法1:手动触发媒体扫描

如果你是用File类直接写入的文件,写完后一定要调用媒体扫描器让系统把这个文件加入MediaStore索引:

// 假设newFile是你刚保存的音频文件
MediaScannerConnection.scanFile(
    getApplicationContext(),
    new String[]{newFile.getAbsolutePath()},
    new String[]{"audio/mpeg"}, // 匹配你的音频格式,比如audio/wav
    (path, uri) -> {
        // 扫描完成后,立刻更新你的播放列表
        refreshAudioPlaylist();
    }
);

解决办法2:用MediaStore API写入文件(推荐)

如果你的目标是Android 10及以上,更稳妥的方式是直接通过MediaStore插入文件,这样系统会自动把文件加入索引,不需要手动扫描:

ContentValues audioValues = new ContentValues();
audioValues.put(MediaStore.Audio.Media.DISPLAY_NAME, "my_recording.mp3");
audioValues.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg");
// 指定你要保存的文件夹,比如内部存储的Music/MyRecordings/
audioValues.put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/MyRecordings/");

// 插入到MediaStore,获取写入Uri
Uri audioUri = getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, audioValues);

// 通过Uri写入音频数据
try (OutputStream outputStream = getContentResolver().openOutputStream(audioUri)) {
    // 这里写入你的录制音频数据
} catch (IOException e) {
    e.printStackTrace();
}

二、你的Cursor没有重新查询

很多开发者只会在App启动时查一次Cursor,之后新增文件后没有重新执行查询逻辑,自然看不到新文件。

解决办法:监听MediaStore变化,自动更新列表

注册一个ContentObserver,监听音频媒体库的变化,一旦有新增/删除/修改,就重新查询Cursor更新播放列表:

private ContentObserver audioContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        // 媒体库变化时,重新获取音频列表
        refreshAudioPlaylist();
    }
};

// 在Activity/Fragment的onResume里注册观察者
@Override
protected void onResume() {
    super.onResume();
    getContentResolver().registerContentObserver(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        true, // 监听子目录变化
        audioContentObserver
    );
}

// 在onPause里注销,避免内存泄漏
@Override
protected void onPause() {
    super.onPause();
    getContentResolver().unregisterContentObserver(audioContentObserver);
}

// 你的刷新列表方法
private void refreshAudioPlaylist() {
    // 重新执行你的Cursor查询逻辑
    String selection = MediaStore.Audio.Media.DATA + " LIKE ?";
    String[] selectionArgs = new String[]{"%/MyRecordings/%"}; // 你的指定文件夹路径
    Cursor cursor = getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        null,
        selection,
        selectionArgs,
        MediaStore.Audio.Media.DATE_ADDED + " DESC" // 按新增时间排序,确保最新的在前面
    );
    
    // 处理Cursor,更新你的播放列表UI
    if (cursor != null) {
        // ... 你的逻辑
        cursor.close();
    }
}

三、别忘了检查权限

如果是Android 13及以上,你需要申请READ_MEDIA_AUDIO权限;Android 12及以下需要READ_EXTERNAL_STORAGE权限。确保你已经动态申请并获得了这些权限,否则MediaStore会返回空数据。

最后排查点:你的查询条件是否正确

检查你的Cursor查询的selection参数,确认路径过滤是否准确——比如有没有写错文件夹名称,或者路径的斜杠是否正确(比如%/MyRecordings/%而不是%MyRecordings%,避免匹配到其他同名文件夹)。

内容的提问来源于stack exchange,提问作者Khurram Shahzad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:43:44