MediaRecorder启动方法调用时出现IllegalStateException问题求助
排查MediaRecorder.start()触发IllegalStateException的问题
我来帮你梳理下代码里可能导致这个异常的几个关键点,以及对应的解决办法:
1. 硬编码常量值的隐患
你直接用数字1来设置音频源、输出格式和编码器,虽然部分常量的数值确实是1(比如MediaRecorder.AudioSource.MIC),但不同Android版本的常量值可能存在差异,而且这种写法可读性极差,很容易因版本适配出错。比如MediaRecorder.OutputFormat.DEFAULT的实际数值是0,你设置成1(对应OutputFormat.THREE_GPP)虽然暂时能用,但硬编码始终是不稳定的写法。
2. 输出文件路径的问题
你把输出文件设为/dev/null,在部分Android版本中,MediaRecorder需要一个可写入的有效文件路径,系统的空设备文件可能无法满足其初始化要求,这会导致prepare()过程隐性失败,进而在调用start()时触发异常。
3. 异常处理过于宽松
第一个catch (RuntimeException re)块直接吞掉了异常,没有任何日志输出。如果初始化MediaRecorder时(比如因缺少录音权限导致setAudioSource()失败)出现错误,你完全无法定位问题,后续调用prepare()和start()自然会因为对象状态不正确抛出IllegalStateException。
修正后的代码示例
public void start() { if (this.mRecorder == null) { this.mRecorder = new MediaRecorder(); try { // 使用官方常量代替硬编码数字,避免版本适配问题 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 使用应用私有目录下的临时文件,规避存储权限问题 String outputPath = getExternalFilesDir(null) + "/temp_recording.3gp"; mRecorder.setOutputFile(outputPath); mRecorder.prepare(); mRecorder.start(); } catch (RuntimeException re) { // 打印异常日志,方便排查问题 re.printStackTrace(); // 异常发生时及时释放资源,避免内存泄漏 if (mRecorder != null) { mRecorder.release(); mRecorder = null; } } catch (IOException e) { e.printStackTrace(); if (mRecorder != null) { mRecorder.release(); mRecorder = null; } } } }
额外注意事项
- 录音权限:务必在
AndroidManifest.xml中声明<uses-permission android:name="android.permission.RECORD_AUDIO" />,并且在Android 6.0及以上版本中动态申请该权限。没有权限的话,setAudioSource()会直接失败,进而引发后续异常。 - 状态机顺序:MediaRecorder有严格的状态流程,必须按照「初始化 → 设置源/格式/编码器 → setOutputFile → prepare → start」的顺序调用,任何步骤颠倒都会触发
IllegalStateException。
内容的提问来源于stack exchange,提问作者Piyush-Ask Any Difference
相关产品推荐
相关产品推荐

