Android开发中Java MediaRecorder录音后音频无法播放问题求解
Android MediaPlayer无法播放录制音频的解决方案
核心问题及修复点
- 音频编码器参数配置错误
你当前setupMediaRecorder()方法中调用setAudioEncoder时传入了MediaRecorder.OutputFormat.AMR_NB,该常量属于输出格式分类,不是合法的音频编码器参数,正确参数应为MediaRecorder.AudioEncoder.AMR_NB。参数错误会导致生成的音频文件格式异常,MediaPlayer无法识别解析。 - 存储路径适配问题
getExternalStorageDirectory()在Android 10(API 29)及以上版本已被废弃,公共存储根目录不允许普通应用直接写入,即使申请了存储权限也会被系统拦截。建议使用应用专属外部目录存储音频,该目录读写不需要申请额外的存储权限:// 替换原有pathSave赋值逻辑 File audioDir = getExternalFilesDir(Environment.DIRECTORY_MUSIC); File recordFile = new File(audioDir, "audiorecordtest.3gp"); pathSave = recordFile.getAbsolutePath(); - 资源未正确释放
录制完成后仅调用了stop()方法,未调用release()释放MediaRecorder占用的硬件资源,可能导致后续录制或播放出现异常。 - 播放逻辑缺少异常处理
当前播放逻辑中prepare()出现异常后仍然会调用start()方法,会触发空指针或状态异常,且没有错误日志提示,无法排查问题。 - 多余权限申请逻辑
btnRecord的点击事件监听器中存在一个多余的匿名类初始化块,里面的requestPermissions()会在监听器初始化时无理由触发权限申请,属于无效代码可以直接删除。
关键代码修改示例
修正音频编码器配置
private void setupMediaRecorder() { mediaRecorder = new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 替换为正确的音频编码器常量 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setOutputFile(pathSave); }
修正录制停止逻辑
btnStopRecording.setOnClickListener(v -> { if (mediaRecorder != null) { mediaRecorder.stop(); mediaRecorder.release(); mediaRecorder = null; } btnStopRecording.setEnabled(false); btnPlay.setEnabled(true); btnRecord.setEnabled(true); btnStop.setEnabled(false); });
修正播放逻辑
btnPlay.setOnClickListener(v -> { btnStopRecording.setEnabled(false); btnStop.setEnabled(true); btnRecord.setEnabled(true); mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(pathSave); mediaPlayer.prepare(); mediaPlayer.start(); Toast.makeText(rec_ingress.this, "正在播放...", Toast.LENGTH_SHORT).show(); // 播放完成自动释放资源 mediaPlayer.setOnCompletionListener(mp -> { mp.release(); mediaPlayer = null; btnStop.setEnabled(false); btnPlay.setEnabled(true); }); // 播放错误监听 mediaPlayer.setOnErrorListener((mp, what, extra) -> { Toast.makeText(rec_ingress.this, "播放失败,错误码:" + what, Toast.LENGTH_SHORT).show(); mp.release(); mediaPlayer = null; return true; }); } catch (IOException e) { e.printStackTrace(); Toast.makeText(rec_ingress.this, "播放错误:" + e.getMessage(), Toast.LENGTH_SHORT).show(); if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } } });
内容的提问来源于stack exchange,提问作者WhitePhantom
相关产品推荐
相关产品推荐

