简体   繁体   English

BLE NOTIFY特性通知

[英]BLE NOTIFY characteristic not notifying

I need to communicate with a BLE thermometer. 我需要与BLE温度计通信。 Workflow is: 工作流程是:

  1. Register notifications on NOTIFY characteristic 注册有关NOTIFY特征的通知
  2. Write initialization string in WRITE, WRITE NO RESPONSE characteristic 在WRITE,WRITE NO RESPONSE特性中写入初始化字符串
  3. Data starts coming in in registered NOTIFY characteristic 数据开始以已注册的NOTIFY特征进入

This process works perfectly from Nordic nRF Connect app. 此过程可从Nordic nRF Connect应用程序完美运行。

However, when doing it myself using the following BluetoothGattCallback object, it fails - I never get updates - the onCharacteristicRead or onCharacteristicChanged callbacks never fire. 但是,当我自己使用以下BluetoothGattCallback对象执行此操作时,它将失败-我从不获取更新-onCharacteristicRead或onCharacteristicChanged回调从不触发。 Everything works, though - all methods that should return true on success do return true... Anyway, here is the BluetoothGattCallback: 一切正常,但是-成功时应返回true的所有方法都将返回true ...无论如何,这是BluetoothGattCallback:

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
    /**
     * Callback indicating when GATT client has connected/disconnected to/from a remote
     * GATT server.
     *
     * @param gatt     GATT client
     * @param status   Status of the connect or disconnect operation.
     *                 {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
     * @param newState Returns the new connection state. Can be one of
     *                 {@link BluetoothProfile#STATE_DISCONNECTED} or
     *                 {@link BluetoothProfile#STATE_CONNECTED}
     */
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothGatt.STATE_CONNECTED) {
            gatt.discoverServices();
        } else {
            responseCharacteristic = null;
            isConnected = false;
            disconnected();
        }
    }

    /**
     * Callback invoked when the list of remote services, characteristics and descriptors
     * for the remote device have been updated, ie new services have been discovered.
     *
     * @param gatt   GATT client invoked {@link BluetoothGatt#discoverServices}
     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
     */
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.wtf("THERMO", "Services discovered");
        BluetoothGattService thermoService = gatt.getService(THERMO_SERVICE);
        if (thermoService != null) {
            Log.wtf("THERMO", "Have service");
            //Find the characteristic
            configChar = thermoService.getCharacteristic(THERMO_CONFIGURATION);
            responseCharacteristic = thermoService.getCharacteristic(THERMO_RESPONSE);
            if (responseCharacteristic != null)
                setCharacteristicNotification(responseCharacteristic, true);
            else
                incompatibleTarget();
        } else
            incompatibleTarget();
    }

    /**
     * Callback triggered as a result of a remote characteristic notification.
     *
     * @param gatt           GATT client the characteristic is associated with
     * @param characteristic Characteristic that has been updated as a result
     */
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        Log.wtf("THERMO", "onCharChanged");
        dataReceived(characteristic);
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.wtf("THERMO", "onCharRead");
        dataReceived(characteristic);
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.wtf("THERMO", "Write done");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.wtf("THERMO", "Write ok");
            if (responseCharacteristic != null) {
                Log.wtf("THERMO", "Have response");
                isConnected = true;
                connected();
            }
        } else {
        }
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        Log.wtf("THERMO", "onDescWrite");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            if (configChar != null) {
                Log.wtf("THERMO", "Have config");
                configChar.setValue(thermoConfigData);
                Log.wtf("THERMO", "Writing: " + gatt.writeCharacteristic(configChar));
            }
        }
    }
};

And here is the method for registering the notifications: 这是注册通知的方法:

private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
    gatt.setCharacteristicNotification(characteristic, enabled);
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
    if (descriptor != null) {
        if (enabled) {
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        } else {
            descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
        }
        Log.wtf("THERMO", "notifyDesc: " + gatt.writeDescriptor(descriptor));
    }
}

The notification enabling method works with all other devices. 通知启用方法适用于所有其他设备。 Any ideas what I'm doing wrong? 有什么想法我做错了吗?

For some reason, changing the callback code to this helped. 由于某种原因,将回调代码更改为此有所帮助。 Looks like you need to call getService and getCharacteristic in the callback you're using them, you can't keep them around in a variable... 看起来您需要在使用它们的回调中调用getService和getCharacteristic,您无法将它们保留在变量中。

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
    /**
     * Callback indicating when GATT client has connected/disconnected to/from a remote
     * GATT server.
     *
     * @param gatt     GATT client
     * @param status   Status of the connect or disconnect operation.
     *                 {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
     * @param newState Returns the new connection state. Can be one of
     *                 {@link BluetoothProfile#STATE_DISCONNECTED} or
     *                 {@link BluetoothProfile#STATE_CONNECTED}
     */
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothGatt.STATE_CONNECTED) {
            gatt.discoverServices();
        } else {
            responseCharacteristic = null;
            isConnected = false;
            disconnected();
        }
    }

    /**
     * Callback invoked when the list of remote services, characteristics and descriptors
     * for the remote device have been updated, ie new services have been discovered.
     *
     * @param gatt   GATT client invoked {@link BluetoothGatt#discoverServices}
     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
     */
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.wtf("THERMO", "Services discovered");
        BluetoothGattService thermoService = gatt.getService(THERMO_SERVICE);
        if (thermoService != null) {
            Log.wtf("THERMO", "Have service");
            //Find the characteristic
            responseCharacteristic = thermoService.getCharacteristic(THERMO_RESPONSE);
            if (responseCharacteristic != null)
                setCharacteristicNotification(responseCharacteristic, true);
            else
                incompatibleTarget();
        } else
            incompatibleTarget();
    }

    /**
     * Callback triggered as a result of a remote characteristic notification.
     *
     * @param gatt           GATT client the characteristic is associated with
     * @param characteristic Characteristic that has been updated as a result
     */
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        Log.wtf("THERMO", "onCharChanged");
        dataReceived(characteristic);
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.wtf("THERMO", "onCharRead");
        dataReceived(characteristic);
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.wtf("THERMO", "Write done");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.wtf("THERMO", "Write ok");
            if (responseCharacteristic != null) {
                Log.wtf("THERMO", "Have response");
                isConnected = true;
                connected();
            }
        } else {
        }
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        Log.wtf("THERMO", "onDescWrite");
        if (status == BluetoothGatt.GATT_SUCCESS) {
            BluetoothGattService thermoService = gatt.getService(THERMO_SERVICE);
            if (thermoService != null) {
                configChar = thermoService.getCharacteristic(THERMO_CONFIGURATION);
                if (configChar != null) {
                    Log.wtf("THERMO", "Have config");
                    configChar.setValue(thermoConfigData);
                    Log.wtf("THERMO", "Writing: " + gatt.writeCharacteristic(configChar));
                }
            }
        }
    }
};

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM