BLE NOTIFY 特性不通知
Posted
技术标签:
【中文标题】BLE NOTIFY 特性不通知【英文标题】:BLE NOTIFY characteristic not notifying 【发布时间】:2019-02-24 14:12:11 【问题描述】:我需要与 BLE 温度计通信。工作流程是:
-
注册关于 NOTIFY 特征的通知
在 WRITE 中写入初始化字符串,WRITE NO RESPONSE 特性
数据开始进入已注册的 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);
的结果是什么?
【参考方案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));
;
【讨论】:
以上是关于BLE NOTIFY 特性不通知的主要内容,如果未能解决你的问题,请参考以下文章