调用AudioRecord.start()时出现IllegalStateException

时间:2012-06-11 16:16:47

标签: android audio capture mediarecorder

我正在使用AudioRecorder来录制短音频片段,但是在调用AudioRecord.start时我收到了IllegalStateException()我一直在找几个小时但是找不到原因......

我已设置Audio Rec + Write外部存储权限。

这是我的一段代码:

// main activity...

// Audio inits
    final MediaRecorder recorder = new MediaRecorder();

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getTempPath());

...

// called the sound rec async

new SoundComponent(tvmic, pb, tb).execute(recorder);

// SoundComponent.java
// Getting IllegalStateException when calling recorder[0].start();

[..]
protected Long doInBackground(MediaRecorder... recorder) {


     try {
         recorder[0].prepare();
        } catch (IOException e) {
            Log.e("100", "prepare() failed");
        }




    while (tb.isChecked())
    {
        //publishProgress();
        //recorder[0].prepare();

         recorder[0].start(); // here it were it throws
         try {
             Thread.sleep(250);
         } catch (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
        // int amplitude = recorder[0].getMaxAmplitude();

         recorder[0].stop();

    }


    // TODO Auto-generated method stub
    return null;
}

[..]

public String getTempPath() // audio temp path
{
    String path =  Environment.getExternalStorageDirectory().getAbsolutePath();
    path+="/temp/audiorectemp.3gp";
    return path;
}

1 个答案:

答案 0 :(得分:2)

在循环中多次启动和停止MediaRecorder可能不是一个好主意。仔细看看你正在做什么,我已经修剪了你的代码,以便更容易看到......

while (tb.isChecked())
{
     recorder[0].start(); // here it were it throws
     // Sleep here
     recorder[0].stop();
}

第一次调用start()时可能没有抛出异常,但它会在第二次循环时抛出异常。请参阅状态机图... MediaRecorder

此外,要检测何时应该退出doInBackground(...)线程,可以使用AsyncTask上的方法,可以从UI线程调用以取消它。

理想情况下,循环应为while (!isCancelled()),您应该从主AsyncTask.cancel(...)代码onCheckedChanged的{​​{1}}监听器调用tb方法(假设{ {1}}是Activity或其他tb}。