蓝牙设备在连接前,会先检查设备是否已经配对过,如果没有则先配对,配对完成后,再开始连接。
onPreferenceTreeClick
蓝牙连接开始于设备列表 DeviceListPreferenceFragment的onPreferenceTreeClick方法。
DeviceListPreferenceFragment是蓝牙设备列表,点击其中一个蓝牙设备,开始蓝牙的连接过程。
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
if (KEY_BT_SCAN.equals(preference.getKey())) {
mLocalAdapter.startScanning(true);
return true;
}
if (preference instanceof BluetoothDevicePreference) {
BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
CachedBluetoothDevice device = btPreference.getCachedDevice();
mSelectedDevice = device.getDevice();
//配对连接
onDevicePreferenceClick(btPreference);
return true;
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
调用onDevicePreferenceClick方法,接着调用BluetoothDevicePreference的onClicked方法,开始连接,以及连接前的状态检测。
BluetoothDevicePreference.onClicked
void onClicked() {
//选中设备的绑定状态
int bondState = mCachedDevice.getBondState();
//已连接,询问是否连接
if (mCachedDevice.isConnected()) {
askDisconnect();
} else if (bondState == BluetoothDevice.BOND_BONDED) {
mCachedDevice.connect(true);
} else if (bondState == BluetoothDevice.BOND_NONE) {
//配对
pair();
}
}
获取mCachedDevice的绑定状态,
- 已经连接,是否断开
- 未连接,已经绑定,开始连接
- 未连接,未绑定,开始配对
开始蓝牙配对流程
CachedBluetoothDevice.startPairing
pair方法会调用CachedBluetoothDevice.startPairing,启动配对
public boolean startPairing() {
// Pairing is unreliable while scanning, so cancel discovery
//配对时,取消搜索
if (mLocalAdapter.isDiscovering()) {
mLocalAdapter.cancelDiscovery();
}
//开始配对配对
if (!mDevice.createBond()) {
return false;
}
//标识位,配对完成后,自动连接
mConnectAfterPairing = true; // auto-connect after pairing
return true;
}
createBond调用BluetoothDevice.createBond方法,BluetoothDevice.createBond接着调用IBluetooth.createBond方法,下面会调用蓝牙远程服务。
和蓝牙扫描一样,实现IBluetooth接口的类是AdapterServiceBinder,
AdapterServiceBinder extends IBluetooth.Stub
AdapterServiceBinder实现IBluetooth.Stub接口,并且是AdapterService的私有内部类,AdapterServiceBinder接受事件,都会转交AdapterService处理,所以IBluetooth.createBond方法会调用AdapterService.createBond方法。
AdapterService.createBond
boolean createBond(BluetoothDevice device, int transport) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
//属性检查
if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
return false;
}
// Pairing is unreliable while scanning, so cancel discovery
// Note, remove this when native stack improves
//再次取消扫描
cancelDiscoveryNative();
//将配对任务转交状态机处理
Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
msg.obj = device;
msg.arg1 = transport;
mBondStateMachine.sendMessage(msg);
return true;
}
createBond方法会检查一下远程设备属性信息,再次取消蓝牙扫描任务,将配对任务转交mBondStateMachine,由状态机处理该信息。
BondStateMachine状态机的初始状态是StableState,所以BondStateMachine.CREATE_BOND由StableState处理,StableState在processMessage中调用BondStateMachine.createBond方法
BondStateMachine.createBond
private boolean createBond(BluetoothDevice dev, int transport, boolean transition) {
if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
infoLog("Bond address is:" + dev);
byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
//调用createBondNative JNI方法
if (!mAdapterService.createBondNative(addr, transport)) {
//发送正在绑定的广播
sendIntent(dev, BluetoothDevice.BOND_NONE,
BluetoothDevice.UNBOND_REASON_REMOVED);
return false;
} else if (transition) {
transitionTo(mPendingCommandState);
}
return true;
}
return false;
}
JNI 方法
createBondNative方法实现com_android_bluetooth_btservice_AdapterService.cpp中