在做即时通信软件时,经常碰到一些音频的相关的问题。
1.蓝牙和有线耳机连接后,音频不能切到耳机中。此类问题主要是AudioManager的setSpeakerphoneOn函数要设置为false才行,而外扩喇叭播放音频数据就要设置为true。以下提供几个常用的代码:
(1) 判断蓝牙耳机是否接通: BluetoothProfile.STATE_DISCONNECTED ==BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(BluetoothProfile.HEADSET)表示没有连接蓝牙耳塞; BluetoothProfile.STATE_CONNECTED==BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(BluetoothProfile.HEADSET)表示已连接蓝牙耳塞;
(2) AudioManager的isWiredHeadsetOn() == true表示有线耳机已插入,等于false表示有线耳机没有插入。
(3)监听耳机的插拔情况是通过监听广播的方式进行的,先注册广播:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);-------监听有线耳塞是否插入
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);监听蓝牙耳塞的连接状态的改变
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); 表示蓝牙耳塞连接上
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);表示蓝牙耳塞没有连接上
广播处理:
public class HeadsetDetectReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
if (intent.hasExtra("state")) {
handleHeadsetDetect(intent);
}
}else if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
handleBluetooth(HEADSETON);
}else if(BluetoothDevice.ACTION_ACL_DISCONNECTED == action){
handleBluetooth(HEADSETOFF);
}else if(BluetoothAdapter.ACTION_STATE_CHANGED == action){
int bluState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
handleBluetooth(bluState);
}
}
}
其中 intent.getIntExtra("state", 0)等于1时表示有线耳塞插入,等于0时表示耳塞拔出了;
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)等于BluetoothAdapter.STATE_TURNING_ON或者 BluetoothAdapter.STATE_ON时表示蓝牙耳塞连接上了。
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)等于BluetoothAdapter.STATE_TURNING_OFF或者BluetoothAdapter.STATE_OFF时表示蓝牙耳塞断开了。
(4) 注意蓝牙耳机有两种模式:A2DP和SCO,A2DP是高质量音乐播放(俗称:只进不出),SCO是语音通话(俗称:有进有出)。
2 AudioRecorder录制问题:
(1) 当AudioRecorder.read(this.pcmBuffer, 0,this.pcmBuffer.length);如果使用蓝牙耳塞(有线耳机未测试过)连接会阻塞住,既不往下执行代码,该问题造成的原因就是在录制时长时间不对AudioRecorder进行read造成的数据阻塞,长时间不读后,又开始调用AudioRecorder.read函数时将阻塞在该句代码。