1. 得到 外圍藍(lán)牙設(shè)備
想與 外圍的藍(lán)牙設(shè)備相連接,首先得要獲得這個(gè)藍(lán)牙設(shè)備。
官方例子:
bleDevice = SampleApplication.getRxBleClient(this).getBleDevice(macAddress);
具體的實(shí)現(xiàn):
由 RxClient 中的 RxBledeviceProvider 提供具體的 獲取藍(lán)牙設(shè)備的 實(shí)現(xiàn):
具體代碼:
- 獲得 BluetoothDevice
rxBleAdapterWrapper.getRemoteDevice(macAddress);
rxBleAdapterWrapper是 BluetoothAdapter 的包裝,以上代碼本質(zhì)上是:
public BluetoothDevice getRemoteDevice(String macAddress) {
return bluetoothAdapter.getRemoteDevice(macAddress);
}
- 包裝 BluetoothDevice---》RxBleDeviceImpl
包裝了 BluetoothDevice,使其變的更強(qiáng)!
如上,可以通過(guò)包裝后的藍(lán)牙設(shè)備做如下事情:
- 建立連接
- 觀察連接狀態(tài)
- 獲得當(dāng)前的連接狀態(tài)
- getName,getMacAddress
2. 觀察 外圍藍(lán)牙設(shè)備的連接狀態(tài)
有了 外圍的藍(lán)牙設(shè)備,我就可以去觀察他了。
官方例子:
// How to listen for connection state changes
bleDevice.observeConnectionStateChanges()
.compose(bindUntilEvent(DESTROY))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onConnectionStateChange);
深入 RxBleDeviceImpl中的 代碼:
connectionStateSubject:
private final BehaviorSubject<RxBleConnection.RxBleConnectionState> connectionStateSubject = BehaviorSubject.create(DISCONNECTED);
它是個(gè)平臺(tái):
生產(chǎn)者 生產(chǎn)完?yáng)|西,消費(fèi)者過(guò)來(lái)買東西。他們都是通過(guò) subject 這個(gè)平臺(tái)。
subject 有如下幾種實(shí)現(xiàn):
著重看一下:BehaviorSubject
藍(lán)牙的 連接狀態(tài) 事件的生產(chǎn)和發(fā)布 是通過(guò) connectionStateSubject 這個(gè)平臺(tái)的。
下面看一下代碼實(shí)現(xiàn):
- 生產(chǎn) 連接中(CONNECTING) 這個(gè)事件。
- 生產(chǎn) 連接上了(CONNECTED) 這個(gè)事件。
- 生產(chǎn) 斷開(kāi)連接(DISCONNECTED) 這個(gè)事件。
說(shuō)著說(shuō)著就到了與外圍藍(lán)牙設(shè)備的 建立連接~
連接
有了藍(lán)牙設(shè)備,就可以與這個(gè)設(shè)備建立連接了。
RxBleDeviceImpl 中 的connector專門負(fù)責(zé)連接:
核心的連接與斷開(kāi)連接,這些代碼被封裝到:
由RxBleConnectionConnectorOperationsProvider來(lái)管理。
其中建立連接:
繼續(xù):
1. 初步檢查
若藍(lán)牙未啟用,生產(chǎn)一個(gè) 異常對(duì)象:BleDisconnectedException
2. 連接過(guò)程中,考慮各種情況。
考慮情況:未連接上的時(shí)候
(在建立藍(lán)牙連接的時(shí)候,若藍(lán)牙不可用了)
考慮情況:已經(jīng)連接上的時(shí)候
(這時(shí)候,藍(lán)牙斷開(kāi)連接了,也要通知觀察者?。?/p>
考慮情況:用戶不想訂閱這個(gè)連接了。
(針對(duì)這個(gè)連接,用戶不想玩了:斷開(kāi)連接)
下面深入:
將 藍(lán)牙連接這個(gè)操作 進(jìn)行入隊(duì):
RxBleRadioOperationConnect 的具體執(zhí)行什么操作?
@Override
protected void protectedRun() {
final Runnable onConnectionEstablishedRunnable = autoConnect ? emptyRunnable : releaseRadioRunnable;
final Runnable onConnectCalledRunnable = autoConnect ? releaseRadioRunnable : emptyRunnable;
getConnectedBluetoothGatt()
.doOnCompleted(onConnectionEstablishedRunnable::run)
.subscribe(getSubscriber());
onConnectCalledRunnable.run();
}
該流程執(zhí)行完畢后,我們建立了 一個(gè)訂閱關(guān)系:
生產(chǎn)者:建立藍(lán)牙連接,連接成功后,返回此鏈接的 gatt。
消費(fèi)者:再將該 gatt 發(fā)射出去。
再細(xì)看下 getConnectedBluetoothGatt()
當(dāng)你連接成功了會(huì)得到一個(gè) gatt。
核心:建立連接
connectionCompat.connectGatt(bluetoothDevice, autoConnect, rxBleGattCallback.getBluetoothGattCallback())
連接的建立 被封裝到 BleConnectionCompat 類中:
那我們看一下 他們的 connectGatt 方法:
public BluetoothGatt connectGatt(BluetoothDevice remoteDevice, boolean autoConnect, BluetoothGattCallback bluetoothGattCallback) {
if (remoteDevice == null) {
return null;
}
if (!autoConnect) {
return connectGattCompat(bluetoothGattCallback, remoteDevice, false);
}
/**
* Some implementations of Bluetooth Stack have a race condition where autoConnect flag
* is not properly set before calling connectGatt. That's the reason for using reflection
* to set the flag manually.
*/
try {
RxBleLog.v("Trying to connectGatt using reflection.");
Object iBluetoothGatt = getIBluetoothGatt(getIBluetoothManager());
if (iBluetoothGatt == null) {
RxBleLog.w("Couldn't get iBluetoothGatt object");
return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
}
BluetoothGatt bluetoothGatt = createBluetoothGatt(iBluetoothGatt, remoteDevice);
if (bluetoothGatt == null) {
RxBleLog.w("Couldn't create BluetoothGatt object");
return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
}
boolean connectedSuccessfully = connectUsingReflection(bluetoothGatt, bluetoothGattCallback, true);
if (!connectedSuccessfully) {
RxBleLog.w("Connection using reflection failed, closing gatt");
bluetoothGatt.close();
}
return bluetoothGatt;
} catch (NoSuchMethodException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException
| InstantiationException
| NoSuchFieldException exception) {
RxBleLog.w(exception, "Error during reflection");
return connectGattCompat(bluetoothGattCallback, remoteDevice, true);
}
}
調(diào)用系統(tǒng)中的 connect 方法進(jìn)行連接。(這個(gè)有空再詳談吧)