简体   繁体   English

Android BLE:onDescriptorWrite、onCharacteristicWrite、onCharacteristicRead 没有被调用,但其他回调工作

[英]Android BLE: onDescriptorWrite, onCharacteristicWrite, onCharacteristicRead none are being called, but other callbacks work

I am writing an Android client that connects to a custom BLE server (peripheral) using a custom service and characteristics.我正在编写一个使用自定义服务和特性连接到自定义 BLE 服务器(外围设备)的 Android 客户端。 I have verified that I can communicate with the device using the Android app BLE Scanner, and have also verified that I have correct UUIDs for the various characteristics.我已经验证我可以使用 Android 应用程序 BLE Scanner 与设备进行通信,并且还验证了我对各种特性都有正确的 UUID。 I have written code to write to the write-only characteristic, and the onCharacteristicWrite callback is never called.我已经编写了写入只写特性的代码,并且永远不会调用 onCharacteristicWrite 回调。 I have also written code to enable notifications on the read/notify characteristic, including updating the CCC descriptor to indicate notifications enabled, but neither the onDescriptorWrite, onCharacteristicWrite nor onCharacteristicChanged callback is called.我还编写了代码来启用关于读取/通知特性的通知,包括更新 CCC 描述符以指示启用通知,但既不调用 onDescriptorWrite、onCharacteristicWrite 也不调用 onCharacteristicChanged 回调。 I know that the BluetoothGattCallback is properly registered, because I do get calls to onConnectionStateChanged and onServicesDiscovered.我知道 BluetoothGattCallback 已正确注册,因为我确实收到了对 onConnectionStateChanged 和 onServicesDiscovered 的调用。

This code enables notifications on a given characteristic:此代码启用有关给定特征的通知:

    public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
                                          boolean enabled) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(CLASS_NAME, "BluetoothAdapter not initialized");
        return;
    }
    // Check if this characteristic actually has NOTIFY property
    if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0 ) {
        Log.e(CLASS_NAME, "Characteristic does not support notifications");
        return;
    }
    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

    // For characteristics that support it, write to the CCC descriptor
    // that notifications are enabled.
    if (enabled) {
        if (TX_PERIPHERAL_TO_CENTRAL.equals(characteristic.getUuid())) {
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
                    UUID.fromString(GattAttributes.TX_PERIPHERAL_TO_CENTRAL_CCC));
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            if (!mBluetoothGatt.writeDescriptor(descriptor)) {
                Log.d(CLASS_NAME, "Write to descriptor failed: "+TX_PERIPHERAL_TO_CENTRAL_CCC);
            }
        }
    }
}

I can see in the logs that this gets called and that the writeDescriptor() call succeeds.我可以在日志中看到它被调用并且 writeDescriptor() 调用成功。 However, onDescriptorWrite is never called, neither is onCharacteristicChanged.但是,永远不会调用 onDescriptorWrite,也不会调用 onCharacteristicChanged。

Here is the code for the callbacks:这是回调的代码:

        @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        Log.d(CLASS_NAME, "in onCharacteristicChange() characteristic = "+characteristic.getUuid());
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        super.onDescriptorWrite(gatt, descriptor, status);
        Log.d(CLASS_NAME, "in onDescriptorWrite() status = "+status+", descriptor = "+descriptor.getUuid());
        Log.d(CLASS_NAME, "  descriptor value = "+descriptor.getValue());
    }

As you can see, I should be seeing something in the logs if either of these were called.如您所见,如果调用其中任何一个,我应该会在日志中看到一些内容。

There's a similar issue with characteristic writes.特征写入也有类似的问题。 Here is the code that performs a write, but onCharacteristicWrite is never called after this:这是执行写入的代码,但在此之后永远不会调用 onCharacteristicWrite:

    public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic, String data) {
    boolean result = false;
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(CLASS_NAME, "BluetoothAdapter not initialized");
        return false;
    }
    // Check if this characteristic actually has WRITE property
    if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 ) {
        Log.e(CLASS_NAME, "Characteristic is not writeable");
        return false;
    }
    byte[] ascii = data.getBytes(StandardCharsets.US_ASCII);
    if (characteristic.setValue(ascii)) {
        result = mBluetoothGatt.writeCharacteristic(characteristic);
    }
    return result;
}

In this case, writeCharacteristic() always returns false, despite the fact that I check to make sure it's a writable characteristic.在这种情况下,writeCharacteristic() 总是返回 false,尽管我检查以确保它是可写特征。

