BLE蓝牙gatt协议的server端发布服务的UUID不全问题
程序员文章站
2022-07-13 17:54:35
...
最近项目使用BLE蓝牙的gatt协议进行通讯,在mtk平台上遇见一个问题:server端发布服务的uuid总是获取不全,有时候甚至获取不到,特别频繁。
我之前是这样添加多个service的,以三个为例:
//马达服务
BluetoothGattService gattService = new BluetoothGattService(Constant.UUID_SERVER_MOVE, BluetoothGattService.SERVICE_TYPE_PRIMARY);
//读写的特征值
BluetoothGattCharacteristic characteristicWrite = new BluetoothGattCharacteristic(Constant.UUID_CHAR_READ_WRITE_MOVE,
BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
//只读的特征值
BluetoothGattCharacteristic characteristicRead = new BluetoothGattCharacteristic(Constant.UUID_CHAR_READ_MOVE,
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ);
//将特征值添加至服务里
gattService.addCharacteristic(characteristicWrite);
gattService.addCharacteristic(characteristicRead);
//添加服务
bluetoothGattServer.addService(gattService);
//扫码拍作业服务
BluetoothGattService gattServiceScanTakePhoto = new BluetoothGattService(Constant.UUID_SERVER_SCAN_TAKEPHOTO, BluetoothGattService.SERVICE_TYPE_PRIMARY);
//扫码拍作业服务-读写的特征值
BluetoothGattCharacteristic characteristicWriteScanTakePhoto = new BluetoothGattCharacteristic(Constant.UUID_CHAR_SCAN_TAKEPHOTO_READ_WRITE,
BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
//扫码拍作业服务-只读的特征值
BluetoothGattCharacteristic characteristicReadScanTakePhoto = new BluetoothGattCharacteristic(Constant.UUID_CHAR_SCAN_TAKEPHOTO_READ,
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ);
//将特征值添加至服务里
gattServiceScanTakePhoto.addCharacteristic(characteristicWriteScanTakePhoto);
gattServiceScanTakePhoto.addCharacteristic(characteristicReadScanTakePhoto);
//添加服务
bluetoothGattServer.addService(gattServiceScanTakePhoto);
//二维码动作触发
BluetoothGattService gattServiceQRActionTrigger = new BluetoothGattService(Constant.UUID_SERVER_QR_ACTION_TRIGGER, BluetoothGattService.SERVICE_TYPE_PRIMARY);
//二维码动作触发-读写的特征值
BluetoothGattCharacteristic characteristicWriteQRActionTrigger = new BluetoothGattCharacteristic(Constant.UUID_SERVER_QR_ACTION_TRIGGER_READ_WRITE,
BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
//二维码动作触发-只读的特征值
BluetoothGattCharacteristic characteristicReadQRActionTrigger = new BluetoothGattCharacteristic(Constant.UUID_SERVER_QR_ACTION_TRIGGER_READ,
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ);
//将特征值添加至服务里
gattServiceQRActionTrigger.addCharacteristic(characteristicWriteQRActionTrigger);
gattServiceQRActionTrigger.addCharacteristic(characteristicReadQRActionTrigger);
//添加服务
bluetoothGattServer.addService(gattServiceQRActionTrigger);
后来发现很多时候都不回调
bluetoothManager.openGattServer(context, gattServerCallback)中gattServerCallback的
onServiceAdded(int status, BluetoothGattService service)方法,正常情况应该每添加成功一个service都回调一次该方法的。
后来想了一个方法:将所有service放到一个集合中,上一个service添加成功过后再添加下一个。
写完后还是会有问题,有时候某个service添加不成功就不回调该方法,后面的service就都添加不成了。
然后又想了一个升级方法:在以上方法的基础上,增加一个计时器,每次添加service就自启一个计时器计时3s,如果3s后还没有执行onServiceAdded方法,就再添加一次这个service,倒计时3s。如果回调onServiceAdded了,就取消计时器并添加下一个。
思路讲解完了,上代码:
List<BluetoothGattService> bluetoothGattServices = new ArrayList<>();
bluetoothGattServices.add(gattService);
bluetoothGattServices.add(gattServiceScanTakePhoto);
bluetoothGattServices.add(gattServiceQRActionTrigger);
//service序号
int serviceSerNum = 0;
Timer timer = new Timer();
//核心方法:负责添加下一个服务并启动计时器
private void addToGattServer() {
if (serviceSerNum != 0) {
timer.cancel();
}
if (serviceSerNum >= bluetoothGattServices.size()) {
return;
}
bluetoothGattServer.addService(bluetoothGattServices.get(serviceSerNum));
serviceSerNum++;
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
//3s后上一个还没添加成功就重新添加上一个
serviceSerNum--;
serviceSerNum = Math.max(serviceSerNum, 0);
LogUtils.e(TAG, "-->重新添加第" + serviceSerNum + "个");
addToGattServer();
}
}, 3000);
}
private final BluetoothGattServerCallback gattServerCallback = new BluetoothGattServerCallback() {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
BluetoothServiceManager.this.device = device;
if (newState == BluetoothProfile.STATE_CONNECTED) {
btNotify(BTListener.CONNECTED, null, null);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
btNotify(BTListener.DISCONNECTED, null, null);
}
}
@Override
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
String uuid = characteristic.getUuid().toString();
Log.e(TAG, "收到了客户端发过来的数据 +uuid:" + characteristic.getUuid().toString());
Log.e(TAG, "收到了客户端发过来的数据 +requestId:" + requestId);
Log.e(TAG, "收到了客户端发过来的数据 +offset:" + offset);
if (value != null && value.length != 0) {
Log.e(TAG, "--- " + Arrays.toString(value));
btNotify(BTListener.MSG_RECEIVED, value, uuid);
}
//告诉客户端发送成功
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, characteristic.getValue());
}
@Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
String uuid = characteristic.getUuid().toString();
Log.e(TAG, "收到了客户端发的读申请 " + characteristic.getUuid().toString());
Log.e(TAG, "收到了客户端发的读申请 requestId:" + requestId);
Log.e(TAG, "收到了客户端发的读申请 offset:" + offset);
byte[] value = bluetoothPresenter.getStatus(uuid);
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, value);
}
@Override
public void onServiceAdded(int status, BluetoothGattService service) {
super.onServiceAdded(status, service);
Log.e(TAG, "onServiceAdded --->:" + service.getUuid());
//添加成功后再添加下一个
addToGattServer();
}
};
上一篇: 解决GitHub访问慢的问题