writeCharacteristic() returns true,但不调用 onCharacteristicWrite()
writeCharacteristic() returns true, but does not call onCharacteristicWrite()
我想读取存储在设备中的特征值,修改该值,然后将其写入设备。由于某种原因,writeCharacteristic()
return 为真,但内部设备值没有改变并且没有调用 onCharacteristicWrite()
。事实上,出于某种原因,如果我尝试写一些东西,它只会被 调用 ,然后在我关闭或重新打开应用程序后不久被调用 - 并且不会更改设备值。我已经研究了几天,这让我发疯。可能值得注意的是,手动和通过通知读取特征都可以正常工作。
为什么 writeCharacteristic()
没有通过,为什么 onCharacteristicWrite()
在这么奇怪的时间被调用?
我不确定问题出在哪里。它可能是一些愚蠢而简单的事情,比如错误地调用 writeCharacteristic()
(我的实现是基于问题“Working with BLE Android 4.3 how to write characteristics?”)。是否有可能因为 onCharacteristicRead()
未完成而忽略请求?
我认为这些链接似乎对指出问题最有帮助,但我自己无法从中提取任何内容:
- Android BLE API: GATT Notification not received
- https://code.google.com/p/android-developer-preview/issues/detail?id=1714
作为我的代码的演练,触发了一个 onItemClick()
事件,该事件启动了序列。
int flag = 1;
((MainActivity)getActivity()).BtService.readFlag(flag);
它调用一个函数(在 Service
中)来验证蓝牙连接并读取特征。
public boolean readFlag(int flag){
/*... removed code here verifies that the Bluetooth Gatt is available,
that the Service exists...*/
BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);
if (characteristic == null) {
Log.e(TAG, "char not found!");
return false;
}
try {
// Store intended flag value in SharedPreferences, then read the current one.
Editor fEditor = sPrefs.edit();
fEditor.putInt(calibrationSetFlagToSendKey, flag);
fEditor.commit();
mConnectedGatt.readCharacteristic(characteristic);
// Catch response in onCharacteristicRead() callback.
return true;
}
catch (NullPointerException e) {
Log.w("readCharacteristic", "The characteristic could not be read.");
return false;
}
}
onCharacteristicRead()
被调用,它只调用一个 Handler
来修改并将结果广播回 MainActivity
。 trueFlagValue
是一个全局存储在 Service
中的字节(我知道这种做法不好,但我打算稍后修改它。)
case MSG_SEND_FLAG:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining current flags");
return;
}
int recentReadDeviceFlag = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
int initialFlag = sPrefs.getInt(calibrationSetFlagToSendKey, 0);
if (initialFlag == 0) Log.e("Write Debug", "Flag to send is apparently 0");
/*... Arithmetic modifying flag integer value...*/
//Desired value is the OR'd value of the value read and value desired
trueFlagValue = (byte) ((byte) initialFlag | (byte) recentReadDeviceFlag);
Log.d("Read Debug", "OR'd value is " + trueFlagValue +", sending broadcast");
Intent fIntent = new Intent("com.example.appwithble.SEND_FLAGS");
sendBroadcast(fIntent);
break;
MainActivity
中的 BroadcastReceiver
然后调用我的 Service
中的方法,验证对 writeCharacteristic()
的请求,就像对 readCharacteristic()
所做的那样。访问之前设置的 trueFlagValue
。
else if("com.example.appwithble.SEND_FLAGS".equals(intent.getAction())) {
BtService.performWriteFlag();
}
// ...
public boolean performWriteFlag () {
/*... check Gatt is available and that Service exists...*/
BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);
if (characteristic == null) {
Log.e(TAG, "char not found!");
return false;
}
byte[] byteValue = new byte[1];
byteValue[0] = trueFlagValue;
characteristic.setValue(byteValue);
boolean status = mConnectedGatt.writeCharacteristic(characteristic);
return status;
}
然后应该调用我的 onCharacteristicWrite()
回调,目前只包含一行代码来记录一条消息。实际上,这只会在应用程序关闭或重新打开时偶尔调用。存储在我的外设特性中的值永远不会改变。
我不是专家,但在我的 BLE 应用中
- 我先连接外设
- 然后与之配对(通过调用createBond()方法),
- 然后发现服务,
- 然后发现特征(并将它们存储在应用程序变量中)和
- 最终将值写入特征(通过使用应用程序变量)
你试过了吗?
这样的菜鸟错误。
因为在我假设写入过程或设备出现问题之前,我没有尝试过写入数据。在查看了来自 readCharacteristic()
的数据类型并询问了我要发送到的设备后,我开始意识到我发送的数据格式可能有误。
事实证明,即使只需要发送四个不同的标志(可以用两位完成),特征也需要格式化为 两个字节特定的设备,而不是一个。所以如果我把我的字节数组做成这样,它就会起作用。
byte[] byteValue = new byte[2];
byteValue[0] = trueFlagValue;
byteValue[1] = (byte)0;
characteristic.setValue(byteValue);
我想如果其他人遇到写入启动但未完成的奇怪问题,那么很可能是这样的问题 - 至少,设备中的某些东西正在拒绝写入。
我想读取存储在设备中的特征值,修改该值,然后将其写入设备。由于某种原因,writeCharacteristic()
return 为真,但内部设备值没有改变并且没有调用 onCharacteristicWrite()
。事实上,出于某种原因,如果我尝试写一些东西,它只会被 调用 ,然后在我关闭或重新打开应用程序后不久被调用 - 并且不会更改设备值。我已经研究了几天,这让我发疯。可能值得注意的是,手动和通过通知读取特征都可以正常工作。
为什么 writeCharacteristic()
没有通过,为什么 onCharacteristicWrite()
在这么奇怪的时间被调用?
我不确定问题出在哪里。它可能是一些愚蠢而简单的事情,比如错误地调用 writeCharacteristic()
(我的实现是基于问题“Working with BLE Android 4.3 how to write characteristics?”)。是否有可能因为 onCharacteristicRead()
未完成而忽略请求?
我认为这些链接似乎对指出问题最有帮助,但我自己无法从中提取任何内容:
- Android BLE API: GATT Notification not received
- https://code.google.com/p/android-developer-preview/issues/detail?id=1714
作为我的代码的演练,触发了一个 onItemClick()
事件,该事件启动了序列。
int flag = 1;
((MainActivity)getActivity()).BtService.readFlag(flag);
它调用一个函数(在 Service
中)来验证蓝牙连接并读取特征。
public boolean readFlag(int flag){
/*... removed code here verifies that the Bluetooth Gatt is available,
that the Service exists...*/
BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);
if (characteristic == null) {
Log.e(TAG, "char not found!");
return false;
}
try {
// Store intended flag value in SharedPreferences, then read the current one.
Editor fEditor = sPrefs.edit();
fEditor.putInt(calibrationSetFlagToSendKey, flag);
fEditor.commit();
mConnectedGatt.readCharacteristic(characteristic);
// Catch response in onCharacteristicRead() callback.
return true;
}
catch (NullPointerException e) {
Log.w("readCharacteristic", "The characteristic could not be read.");
return false;
}
}
onCharacteristicRead()
被调用,它只调用一个 Handler
来修改并将结果广播回 MainActivity
。 trueFlagValue
是一个全局存储在 Service
中的字节(我知道这种做法不好,但我打算稍后修改它。)
case MSG_SEND_FLAG:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining current flags");
return;
}
int recentReadDeviceFlag = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
int initialFlag = sPrefs.getInt(calibrationSetFlagToSendKey, 0);
if (initialFlag == 0) Log.e("Write Debug", "Flag to send is apparently 0");
/*... Arithmetic modifying flag integer value...*/
//Desired value is the OR'd value of the value read and value desired
trueFlagValue = (byte) ((byte) initialFlag | (byte) recentReadDeviceFlag);
Log.d("Read Debug", "OR'd value is " + trueFlagValue +", sending broadcast");
Intent fIntent = new Intent("com.example.appwithble.SEND_FLAGS");
sendBroadcast(fIntent);
break;
MainActivity
中的 BroadcastReceiver
然后调用我的 Service
中的方法,验证对 writeCharacteristic()
的请求,就像对 readCharacteristic()
所做的那样。访问之前设置的 trueFlagValue
。
else if("com.example.appwithble.SEND_FLAGS".equals(intent.getAction())) {
BtService.performWriteFlag();
}
// ...
public boolean performWriteFlag () {
/*... check Gatt is available and that Service exists...*/
BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);
if (characteristic == null) {
Log.e(TAG, "char not found!");
return false;
}
byte[] byteValue = new byte[1];
byteValue[0] = trueFlagValue;
characteristic.setValue(byteValue);
boolean status = mConnectedGatt.writeCharacteristic(characteristic);
return status;
}
然后应该调用我的 onCharacteristicWrite()
回调,目前只包含一行代码来记录一条消息。实际上,这只会在应用程序关闭或重新打开时偶尔调用。存储在我的外设特性中的值永远不会改变。
我不是专家,但在我的 BLE 应用中
- 我先连接外设
- 然后与之配对(通过调用createBond()方法),
- 然后发现服务,
- 然后发现特征(并将它们存储在应用程序变量中)和
- 最终将值写入特征(通过使用应用程序变量)
你试过了吗?
这样的菜鸟错误。
因为在我假设写入过程或设备出现问题之前,我没有尝试过写入数据。在查看了来自 readCharacteristic()
的数据类型并询问了我要发送到的设备后,我开始意识到我发送的数据格式可能有误。
事实证明,即使只需要发送四个不同的标志(可以用两位完成),特征也需要格式化为 两个字节特定的设备,而不是一个。所以如果我把我的字节数组做成这样,它就会起作用。
byte[] byteValue = new byte[2];
byteValue[0] = trueFlagValue;
byteValue[1] = (byte)0;
characteristic.setValue(byteValue);
我想如果其他人遇到写入启动但未完成的奇怪问题,那么很可能是这样的问题 - 至少,设备中的某些东西正在拒绝写入。