Android AudioRecord 问题
Android AudioRecord troubles
private static final int SampleRate = 8000;
private static final int Channels = AudioFormat.CHANNEL_IN_MONO;
private static final int Encoding = AudioFormat.ENCODING_PCM_16BIT;
private void startRecording(){
int bufferSize = AudioRecord.getMinBufferSize(SampleRate, Channels, AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize > 0) {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SampleRate, Channels, Encoding, BufferElements2Rec*BytesPerElement);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable(){
public void run(){
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}
}
这适用于设备模拟器,我在那里有任何问题,但在真正的 phone 上不起作用。我收到此错误:
java.lang.IllegalStateException: startRecording() called on an unitialized AudioRecord.
我把我的清单:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
正如 AudioRecord 构造函数的 documentation 所说,
you should call getState() immediately after construction to confirm
that the object is usable.
可能的状态是:
STATE_INITIALIZED
STATE_UNINITIALIZED
在您的情况下,recorder 未正确初始化,因此在调用 startRecording() 时出现 IllegarArgumentException。
原因之一可能是您的 SampleRate,它是 8000。根据文档,44100Hz 是唯一可以保证在所有设备上工作的速率,所以请先尝试这个速率(另外,文档没有明确说明声明 8000HZ 为有效频率)。
然后在您的代码中,将 SampleRate 更改为 44100 并检查对象状态,例如:
private static final int SampleRate = 44100;
及以后:
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SampleRate, Channels, Encoding, BufferElements2Rec*BytesPerElement);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED) {
recorder.startRecording();
isRecording = true;
//rest of the code
}
else {
//not initialized properly
}
在某些情况下(我在 Android 6 而不是 5 上遇到了同样的问题)当您第一次启动应用程序时您需要转到设置>应用程序>您的应用程序>权限并让应用程序使用麦克风,我打开后,错误消失了。
更好的做法是像这样在启动时检查 sdk 编号,并在您的应用程序内部请求用户许可以防止错误(将 PUT_YOUR_PERMISSION_HERE 替换为您需要的许可)-
//check for permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.PUT_YOUR_PERMISSION_HERE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.PUT_YOUR_PERMISSION_HERE},
MY_PERMISSIONS_REQUEST_PUT_YOUR_PERMISSION_HERE);
// MY_PERMISSIONS_REQUEST_PUT_YOUR_PERMISSION_HERE is an
// app-defined int constant
return;
}
private static final int SampleRate = 8000;
private static final int Channels = AudioFormat.CHANNEL_IN_MONO;
private static final int Encoding = AudioFormat.ENCODING_PCM_16BIT;
private void startRecording(){
int bufferSize = AudioRecord.getMinBufferSize(SampleRate, Channels, AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize > 0) {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SampleRate, Channels, Encoding, BufferElements2Rec*BytesPerElement);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable(){
public void run(){
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}
}
这适用于设备模拟器,我在那里有任何问题,但在真正的 phone 上不起作用。我收到此错误:
java.lang.IllegalStateException: startRecording() called on an unitialized AudioRecord.
我把我的清单:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
正如 AudioRecord 构造函数的 documentation 所说,
you should call getState() immediately after construction to confirm that the object is usable.
可能的状态是:
STATE_INITIALIZED
STATE_UNINITIALIZED
在您的情况下,recorder 未正确初始化,因此在调用 startRecording() 时出现 IllegarArgumentException。
原因之一可能是您的 SampleRate,它是 8000。根据文档,44100Hz 是唯一可以保证在所有设备上工作的速率,所以请先尝试这个速率(另外,文档没有明确说明声明 8000HZ 为有效频率)。
然后在您的代码中,将 SampleRate 更改为 44100 并检查对象状态,例如:
private static final int SampleRate = 44100;
及以后:
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SampleRate, Channels, Encoding, BufferElements2Rec*BytesPerElement);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED) {
recorder.startRecording();
isRecording = true;
//rest of the code
}
else {
//not initialized properly
}
在某些情况下(我在 Android 6 而不是 5 上遇到了同样的问题)当您第一次启动应用程序时您需要转到设置>应用程序>您的应用程序>权限并让应用程序使用麦克风,我打开后,错误消失了。
更好的做法是像这样在启动时检查 sdk 编号,并在您的应用程序内部请求用户许可以防止错误(将 PUT_YOUR_PERMISSION_HERE 替换为您需要的许可)-
//check for permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.PUT_YOUR_PERMISSION_HERE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.PUT_YOUR_PERMISSION_HERE},
MY_PERMISSIONS_REQUEST_PUT_YOUR_PERMISSION_HERE);
// MY_PERMISSIONS_REQUEST_PUT_YOUR_PERMISSION_HERE is an
// app-defined int constant
return;
}