AudioRecord对象没有初始化

在下面的代码中,我的audioRecord对象没有初始化。 我试着把它移动到onCreate方法,并使其成为一个全球性的。 我logging了状态,并返回值1 ,这意味着可以使用。 debugging器说,正在对未初始化的对象调用startRecording 。 这也是说,它无法获得audio源。

为什么我会收到这些错误?

  package com.tecmark; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import android.app.Activity; import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import android.widget.TextView; public class recorder extends Activity { private Thread thread; private boolean isRecording; private AudioRecord recorder; private FileOutputStream os; private BufferedOutputStream bos; private DataOutputStream dos; private TextView text; private int audioSource = MediaRecorder.AudioSource.MIC; private int sampleRate = 22050; private int channel = AudioFormat.CHANNEL_CONFIGURATION_MONO; private int encoding = AudioFormat.ENCODING_PCM_16BIT; private int result = 0; private int bufferSize; private byte[] buffer; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.v("onCreate", "layout set, about to init audiorec obj"); text = (TextView)findViewById(R.id.TextView01); bufferSize = AudioRecord.getMinBufferSize(sampleRate,channel,encoding); buffer = new byte[bufferSize]; recorder = new AudioRecord(audioSource, sampleRate,channel,encoding, AudioRecord.getMinBufferSize(sampleRate, channel,encoding)); Log.i("recorder obj state",""+recorder.getRecordingState()); } public void onClickPlay(View v){ } public void record(){ Log.i("inside record method", "******"); File path = Environment.getExternalStorageDirectory(); Log.v("file path", ""+path.getAbsolutePath()); File file = new File(path, "test.wav"); if(file.exists()){ file.delete(); } path.mkdirs(); Log.v("file path", ""+file.getAbsolutePath()); try { os = new FileOutputStream(file); bos = new BufferedOutputStream(os); dos = new DataOutputStream(bos); } catch (Exception e1) { e1.printStackTrace(); } int bufferSize = AudioRecord.getMinBufferSize(sampleRate,channel,encoding); byte[] buffer = new byte[bufferSize]; recorder.startRecording(); isRecording = true; try{ while (isRecording){ result = recorder.read(buffer, 0, bufferSize); for(int a=0; a<result;a++){ dos.write(buffer[a]); if(!isRecording){ recorder.stop(); break; } } } dos.flush(); dos.close(); }catch(Exception e){ e.printStackTrace(); } }// end of record method public void onClickStop(View v){ Log.v("onClickStop", "stop clicked"); isRecording=false; } public void onClickReverse(View v){ Log.v("onClickReverse", "reverse clicked"); } public void onClickRecord(View v){ Log.v("onClickRecourd", "record clicked, thread gona start"); text.setText("recording"); thread = new Thread(new Runnable() { public void run() { isRecording = true; record(); } }); thread.start(); isRecording = false; } }//end of class 

logcat的

 01-30 15:23:16.724: ERROR/AudioRecord(12817): Could not get audio input for record source 1 01-30 15:23:16.729: ERROR/AudioRecord-JNI(12817): Error creating AudioRecord instance: initialization check failed. 01-30 15:23:16.729: ERROR/AudioRecord-Java(12817): [ android.media.AudioRecord ] Error code -20 when initializing native AudioRecord object. 01-30 15:23:16.729: INFO/recorder obj state(12817): 1 01-30 15:23:16.729: WARN/dalvikvm(12817): threadid=13: thread exiting with uncaught exception (group=0x4001b180) 01-30 15:23:16.729: ERROR/AndroidRuntime(12817): Uncaught handler: thread Thread-7 exiting due to uncaught exception 01-30 15:23:16.739: ERROR/AndroidRuntime(12817): java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord. 01-30 15:23:16.739: ERROR/AndroidRuntime(12817): at android.media.AudioRecord.startRecording(AudioRecord.java:495) 01-30 15:23:16.739: ERROR/AndroidRuntime(12817): at com.tecmark.recorder.record(recorder.java:114) 01-30 15:23:16.739: ERROR/AndroidRuntime(12817): at com.tecmark.recorder$1.run(recorder.java:175) 01-30 15:23:16.739: ERROR/AndroidRuntime(12817): at java.lang.Thread.run(Thread.java:1096) 