I have also used BLE Scanner to make sure that the characteristics I'm using can successfully be written to and read using notifications, so whatever the problem is, it's on my end.我还使用 BLE Scanner 来确保可以使用通知成功写入和读取我正在使用的特性,所以无论问题是什么,它都在我的尽头。 And apologies for the messy code - it's definitely in an incomplete state.并为凌乱的代码道歉 - 它肯定处于不完整的状态。

I've managed to figure this out on my own.我已经设法自己解决了这个问题。 The reason the attempts to write and turn on notifications were failing is the way in which I was managing the BluetoothGattCharacteristic objects.写入和打开通知的尝试失败的原因是我管理BluetoothGattCharacteristic对象的方式。 Using sample code I had found online, I was caching all of the BluetoothGattCharacteristic objects that are returned from BluetoothGatt.getServices() .使用我在网上找到的示例代码,我正在缓存从BluetoothGatt.getServices()返回的所有BluetoothGattCharacteristic对象。 I was then fetching each BluetoothGattCharacteristic from the cache and using it to make calls to operations such as BluetoothGatt.writeCharacteristic() or BluetoothGatt.setCharacteristicNotification() .然后我从缓存中获取每个BluetoothGattCharacteristic并使用它来调用诸如BluetoothGatt.writeCharacteristic()BluetoothGatt.setCharacteristicNotification()之类的操作。 Apparently, this is not the correct approach.显然,这不是正确的做法。

I have since modified my code so that I fetch a fresh copy of the service and characteristic object from BluetoothGatt before making any of the calls that were failing, using the method shown here:我已经修改了我的代码,以便在使用此处显示的方法进行任何失败的调用之前从BluetoothGatt获取服务和特征对象的新副本:

/**
 * Fetches a characteristic from the GATT server.
 * @param serviceUUID unique id of the service that has the characteristic
 * @param characteristicUUID unique id of the characteristic
 * @return the requested characteristic, or null
 */
private BluetoothGattCharacteristic getCharacteristic(UUID serviceUUID, UUID characteristicUUID) {
    if (characteristicUUID == null) {
        Log.e(CLASS_NAME, "Attempt to fetch characteristic using null characteristic UUID");
        return null;
    }
    if (serviceUUID == null) {
        Log.e(CLASS_NAME, "Attempt to fetch characteristic "+characteristicUUID+" using null service UUID");
        return null;
    }
    BluetoothGattCharacteristic characteristic = null;
    BluetoothGattService service = mBluetoothGatt.getService(serviceUUID);
    if (service != null) {
        characteristic = service.getCharacteristic(characteristicUUID);
        if (characteristic == null) {
            Log.d(CLASS_NAME, "getCharacteristic(): Unable to obtain characteristic.");
        }
    }
    else {
        Log.d(CLASS_NAME, "getCharacteristic(): Unable to obtain service.");
    }

    return characteristic;
}

With this, I now get the expected callbacks to onCharacteristicWrite , onCharacteristicChange , onDescriptorWrite , etc. I hope this is helpful to someone in the future.有了这个,我现在得到了对onCharacteristicWriteonCharacteristicChangeonDescriptorWrite等的预期回调。我希望这对将来的某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 android 4.3蓝牙ble不叫onCharacteristicRead() - android 4.3 Bluetooth ble don't called onCharacteristicRead() android ble无法调用onCharacteristicRead() - android ble cannot call onCharacteristicRead() Android BLE:onCharacteristicRead()似乎被线程阻止 - Android BLE: onCharacteristicRead() appears to be blocked by thread BLE Android - onConnectionStateChange 未被调用 - BLE Android - onConnectionStateChange not being called Android BLE onCharacteristicRead 错误状态导致蓝牙已停止工作 - Android BLE onCharacteristicRead wrong status causing Bluetooth has stopped working Android BLE write Characteristic locks up onCharacteristicWrite/onCharacteristicChange - Android BLE write Characteristic locks up onCharacteristicWrite/onCharacteristicChange onCharacteristicWrite 中的 BLE Gatt 状态 133 - BLE Gatt status 133 in onCharacteristicWrite 在BLE android应用中,即使我写了bluetoothGatt.readCharacteristic(gattCharacteristic),onCharacteristicRead也不会调用 - In BLE android app onCharacteristicRead is not calling even i have write bluetoothGatt.readCharacteristic(gattCharacteristic) Android BLE中未调用onBatchScanResults - onBatchScanResults is not called in Android BLE BluetoothGattCallback onCharacteristicRead 从未回调 - BluetoothGattCallback onCharacteristicRead never called back
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM