Hel*_*ena 7 java multithreading android audiorecord
我正在尝试实现一个监听麦克风输入(特别是呼吸)的应用程序,并根据它提供数据.我正在使用Android类AudioRecord,在尝试实例化AudioRecord时,我得到了三个错误.
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.
Run Code Online (Sandbox Code Playgroud)
我发现这个优秀的线程:AudioRecord对象没有初始化
我从已接受的答案中借用了代码,尝试所有采样率,音频格式和通道配置以尝试解决问题,但它没有帮助,我得到了所有设置的上述错误.我还根据线程中的一个答案在几个地方添加了对AudioRecord.release()的调用,但它没有任何区别.
这是我的代码:
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, 0, 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, channelConfig, 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;
}
Run Code Online (Sandbox Code Playgroud)
}
我也加了
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
Run Code Online (Sandbox Code Playgroud)
根据上面提到的线程中的其他答案之一,标记到我的清单文件,作为清单标记的子项和应用程序标记的兄弟.我在添加此标记后重建了该项目.
这些是我在搜索问题时找到的解决方案,但不幸的是,它们似乎并没有为我做到这一点.我正在调试我的Nexus 5手机(不是模拟器).调用AudioRecord的构造函数时会出现这些错误.我已经多次重启我的手机试图释放麦克风,但无济于事.该项目基于Android 4.4,我的手机目前运行的是Android 6.0.1.
非常感谢我可以尝试的其他一些提示,我可能错过了什么.谢谢!
Hel*_*ena 15
我自己找到了答案.它与权限有关.
问题是我在手机上运行API版本23(Android 6.0.1),它不再仅使用清单文件来处理权限.从版本23开始,将在运行时授予权限.我添加了一个确保在运行时请求权限的方法,当我在手机上允许它一次时,它就可以了.
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在创建AudioRecord之前,从主活动中的onCreate()方法调用requestRecordAudioPermission().
归档时间: |
|
查看次数: |
7942 次 |
最近记录: |