Hej,我目前正试图让AudioRecord工作。因为我需要一个更大的项目。但它似乎搞得很多。 我一直在尝试很多东西,所以当我追踪这个bug时我回到了基础。 我使用的是三星Galaxy S作为我的调试设备。
我的问题是,第一次重新启动设备后,我可以初始化我创建的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 :(得分:10)
我能够重现你的问题(在三星手机上)。我添加了一个释放记录的onDestroy()方法:
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("OnDestroy");
audRec.release();
}
添加此项后,每次启动活动时,audioRecord似乎都会正确初始化。
答案 1 :(得分: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;
}
}
答案 2 :(得分:1)
回答我自己的问题,我发现它可以使用AudioRecord的唯一方法是永远不要把它作为一个全局变量,不知道为什么,但它似乎不会让你正确释放实例的资源如果你这样做。
答案 3 :(得分:0)
您应该尝试调用audRec.stop()来释放资源。
答案 4 :(得分:0)
我的AudioRecord未初始化,因为它是静态的