【问题标题】:BLE NOTIFY characteristic not notifyingBLE NOTIFY 特性不通知
【发布时间】:2019-02-24 14:12:11
【问题描述】:

我需要与 BLE 温度计通信。工作流程是:

  1. 注册关于 NOTIFY 特征的通知
  2. 在 WRITE 中写入初始化字符串,WRITE NO RESPONSE 特性
  3. 数据开始进入已注册的 NOTIFY 特征

这个过程在 Nordic nRF Connect 应用中完美运行。

但是,当我自己使用以下 BluetoothGattCallback 对象执行此操作时,它会失败 - 我永远不会得到更新 - onCharacteristicRead 或 onCharacteristicChanged 回调永远不会触发。不过,一切正常 - 所有应该在成功时返回 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));
            }
        }
    }
};

这里是注册通知的方法:

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

通知启用方法适用于所有其他设备。任何想法我做错了什么?

【问题讨论】:

  • gatt.setCharacteristicNotification(characteristic, enabled); 的结果是什么?

标签: android bluetooth-lowenergy


【解决方案1】:

出于某种原因,将回调代码更改为此有所帮助。看起来您需要在使用它们的回调中调用 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));
                }
            }
        }
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多