Java – Android audiorecord does not initialize

I'm trying to implement an application that monitors microphone input (especially breathing) and provides data based on it I am using the Android class audiorecord. When trying to instantiate audiorecord, I get three errors

AudioRecord: AudioFlinger Could not create record track,status: -1
AudioRecord-JNI: Error creating AudioRecord instance: initialization check Failed with status -1.
android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.

I found this excellent topic: audiorecord object not initializing

I borrowed the code from the accepted answers and tried all sampling rates, audio formats and channel configurations to try to solve the problem, but it didn't help. I got the above errors of all settings I also added a pair of audiorecord in several places according to an answer in the thread Release() is called, but it makes no difference

This is my code:

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

public class SoundMeter {

private AudioRecord ar = null;
private int minSize;
private static int[] mSampleRates = new int[] { 8000,11025,22050,32000,44100 };

public boolean start() {
    ar = findAudioRecord();
    if(ar != null){
        ar.startRecording();
        return true;
    }
    else{
        Log.e("SoundMeter","ERROR,Could not create audio recorder");
        return false;
    }
}

public void stop() {
    if (ar != null) {
        ar.stop();
        ar.release();
    }
}

public double getAmplitude() {
    short[] buffer = new short[minSize];
    ar.read(buffer,minSize);
    int max = 0;
    for (short s : buffer)
    {
        if (Math.abs(s) > max)
        {
            max = Math.abs(s);
        }
    }
    return max;
}

public AudioRecord findAudioRecord() {
    for (int rate : mSampleRates) {
        for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT,AudioFormat.ENCODING_PCM_16BIT,AudioFormat.ENCODING_PCM_FLOAT }) {
            for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO,AudioFormat.CHANNEL_IN_STEREO }) {
                try {
                    Log.d("SoundMeter","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
                        Log.d("SoundMeter","Found a supported bufferSize,attempting to instantiate");
                        AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,rate,audioFormat,bufferSize);

                        if (recorder.getState() == AudioRecord.STATE_INITIALIZED){
                            minSize = bufferSize;
                            return recorder;
                        }
                        else
                            recorder.release();
                    }
                } catch (Exception e) {
                    Log.e("SoundMeter",rate + " Exception,keep trying.",e);
                }
            }
        }
    }
    return null;
}

}

I added it, too

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

According to one of the other answers in the thread mentioned above, mark it to my manifest file as a child of the manifest tag and a brother of the application tag I rebuilt the project after adding this tag

These are the solutions I found when searching for problems, but unfortunately they don't seem to do that for me I'm debugging my nexus 5 phone (not a simulator) These errors occur when calling the audiorecord constructor I've restarted my phone many times and tried to release the microphone, but it didn't help The project is based on Android 4.4. My mobile phone is currently running Android 6.0 one

Thank you very much for some other tips I can try. I may have missed something thank you!

Solution

I found the answer myself It is related to permissions

The problem is that I run API version 23 (Android 6.0.1) on my phone, which no longer only uses manifest files to handle permissions Starting with version 23, permissions will be granted at run time I added a method to ensure that permission is requested at run time. When I allow it once on the phone, it will be OK

private void requestRecordAudioPermission() {
    //check API version,do nothing if API version < 23!
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion > android.os.Build.VERSION_CODES.LOLLIPOP){

        if (ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUdio) != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.RECORD_AUdio)) {

                // Show an expanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation,try again to request the permission.

            } else {

                // No explanation needed,we can request the permission.

                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUdio},1);
            }
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,String permissions[],int[] grantResults) {
    switch (requestCode) {
        case 1: {
            // If request is cancelled,the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted,yay! Do the
                // contacts-related task you need to do.
                Log.d("Activity","Granted!");

            } else {

                // permission denied,boo! Disable the
                // functionality that depends on this permission.
                Log.d("Activity","Denied!");
                finish();
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

Then, before creating the audiorecord, call requestrecordaudiopermission() from the oncreate() method in the main activity

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>