2012-06-11 23 views
1

我使用AudioRecorder錄製短音頻剪輯,但我調用AudioRecord.start()時我得到IllegalStateException我一直在尋找小時,但無法找到這個原因...IllegalStateException當調用AudioRecord.start()

我已設置音頻錄製+寫入外部存儲權限。

這裏有一塊我的代碼:

// 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; 
} 
+0

爲什麼你使用'AsyncTask'來做到這一點? – Squonk

+0

這是更復雜的應用程序的一部分。我已經完成視頻採集和傳感器處理使用異步沒有問題。 –

+1

無論是否成功準備,您都將開始錄製對象。如果應該輸入'IOException' catch塊(即「prepare()失敗」),你應該處理它不同的問題。 – kcoppock

回答

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())和你應該調用在主Activity代碼從onCheckedChanged聽者的tbAsyncTask.cancel(...)方法(假設tbCheckBox或一些其它CompoundButton)。

+0

循環是問題,對象需要重新創建和釋放。 –

+0

@EmilAnca:是的,當我看着狀態機圖時,似乎是問題所在。請記住我所說的關於使用'AsyncTask'的isCancelled()方法。最好有一個'AsyncTask'被'Activity'取消,它創建它而不是在UI上爲''''''''''做一個'doInBackground(...)'線程測試。如果您創建一個獨立的'AsyncTask',尤其如此,可以在UI元素可能不同的'Activities'中重複使用。 – Squonk

相關問題