AudioRecord对象未初始化

时间:2011-01-30 15:40:14

标签: android android-audiorecord

在下面的代码中,我的audioRecord对象未初始化。我尝试将其移至onCreate方法并使其成为全局方法。我已记录状态,并返回值1,这意味着可以使用。调试器表示正在对未初始化的对象调用startRecording。它也说无法获得音频源。

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

    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)

12 个答案:

答案 0 :(得分:92)

使用AudioRecord的技巧是每个设备可能有不同的初始化设置,因此您必须创建一个循环所有可能的比特率,编码等组合的方法。

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();

答案 1 :(得分:91)

我有同样的问题,它是通过放

来解决的
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

进入清单。

自Lollipop以来,您还需要具体询问用户每个权限。因为他们可能已经撤销了他们。确保授予权限。

答案 2 :(得分:9)

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

44100,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT。

更改为CHANNEL_OUT_MONO进行播放。

答案 3 :(得分:4)

现在,使用棒棒糖,您需要专门询问用户是否有权限。确保授予权限。

答案 4 :(得分:4)

即使在完成上述所有步骤后,我也遇到了同样的问题,对我来说有用的是我的操作系统是棉花糖,我不得不要求获得许可

答案 5 :(得分:3)

初始化少数AudioRecord对象的问题可以通过在创建下一个对象之前使用audioRecord.release();来修复... 更多信息:Android AudioRecord - Won't Initialize 2nd time

答案 6 :(得分:2)

刚遇到同样的问题。 解决方案是重启设备。在播放代码时,我没有发布AudioRecord对象,这显然导致音频设备卡住了。 为了测试音频设备是否有效,我从Google Play下载了Audalyzer。

答案 7 :(得分:2)

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

答案 8 :(得分:2)

在我的情况下,我必须手动允许android 7中的麦克风权限,正如肖恩珠所评论的那样。

答案 9 :(得分:1)

我注意到当我运行的avd上的SDCard变满时,AudioRecord构造函数返回null。您是否尝试过清除SD卡?

答案 10 :(得分:0)

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

我通过更改onResume()和onPause()方法来解决它,以修改isRecording boolean。

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

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

然后在你的主题中,使用if-statements检查isRecording:{/ 1>} startRecording()stop()

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

答案 11 :(得分:0)

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

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);
            }
        }
    }
}