我正在尝试录制音频并从蓝牙耳机中分析它,为此我正在使用对象:android.media.AudioRecord, 我的问题是,对于某些设备与他们的Android版本相结合,我从手机麦克风而不是蓝牙耳机获得录音。
在某些情况下我可以解决这个问题 - 如果我创建这个对象时,我会向它的构造函数传递一个不同的音频源类型。
例如,我看到为了从带有Android 5.0的Nexus 6中的蓝牙耳机录制,我需要像这样构建AudioRecord:
audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 4410);
但是,如果我尝试将相同的代码用于名为" THL T6S"也有Android 5.0,录音来自手机麦克风。 如果我希望它来自这款手机中的耳机,我需要写一下:
audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 4410);
但是当然我不能在我的代码中涵盖所有可能的手机类型和操作系统版本的组合。
我该如何解决?
附上所有相关代码。
感谢。
这是我的蓝牙Sco课程
public class BluetoothSco {
private static BluetoothSco instance = null;
// Context
private Context mContext;
private Service service;
// Logcat TAG
private final String TAG = BluetoothSco.class.getSimpleName();
// AudioMode
public static final int MODE_IN_CALL = 1;
public static final int MODE_IN_COMMUNICATION = 2;
public static final int MODE_NORMAL = 3;
// BluetoothAdapter
private final BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
protected BluetoothSco() { }
public static BluetoothSco getInstance(Context context) {
if(instance == null) {
instance = new BluetoothSco();
instance.mContext = context;
instance.service = (Service) context;
}
return instance;
}
// Start Sco
public synchronized void startSco(final int audioMode) {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (btAdapter == null) {
Log.i(TAG, "This device does not support Bluetooth");
return;
}
else if (!btAdapter.isEnabled()) {
Log.i(TAG, "Bluetooth headset is disconnected. Would you like to monitor manually?");
return;
}
AudioManager audioManager = (AudioManager) service.getSystemService(Context.AUDIO_SERVICE);
if (!audioManager.isBluetoothScoAvailableOffCall()) {
Log.i(TAG, "Off-call Bluetooth audio not supported on this device.");
return;
}
if (audioMode == BluetoothSco.MODE_IN_CALL) {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
else if (audioMode == BluetoothSco.MODE_IN_COMMUNICATION) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
}
else {
audioManager.setMode(AudioManager.MODE_NORMAL);
}
}
else if (audioMode == BluetoothSco.MODE_NORMAL) {
audioManager.setMode(AudioManager.MODE_NORMAL);
}
//Roni - temp code/////////
//audioManager.setMode(AudioManager.MODE_IN_CALL);
////////////////////
audioManager.setBluetoothScoOn(true);
try{
audioManager.startBluetoothSco();
Log.v(TAG, "Bluetooth SCO Started");
}
catch(NullPointerException ex){
Log.i(TAG, "Bluetooth headset is disconnected. Would you like to monitor manually?");
}
}
};
runnable.run();
}
public synchronized void stopSco() {
Runnable runnable = new Runnable() {
@Override
public void run() {
AudioManager audioManager = (AudioManager) service.getSystemService(Context.AUDIO_SERVICE);
try {
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
audioManager.setMode(AudioManager.MODE_NORMAL);
Log.v(TAG, "Bluetooth SCO Stopped");
}
catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
};
runnable.run();
}
}
以下是我如何初始化AudioRecord和Bluetooth Sco
audioRecord = new AudioRecord(Options.audioSource, Options.sampleRate, Options.channelConfig,
Options.audioEncoding, Options.numBuffers * Math.max(minBufSize, bufferSizeBytes));
mBluetoothSco.startSco(BluetoothSco.MODE_NORMAL);
audioRecord.startRecording();