【问题标题】:Multiple writeDescriptor() calls fail on Android 5.1Android 5.1 上的多个 writeDescriptor() 调用失败
【发布时间】:2016-01-12 16:01:59
【问题描述】:

我有一个与蓝牙低功耗血糖仪通信的应用程序。

目前我的应用程序在 Android 4.4.4 上运行良好,但在 5.1.1 上失败

调试发现writeDescriptor()方法多次执行失败...

使用调试器,我进入了 writeDescriptor() 方法,发现它在这一行失败:

    public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
    ...
    synchronized(mDeviceBusy) {
        if (mDeviceBusy) return false;
        mDeviceBusy = true;
    }

(BluetoothGatt.java:1029)

我尝试等待 onDescriptorWrite() 回调,但它从未被调用,我还尝试等待(100 毫秒、500 毫秒和 2 秒)进行第二次写入,以查看 mDeviceBusy 变量是否已清除...两次尝试均失败...

我用谷歌搜索了这个问题,但找不到任何东西,最接近的是这个未回答的问题:Android SensorTag: writeDescriptor failed

注意:如果需要我可以附上我的代码,但它非常简单,类似于这篇文章中的代码:Android BLE notifications for Glucose

【问题讨论】:

    标签: android bluetooth bluetooth-lowenergy gatt android-5.1.1-lollipop


    【解决方案1】:

    我发现了问题...在我的代码中,我错误地定义了 onDescriptorWrite() 回调。修复此问题后,我在编写描述符成功时设法接收回调。

    解决了这个问题,我找到的解决方案是通过创建一个负责对操作进行排序的类来阻止 BTLE 操作。

    我创建的类非常简单,一个单独线程上的 BlockingQueue 用于对传入操作进行排队。

    BTLE 操作通过调用 writeDescriptor()、writeCharacteristic() 方法入队,一个单独的线程在空闲时开始执行操作,并且当操作完成时 gattCallback 通知线程,以便继续下一个操作。

    队列类:

    public BtleAsynchronousOperationThread(SensorAbstract sensor, BluetoothGatt gatt) {
    
        log("Creating Btle Operation thread");
        this.gatt = gatt;
        this.sensor = sensor;
    }
    
    public void enable() {
        log("Enabling btle command thread");
        queueReadySemaphore.release();
    }
    
    public void writeDescriptor(BluetoothGattDescriptor descriptor) throws BTCommunicationException {
    
        BtleAsynchronousCommand command = new BtleAsynchronousCommand(descriptor);
        try {
            queue.put(command);
        } catch (InterruptedException e) {
            throw new BTCommunicationException("Error while writing the descriptor");
        }
    }
    
    public void writeCharacteristic(BluetoothGattCharacteristic characteristic) throws BTCommunicationException {
    
        BtleAsynchronousCommand command = new BtleAsynchronousCommand(
                BtleAsynchronousCommand.CommandType.WRITE_CHARACTERISTIC, characteristic);
        try {
            queue.put(command);
        } catch (InterruptedException e) {
            throw new BTCommunicationException("Error while writing the characteristic");
        }
    }
    
    public void readCharacteristic(BluetoothGattCharacteristic characteristic) throws BTCommunicationException {
    
        BtleAsynchronousCommand command = new BtleAsynchronousCommand(
                BtleAsynchronousCommand.CommandType.READ_CHARACTERISTIC, characteristic);
        try {
            queue.put(command);
        } catch (InterruptedException e) {
            throw new BTCommunicationException("Error while reading the characteristic");
        }
    }
    
    public void cancel() {
        this.interrupt();
    }
    
    public void writeCompleted() {
        queueReadySemaphore.release();
    }
    
    @Override
    public void run() {
        BtleAsynchronousCommand command;
    
        try {
            while (!(Thread.currentThread().isInterrupted())) {
    
                queueReadySemaphore.acquire();
    
                log("Waiting for BTLE command");
    
                command = queue.take();
    
                switch (command.getCommandType()) {
                case WRITE_DESCRIPTOR:
                    log("Starting to write descriptor:" + command.getDescriptor().getUuid());
                    if (!gatt.writeDescriptor(command.getDescriptor())) {
                        throw new BTCommunicationException("Error while writing the descriptor");
                    }
    
                    break;
                case WRITE_CHARACTERISTIC:
                    log("Starting to write characteristic:" + command.getCharacteristic().getUuid());
                    if (!gatt.writeCharacteristic(command.getCharacteristic())) {
                        throw new BTCommunicationException("Error while writing the characteristic");
                    }
    
                    break;
                case READ_CHARACTERISTIC:
                    log("Starting to read characteristic:" + command.getCharacteristic().getUuid());
                    if (!gatt.readCharacteristic(command.getCharacteristic())) {
                        throw new BTCommunicationException("Error while writing the characteristic");
                    }
    
                    break;
                default:
                    log("Unknown command received");
                    break;
                }
            }
    
        } catch (InterruptedException e) {
            log("Btle thread interrupted, closing.");
        } catch (BTCommunicationException e) {
            log("Error while reading:" + e.getMessage());
            sensor.retry();
        }
    
        gatt = null;
        queue = null;
        queueReadySemaphore = null;
        Thread.currentThread().interrupt();
    }
    }
    

    定义蓝牙回调时:

    mGattCallback = new BluetoothGattCallback() {
    
    //Other methods can be defined around here, such as
    //onConnectionStateChange(), etc
    
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        onSensorCharacteristicChangedInner(gatt, characteristic);
    }
    
    @Override
    public void onDescriptorWrite (BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status){
        log("onDescriptorWrite:"+descriptor.getUuid()+ " status:"+status);
        btleCommunicationThread.writeCompleted();
    }
    
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
        log("onCharacteristicWrite:"+characteristic.getUuid()+ " status:"+status);
        btleCommunicationThread.writeCompleted();
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-05
      • 2015-08-10
      • 2013-01-03
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2011-01-13
      • 2012-09-21
      • 2015-09-27
      相关资源
      最近更新 更多