Android writeCharacteristic()返回true,但不调用onCharacteristicWrite()
我希望读取存储在设备中的特征值,修改该值,然后将其写入设备。由于某些原因,Android writeCharacteristic()返回true,但不调用onCharacteristicWrite(),android,bluetooth,bluetooth-lowenergy,Android,Bluetooth,Bluetooth Lowenergy,我希望读取存储在设备中的特征值,修改该值,然后将其写入设备。由于某些原因,writeCharacteristic()返回true,但内部设备值不会更改,并且不会调用onCharacteristicWrite()。事实上,出于某种原因,它只在我尝试写东西时才会被调用,然后在我关闭或重新打开应用程序后不久被调用,并且不会更改设备值。我已经调查这件事好几天了,它快把我逼疯了。值得注意的是,手动和通过通知读取特征都可以正常工作 为什么writeCharacteristic()没有通过,为什么在这么奇怪的
writeCharacteristic()
返回true,但内部设备值不会更改,并且不会调用onCharacteristicWrite()
。事实上,出于某种原因,它只在我尝试写东西时才会被调用,然后在我关闭或重新打开应用程序后不久被调用,并且不会更改设备值。我已经调查这件事好几天了,它快把我逼疯了。值得注意的是,手动和通过通知读取特征都可以正常工作
为什么writeCharacteristic()
没有通过,为什么在这么奇怪的时间调用onCharacteristicWrite()
我不确定这个问题是从哪里来的。它可能是一些愚蠢而简单的东西,比如错误地调用writeCharacteristic()
(我的实现基于问题“”)。是否有可能因为onCharacteristicRead()
未完成而忽略该请求
我相信这些链接似乎对指出问题最有帮助,但我自己却无法从中获得任何信息:
onItemClick()
事件,该事件将启动序列
int flag = 1;
((MainActivity)getActivity()).BtService.readFlag(flag);
它调用一个函数(在服务中
)来验证蓝牙连接并读取特征
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()
,它只调用处理程序
来修改结果并将结果广播回MainActivity
trueFlagValue
是一个全局存储在服务中的字节(我知道这是一个错误的做法,但我打算稍后对此进行修改。)
main活动中的BroadcastReceiver
随后调用我的服务中的一个方法,验证请求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;
}
然后应该调用MyonCharacteristicWrite()
回调,并且当前只包含一行用于记录消息的代码。实际上,只有在应用程序关闭或重新打开时,才会调用此函数。存储在我的外设特征中的值永远不会改变。我不是专家,但在我的BLE应用程序中
- 我首先连接到外围设备
- 然后配对到它(通过调用方法)
- 然后发现服务
- 然后发现特征(并将其存储在应用程序变量中)并
- 最后将值写入特征(使用应用程序变量)
你试过了吗?这是个新手犯的错误
因为我以前没有尝试过写数据,所以我认为写过程或设备出了问题。通过查看readCharacteristic()
提供的各种数据,并询问我要发送到的设备,我开始意识到,可能我发送的数据格式不正确
事实证明,即使只需要发送四个不同的标志(可以用两个位完成),但对于我的特定设备,特性需要格式化为两个字节,而不是一个字节。所以,如果我把我的字节数组做成这样,它就可以工作了
byte[] byteValue = new byte[2];
byteValue[0] = trueFlagValue;
byteValue[1] = (byte)0;
characteristic.setValue(byteValue);
我预计,如果其他任何人有一个奇怪的问题,即写入已启动但尚未完成,那么很可能是这样的问题-至少,设备中存在拒绝写入的问题。我还没有尝试实现任何类型的配对-但过程的其余部分仍然存在。我让用户选择一个设备并连接到device.connectGatt,读取/存储所有特性并设置通知程序。我可以很好地完成这两项工作,我可以阅读命令,为通知程序设置描述符,并在onCharacteristicChanged()
中接收特征。我不认为需要编写配对,但因为这是我打算稍后实现的东西,所以现在尝试一下对我没有什么影响。我会让你知道它是否工作。我的问题是,这个回调在4.3设备中工作,但在棒棒糖设备中没有启动
byte[] byteValue = new byte[2];
byteValue[0] = trueFlagValue;
byteValue[1] = (byte)0;
characteristic.setValue(byteValue);