Android 蓝牙连接状态
Context
最近做了三个涉及蓝牙的小应用,都有Android版本。说实话,写了一年多Android(完完整整的写)。我对Android的蓝牙链接状态还是存在一些不明确的地方。
毕竟最早接触的是iOS的蓝牙开发,接触新领域的时候总是会根据以前的认知来加以理解。
iOS
iOS上面对蓝牙外设的连接状态是通过BluetoothCentralManager来告知的。
@protocol CBCentralManagerDelegate <NSObject>
//外设链接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;
//外设连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error;
//外设已断开连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error;
所以蓝牙是否连接成功是通过中心来通知的,但是在Android上,连接状态是由外设来通知的
Android
public final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
}
}
其中status代表了GATT操作的成功与失败,newState代表了GATT的新状态
status有GATT_SUCCESS,GATT_FAIL
newState有STATE_CONNECTED,STATE_CONNECTING,STATE_DISCONNECTED,STATE_DISCONNECTING
所以这个回调函数可以出现8种状态。
State
那么,对比上面iOS的三个协议,列一张对比表
状态 | iOS | Android |
---|---|---|
已连接 | didConnectPeripheral | GATT_SUCCESS+STATE_CONNECTED |
已断开 | didDisconnectPeripheral | GATT_SUCCESS+STATE_DISCONNECTED,GATT_FAIL+STATE_DISCONNECTED |
连接失败 | didFailToConnectPeripheral | GATT_FAIL+STATE_CONNECTED |
可以看到已断开这里,android有两种可能性,第一种是系统底层发现连接断开了GATT_FAIL
+STATE_DISCONNECTED,另外一种是用户控制断开GATT_SUCCESS
+STATE_DISCONNECTED。
这并不是说明iOS的接口设计的不够周到,而只是iOS把断开的原因放在了error里面而已。
Disconnect
在iOS里断开外设的连接实在是简单。只要让centralManager cancel Connection就可以了。但是在android中,会发现有两个方法~disconnect(),close()
感觉好像两个方法都是对的样子,但实际上他们是有区别的。
BLE通信从底层来说,是在每个connection
中传递数据的。所以disconnect是指停止connection通信,但是并没有断开连接。当gatt disconnect了之后,再使用close()便可以真正的断开连接。
假设直接使用close()会怎样呢?
其实不会怎样,蓝牙照样断开了,只不过不会在BluetoothGattCallback中通知。这或许对于开发者来说,会比较麻烦。因为像我就是在BluetoothGattCallback中来定义外设的连接状态,并使用event来通知相关的组件和界面做操作的。
直接close()对于蓝牙来说就会出现一个延迟,因为没有disconnect的蓝牙外设完全断开需要花点时间。
End
这一篇blog是写了一年多Android蓝牙后,从一次次的项目中慢慢总结的。现在回过去看最早最早做的蓝牙类,那是真的漏洞百出啊。
现在感觉自己封装的蓝牙库,和iOS越来越接近了。这样以后写完iOS,再写android会更方便~有点儿爽。