我正在寻找一种 android 方法来刷新应用程序从 Ble 设备接收到的特征,或者至少从数据中知道连接已经丢失,除非它在断开连接后大约 15 秒。如果有办法改变 gatt 连接超时,那会好很多。
以不同的形式重复,我想要一个解决方案(或可以解释的链接),通过查看我得到的值是否是新鲜的,比当前的超时值更快地检测 BLE 设备的断开连接通过刷新特性或更改 gatt 端的断开连接超时,我可以在一秒钟内看到它断开连接以触发其他代码。
我正在寻找一种 android 方法来刷新应用程序从 Ble 设备接收到的特征,或者至少从数据中知道连接已经丢失,除非它在断开连接后大约 15 秒。如果有办法改变 gatt 连接超时,那会好很多。
以不同的形式重复,我想要一个解决方案(或可以解释的链接),通过查看我得到的值是否是新鲜的,比当前的超时值更快地检测 BLE 设备的断开连接通过刷新特性或更改 gatt 端的断开连接超时,我可以在一秒钟内看到它断开连接以触发其他代码。
这里的其他答案可能比这个更好,但这是我解决问题的方法。在使用它之前,一定要尝试Emil 的回答。
由于时间太慢而无法等待,我所做的就是检查 rssi,因为它总是在变化。如果有一段时间,比如说 3 秒,该值保持不变,它将与设备断开连接。这围绕 15 秒超时并添加我们自己的超时。
这将是检查信号强度所需要的。这是几年前写的,所以有些东西可能需要改变。
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status){
//check for signal strength changes. It will stay the same if we
//are getting no updates
if(mLastRssi == rssi){
disconnectCounter++;
if(disconnectCounter> 140) {
//disconnect logic as if we are done with connection
//maybe start listening for device again to reconnect
disconnectCounter = 0;
}
}
else{
//we are connected. reset counter
disconnectCounter = 0;
}
//store last value as global for comparison
mLastRssi= rssi;
}
}
在循环中的某个地方,调用
mBluetoothGatt.readRemoteRssi()
不知道这是否有帮助,但您可以利用(如果有的话)在 gatt 中传输的周期性数据。因此,例如,如果您测量 1 秒的周期性,您可以执行以下操作:
// runnable to detect the lack of activity:
private final Runnable watchDog = new Runnable() {
@Override
public void run() {
measurement_timeout--;
if(measurement_timeout==0) {
Log.d("BLE_CONTROLLER", "PROBE WITH NO ACTIVITY");
}
}
};
// this should be in the reception of the periodic data:
measurement_timeout++;
mHandler.postDelayed(watchDog, 3000);
因此,“measurement_timeout”将作为实际超时工作,当它达到 0 时,意味着您在 3000 毫秒的时间内没有收到数据。请注意,您的观看时间必须 > 2*数据周期。
我设法实现快速 gatt 断开连接的唯一方法是确保外围设备在断电或切断连接之前发送 BLE 断开连接指令。
一旦 android 接收到断开连接指令,gatt 会立即整理,而不是花 15 秒来意识到外围设备丢失。
似乎大多数外围设备都不会打扰,只是消失了。
显然,这种方法只有在您能够修改外围设备的情况下才有可能。
正确的方法是使用来自外设端的连接参数更新请求将超时更改为较低的值。
Android中有一个回调:
BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange( BluetoothGatt gatt,int status,int newState){
if(newState == BluetoothProfile.STATE_DISCONNECTED){
//your code here
}
}
}