记录一下个人本地蓝牙调试指令,留点足迹以备后面查询
打开和关闭蓝牙BT
打开bt
1、adb shell svc bluetooth enable
2、echo 1>/sys/class/rfkill/rfkill0/state
3、svc bluetooth enable
关闭bt
adb shell svc bluetooth disable
echo 0>/sys/class/rfkill/rfkill0/state
svc bluetooth disable
获取蓝牙状态:
1、adb shell settings get global bluetooth_on 1\0
2、cat /sys/class/rfkill/rfkill0/state 1\0
3、adb shell dumpsys bluetooth_manager (dumpsys -l )
demo:
Bluetooth Status
enabled: true
state: ON
address: 22:22:CE:61:D6:21
name: BTdevice-0104
time since enabled: 01:16:24.119
setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE);/*可连接*/
setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); /*可连接和可被发现*/
adb 指令设置蓝牙mode
允许蓝牙被发现:
adb shell am start -a android.bluetooth.adapter.action.REQUEST_DISCOVERABLE
蓝牙地址获取:
adb shell settings get secure bluetooth_address
蓝牙名称获取:
adb shell settings get secure bluetooth_name
获取已配对的设备:
if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
mBluetoothAdapter.getBondedDevices();
获取已连接设备:
packages/apps/Bluetooth/src/com/android/bluetooth/pan/PanService.java
public List<BluetoothDevice> getConnectedDevices() {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
List<BluetoothDevice> devices =
getDevicesMatchingConnectionStates(new int[]{BluetoothProfile.STATE_CONNECTED});
return devices;
}
List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
List<BluetoothDevice> panDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device : mPanDevices.keySet()) {
int panDeviceState = getConnectionState(device);
for (int state : states) {
if (state == panDeviceState) {
panDevices.add(device);
break;
}
}
}
return panDevices;
}
蓝牙配置保存为位置
/data/misc/bluedroid
dumpsys 蓝牙信息:
adb shell dumpsys bluetooth_manager
蓝牙耳机状态切换:
AudioManager 提供的下列方法可以用来查询当前Audio输出的状态:
isBluetoothA2dpOn():检查A2DPAudio音频输出是否通过蓝牙耳机;
isSpeakerphoneOn():检查扬声器是否打开;
isWiredHeadsetOn():检查线控耳机是否连着;注意这个方法只是用来判断耳机是否是插入状态,并不能用它的结果来判定当前的Audio是通过耳机输出的,这还依赖于其他条件
setSpeakerphoneOn(boolean on):直接选择外放扬声器发声;
setBluetoothScoOn(boolean on):要求使用蓝牙SCO耳机进行通讯;
A2DP:是一种单向的高品质音频数据传输链路,通常用于播放立体声音乐;
SCO: 则是一种双向的音频数据的传输链路,该链路只支持8K及16K单声道的音频数据,只能用于普通语音的传输,若用于播放音乐那就只能呵呵了。
两者的主要区别是:A2DP只能播放,默认是打开的,而SCO既能录音也能播放,默认是关闭的。 如果要录音肯定要打开sco啦,因此调用上面的setBluetoothScoOn(boolean on)就可以通过蓝牙耳机录音、播放音频了,录完、播放完记得要关闭。
AudioManager.setMode()方法来管理播放模式。在setMode()方法中有以下几种对应不同的播放模式:
MODE_NORMAL : 普通模式,既不是铃声模式也不是通话模式
MODE_RINGTONE : 铃声模式
MODE_IN_CALL : 通话模式
MODE_IN_COMMUNICATION : 通信模式,包括音/视频,VoIP通话.(3.0加入的,与通话模式类似)
/**
* 切换到外放
*/
public void changeToSpeaker(){
//注意此处,蓝牙未断开时使用MODE_IN_COMMUNICATION而不是MODE_NORMAL
mAudioManager.setMode(bluetoothIsConnected ? AudioManager.MODE_IN_COMMUNICATION : AudioManager.MODE_NORMAL);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(true);
}
/**
* 切换到蓝牙
*/
public void changeToHeadset(){
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
mAudioManager.setSpeakerphoneOn(false);
}
/**
* 切换到耳机模式
*/
public void changeToHeadset(){
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(false);
}
/**
* 切换到听筒
*/
public void changeToReceiver(){
audioManager.setSpeakerphoneOn(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
}
蓝牙音频切换 key log:
02-21 05:17:19.079 825 825 I Telecom : WiredHeadsetManager: ACTION_HEADSET_PLUG event, plugged in: true, : WHC.oADA@AEg
02-21 05:17:19.127 509 559 D audio_hw_primary: adev_set_parameters: enter: BT_SCO=off
02-21 05:17:19.147 825 2812 I Telecom : CallAudioRouteStateMachine: Message received: SWITCH_HEADSET=1003, arg1=0: WHC.oADA->CARSM.pM_CONNECT_WIRED_HEADSET->CARSM.pM_SWITCH_HEADSET@AEg
02-21 05:17:19.148 825 2812 I Telecom : QuiescentEarpieceRoute: Processing message SWITCH_HEADSET: WHC.oADA->CARSM.pM_CONNECT_WIRED_HEADSET->CARSM.pM_SWITCH_HEADSET@AEg
02-21 05:17:19.151 825 2812 I Telecom : Logging.Events: Non-call EVENT: AUDIO_ROUTE, Entering state QuiescentHeadsetRoute: WHC.oADA->CARSM.pM_CONNECT_WIRED_HEADSET->CARSM.pM_SWITCH_HEADSET@AEg
02-21 05:17:19.292 509 3249 I msm8916_platform: xxx-audio: check devices: { headphones } -> { headphones-pmln8191 }
02-21 05:17:19.292 509 3249 D audio_hw_primary: select_devices: out_snd_device(10: headphones-pmln8191) in_snd_device(0: )
heaset->speaker-> bt
02-21 05:20:53.339 2338 2338 V MediaRouter: Audio routes updated: AudioRoutesInfo{ type=HEADSET }, a2dp=false
02-21 05:20:53.380 2338 2338 V MediaRouter: Audio routes updated: AudioRoutesInfo{ type=SPEAKER }, a2dp=false
02-21 05:20:53.577 825 825 I Telecom : WiredHeadsetManager: ACTION_HEADSET_PLUG event, plugged in: false, : WHC.oADR@AJo
02-21 05:20:53.577 825 2812 I Telecom : QuiescentHeadsetRoute: Processing message DISCONNECT_WIRED_HEADSET: WHC.oADR->CARSM.pM_DISCONNECT_WIRED_HEADSET@AJo
02-21 05:20:53.577 6786 6922 D HeadsetStateMachine: moveTempStackToStateStack: X mStateStackTop=0,startingIndex=0,Top=Connected
02-21 05:20:53.577 825 2812 I Telecom : Logging.Events: Non-call EVENT: AUDIO_ROUTE, Wired headset disconnected: WHC.oADR->CARSM.pM_DISCONNECT_WIRED_HEADSET@AJo
02-21 05:20:53.578 6786 6922 D HeadsetStateMachine: Connected: currentDevice=4C:CC:34:AC:B1:8B, msg=audio state changed: 4C:CC:34:AC:B1:8B: AudioDisconnecting -> Connected
02-21 05:20:53.578 6786 6922 D HeadsetStateMachine: Connected: currentDevice=4C:CC:34:AC:B1:8B, msg=broadcastAudioState: 4C:CC:34:AC:B1:8B: 12->10
02-21 05:20:53.578 6786 6922 W HeadsetService: onAudioStateChangedFromStateMachine: 12->10
02-21 05:20:53.593 6786 6922 D HeadsetA2dpSync: releaseA2DP mA2dpSuspendTriggered 0 by device 4C:CC:34:AC:B1:8B
02-21 05:20:53.596 2868 2868 I [DEBUG][com.xxx.yyy.launcher][yyyAudioManager]: onReceive: ACTION_AUDIO_STATE_CHANGED. audioState: 10
02-21 05:20:53.597 2868 2868 I [DEBUG][com.xxx.yyy.launcher][VolumeKeyHelper]: onReceive: ACTION_AUDIO_STATE_CHANGED. BTState: 10
...
02-21 05:20:53.814 509 509 D hardware_info: hw_info_append_hw_type : device_name = speaker
02-21 05:20:53.814 509 509 D audio_hw_primary: disable_snd_device: snd_device(2: speaker)
02-21 05:20:53.828 825 2235 W system_server: Long monitor contention with owner Binder:825_5 (2471) at void com.android.server.audio.AudioDeviceBroker.setBluetoothScoOn(boolean, java.lang.String)(AudioDeviceBroker.java:352) waiters=1 in boolean com.android.server.audio.AudioDeviceBroker.isAvrcpAbsoluteVolumeSupported() for 236ms
02-21 05:20:53.832 2868 8386 I [DEBUG][com.xxx.yyy.launcher][yyyAudioManager]: ACTION_HEADSET_PLUG switchAudioPath2
02-21 05:20:53.832 2868 8386 I [DEBUG][com.xxx.yyy.launcher][yyyAudioManager]: switchAudioPath: To BT