2011-02-28 129 views
13

Hej,即時試圖讓AudioRecord工作。因爲我需要一個更大的項目。但它似乎弄得很多。 我一直在嘗試很多東西,所以當我追蹤這個錯誤時,我回到了基本。 我正在使用我的Samsung Galaxy S作爲我的調試設備。Android AudioRecord - 不會初始化第二次

我的問題是,第一次重新啓動設備後,我可以初始化我創建的AudioRecord對象,而不會出現任何問題。 但我第二次運行它,它不會初始化AudioRecord對象。 我試過了幾個頻率,fyi。

這裏是我的代碼:

package android.audiorecordtest; 

import android.app.Activity; 
import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class AudioRecordTest extends Activity { 

    int frequency; 
    AudioRecord audRec; 
    TextView txtVw; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     txtVw = (TextView) findViewById(R.id.txtVw); 


     frequency=8000; 
     int bufferSize=(AudioRecord.getMinBufferSize(frequency, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT))*2; 
     if (bufferSize>0) { 
      audRec = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 
       int status = audRec.getState(); 
     if (status == AudioRecord.STATE_INITIALIZED) { 
      txtVw.setText("Initialized" + frequency); 
     } else { 
      txtVw.setText("Not Initialized i=" + frequency); 
     } 
     } 

通過logcat的信息,找了幾個小時,我發現這個事件

02-28 10:46:37.048: DEBUG/dalvikvm(4477): GC_EXPLICIT freed 1801 objects/98944 bytes in 97ms 
02-28 10:46:37.048: VERBOSE/AudioRecord(4477): stop 

這似乎是「解除對AudioRecord本土保持後 所以我試着用我的Audiorecord object.release()做一個重寫finalize。這個沒有工作,但是..任何人有任何想法?

+0

我真的很奇怪,爲什麼沒有人有任何答案,是不是因爲你們無法重現的問題,還是因爲人們只是不能被人打擾的幫助,或:你可以按如下方式使用它? – 2011-03-07 08:36:02

+0

對於那些磕磕絆絆的人,請確保您有記錄許可! – NateS 2012-01-01 05:45:47

+1

@NateS如果你沒有記錄權限,那麼它甚至不會初始化第一次,因爲我的問題標題明確指出:) 但是,如果有人只有第一次初始化嘗試的問題,那麼他們應該檢查他們在AndroidManifest.xml中的權限 – 2012-01-06 09:59:42

回答

11

我能夠重現您的問題(在三星手機上)。我添加了一個的onDestroy()方法釋放記錄:

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    System.out.println("OnDestroy"); 
    audRec.release(); 
} 

添加此之後,audioRecord似乎每次活動啓動時正確初始化。

+1

+1對我來說,我需要一個AsyncTask的onCancelled()方法,但是我不知道如果沒有這個,我該如何處理這個問題的底部。謝謝。 :) – Mikaveli 2013-08-20 15:47:57

0

你應該試試t調用audRec.stop()釋放資源。

+0

停止僅用於停止正在運行的錄音。但Release還有一個try-catch來呼叫停止,儘管釋放釋放資源,但並沒有停止。就我所看過的課程而言。另外謝謝。 – 2011-03-03 07:02:38

1

回答我自己的問題,我發現它可以使用AudioRecord的唯一方法是永遠不會將其作爲全局變量,不知道爲什麼,但它似乎不會讓您釋放實例的資源如果你這樣做是正確的。

+0

你應該嘗試喬丹的方式。我這樣做也是這樣,它工作得很好... – ThaMe90 2011-04-26 12:53:09

+0

不再有實現,但是如果他再現它,並解決它,即時通訊足夠安全,給他一個正確的答案,感謝它帶來了我的注意力。 – 2011-04-27 08:30:53

+0

我必須說,在調用release()之後,將它設置爲null有點超出頂部,GC會在某個時候自動爲您清理它,因此您可以自由地重新初始化它。 – ThaMe90 2011-04-27 08:34:24

5

我有同樣的問題,通常audRec.release()確實有幫助,但如果您需要停止並啓動多次,以下代碼更健壯。另外,我有一個問題,錄製發生在一個單獨的線程中,Android有時在長時間運行時會導致線程死亡。所以看看這個代碼,它可以確保當其他線程是死的,基於以下audRec.start()停止錄音甚至舉行,並釋放:

import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 

public class RecorderSingleton { 

    private static final int FREQUENCY = 16000; 

    public static RecorderSingleton instance = new RecorderSingleton(); 
    private AudioRecord recordInstance = null; 
    private int bufferSize; 

    private RecorderSingleton() { 
     bufferSize = AudioRecord.getMinBufferSize(FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    } 

    public boolean init() { 
     recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 
     if (recordInstance.getState() == AudioRecord.STATE_UNINITIALIZED) { 
      return false; 
     } 
     return true; 
    } 

    public int getBufferSize() { 
     return bufferSize; 
    } 
    public boolean start() { 
     if (recordInstance != null && recordInstance.getState() != AudioRecord.STATE_UNINITIALIZED) { 
      if (recordInstance.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) { 
       recordInstance.stop(); 
      } 
      recordInstance.release(); 
     } 
     if (!init()) { 
      return false; 
     } 
     recordInstance.startRecording(); 
     return true; 
    } 

    public int read(short[] tempBuffer) { 
     if (recordInstance == null) { 
      return AudioRecord.ERROR_INVALID_OPERATION; 
     } 
     int ret = recordInstance.read(tempBuffer, 0, bufferSize); 
     return ret; 
    } 

    public void stop() { 
     if (recordInstance == null) { 
      return; 
     } 
     recordInstance.stop(); 
     recordInstance.release(); 
    } 
} 

然後,如果你有一個記錄線程

import android.media.AudioRecord; 

public class Recorder implements Runnable { 
    private int requiredSamples; 
    private int takenSamples = 0; 
    private boolean cancelled = false; 

    public void run() { 

     // We're important... 
     android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 

     int bufferRead = 0; 
     int bufferSize = RecorderSingleton.instance.getBufferSize(); 
     short[] tempBuffer = new short[bufferSize]; 
     if (!RecorderSingleton.instance.start()) { 
      return; 
     } 
     try { 
      Log.d(RoomieConstants.LOG_TAG, "Recorder Started"); 
      while (takenSamples < requiredSamples && !cancelled) { 
       bufferRead = RecorderSingleton.instance.read(tempBuffer); 
       if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) { 
        throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION"); 
       } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) { 
        throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE"); 
       } 
       takenSamples += bufferRead; 
       // do something with the samples ... 
       // ... 
       // ... 
      } 
     } finally { 
      // Close resources... 
      stop(); 
     } 
    } 

    public void stop() { 
     RecorderSingleton.instance.stop(); 
    } 

    public void cancel() { 
     cancelled = true; 
    } 
} 
+0

您在特定情況下給了哪個值requiredSamples? – Josh 2017-08-28 14:52:56