欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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();
        }
    };

相关标签: Android