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

如何使用MediaStore API结合AudioRecord实现安卓音频录制

AudioRecord适配MediaStore API实现方案

前置依赖配置

  • Android 6.0及以上版本需动态申请RECORD_AUDIO权限
  • Android 9及以下版本额外需要申请WRITE_EXTERNAL_STORAGE权限
  • TargetSdk >= 29(Android 10)无需申请存储权限,直接使用MediaStore操作公共媒体目录即可

适配后完整代码

原有AudioRecord的采集逻辑完全复用,仅修改文件写入相关的逻辑即可,适配后代码如下:

// 1. 构造MediaStore音频元数据,代替原有直接创建本地File的逻辑
ContentValues audioValues = new ContentValues();
audioValues.put(MediaStore.Audio.Media.DISPLAY_NAME, "test.pcm");
audioValues.put(MediaStore.Audio.Media.MIME_TYPE, "audio/pcm");
// API 29及以上可以指定存储子路径,低版本可删除该行,默认存至Music根目录
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    audioValues.put(MediaStore.Audio.Media.RELATIVE_PATH, Environment.DIRECTORY_MUSIC + "/CustomRecord");
    // 录制过程中标记为待处理,避免其他应用访问
    audioValues.put(MediaStore.Audio.Media.IS_PENDING, 1);
}

// 2. 插入元数据获取音频Uri
Uri audioUri = getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, audioValues);
if (audioUri == null) {
    // 插入失败处理逻辑
    return;
}

try {
    // 3. 通过Uri打开输出流,替换原有FileOutputStream
    OutputStream outputStream = getContentResolver().openOutputStream(audioUri);
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
    DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);

    // 以下AudioRecord采集逻辑和原有实现完全一致,无需修改
    int minBufferSize = AudioRecord.getMinBufferSize(11025,
            AudioFormat.CHANNEL_IN_STEREO,
            AudioFormat.ENCODING_PCM_16BIT);

    short[] audioData = new short[minBufferSize];

    AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
            11025,
            AudioFormat.CHANNEL_IN_STEREO,
            AudioFormat.ENCODING_PCM_16BIT,
            minBufferSize);

    audioRecord.startRecording();

    while(recording){
        int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
        for(int i = 0; i < numberOfShort; i++){
            dataOutputStream.writeShort(audioData[i]);
        }
    }

    if(!recording){
        audioRecord.stop();
        dataOutputStream.close();
        audioRecord.release(); // 建议补充资源释放逻辑
    }

    // 4. 录制完成后更新状态,通知系统文件已可访问
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        ContentValues updateValues = new ContentValues();
        updateValues.put(MediaStore.Audio.Media.IS_PENDING, 0);
        getContentResolver().update(audioUri, updateValues, null, null);
    }

} catch (IOException e) {
    e.printStackTrace();
}

关键修改说明

仅文件存储逻辑做了适配,AudioRecord采集逻辑完全保留,不影响你自定义采样率、声道、位深的需求。

  • 不再直接构造本地File对象,改为先向MediaStore插入音频元数据获取对应的Uri,通过Uri操作文件
  • 输出流从直接读取本地文件路径改为通过ContentResolver.openOutputStream(uri)获取
  • 新增录制状态标记IS_PENDING,避免录制过程中其他应用扫描到未完成的音频文件

注意事项

  • 如果需要生成可直接播放的WAV格式文件,只需在PCM数据写入完成后,在文件开头补充对应参数的WAV头信息即可,MediaStore相关逻辑无需修改
  • 后续访问录制的音频可以直接使用返回的audioUri,无需再通过本地文件路径读取
  • 低版本Android系统兼容只需删除RELATIVE_PATH和IS_PENDING相关的版本判断逻辑即可,其余代码通用

内容的提问来源于stack exchange,提问作者Abdellah SAYOUL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:06:05