使用AudioRecord的技巧是每个设备可能有不同的初始化设置,所以你将不得不创build一个方法,循环所有可能的比特率,编码等组合。

 private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 }; public AudioRecord findAudioRecord() { for (int rate : mSampleRates) { for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) { for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { try { Log.d(C.TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig); int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { // check if we can instantiate and have a success AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize); if (recorder.getState() == AudioRecord.STATE_INITIALIZED) return recorder; } } catch (Exception e) { Log.e(C.TAG, rate + "Exception, keep trying.",e); } } } } return null; } AudioRecord recorder = findAudioRecord(); recorder.release(); 

我有同样的问题,它通过放置解决

 <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission> 

进入清单

根据javadocs,所有设备都保证支持这种格式(用于logging):

44100,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT。

切换到CHANNEL_OUT_MONO播放。

现在,用棒棒糖,你需要专门询问用户的每个权限。 确保授予权限。

初始化AudioRecord对象的问题可以通过使用audioRecord.release();audioRecord.release(); 在创build下一个对象之前…更多这里: Android AudioRecord – 不会初始化第二次

即使在完成上述所有步骤之后,我也遇到了同样的问题,对我而言,我的操作系统是棉花糖,我不得不要求权限

刚刚有同样的问题。 解决scheme是重新启动设备。 在播放代码时,我没有释放AudioRecord对象,这明显导致audio设备卡住。 要testingaudio设备是否工作,我从Google Play下载了Audalyzer。

如果您的手机系统是Android M或更高版本,则可能需要在Android M中应用loggingaudio权限。http: //developer.android.com/guide/topics/security/permissions.html

我注意到,当我正在运行的AVD的SD卡得到充分的AudioRecord构造函数返回null。 您是否尝试清除SDCard?

我认为这与线程不知道你已经暂停了主要活动并且在你停止logging器之后仍然试图logging有关。

我通过改变我的onResume()和onPause()方法来修改isRecording布尔值来解决它。

 public void onResume() { ... isRecording = true; } public void onPause() { ... isRecording = false; } 

然后在你的线程中,使用if语句来检查isRecording是否包含startRecording()stop()

 if(isRecording) recorder.startRecording(); ... if(isRecording) recorder.stop(); // which you've done 

我为@DustinB重写了任何使用C#使用Xamarin Android AudioRecord的人的回答。

 int[] sampleRates = new int[] { 44100, 22050, 11025, 8000 }; Encoding[] encodings = new Encoding[] { Encoding.Pcm8bit, Encoding.Pcm16bit }; ChannelIn[] channelConfigs = new ChannelIn[]{ ChannelIn.Mono, ChannelIn.Stereo }; //Not all of the formats are supported on each device foreach (int sampleRate in sampleRates) { foreach (Encoding encoding in encodings) { foreach (ChannelIn channelConfig in channelConfigs) { try { Console.WriteLine("Attempting rate " + sampleRate + "Hz, bits: " + encoding + ", channel: " + channelConfig); int bufferSize = AudioRecord.GetMinBufferSize(sampleRate, channelConfig, encoding); if (bufferSize > 0) { // check if we can instantiate and have a success AudioRecord recorder = new AudioRecord(AudioSource.Mic, sampleRate, channelConfig, encoding, bufferSize); if (recorder.State == State.Initialized) { mBufferSize = bufferSize; mSampleRate = sampleRate; mChannelConfig = channelConfig; mEncoding = encoding; recorder.Release(); recorder = null; return true; } } } catch (Exception ex) { Console.WriteLine(sampleRate + "Exception, keep trying." + ex.Message); } } } } 

在我的情况下,我不得不手动允许在Android 7的麦克风的权限,作为sean zhu评论。