我遇到了Android 6.0和一些蓝牙低功耗设备的严重问题。其中一个冲突的设备就是这个:
DEVICE INFO:
Name: Samsung Galaxy SV
Model number: SM-G900V
Android vers: 6.0.1
Patch level: May 1, 2016
Hard. vers: G900V.05
如果我根据连接和断开应用程序与BLE外围设备进行压力测试,则成功率几乎不会达到50%。
阅读Android的最新文档,他们建议在connectGatt方法的最后一个参数中指定传输模式,以强制执行BLE传输连接而不是BR / EDR:
device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
这种改进没有任何改变。
关于一些suggestions以及关于BLE连接问题的阅读,我发现了三星Galaxy S6的几个相关问题,在one of those他们提出了一系列修复BLE连接问题的步骤。关键的一个是clear Bluetooth Share system app数据。这样做,连接率几乎立即增加了100%。但是,如果您等待并使用其他一些BLE应用程序并连接到其他外围设备,问题迟早会回来。
Google Play中有some apps试图解决这些BLE问题,以及他们基本上做的是:
/system/bin/rm -r /data/misc/bluetoothd/*
/system/bin/rm -r /data/misc/hcid/*
虽然这是一种清除蓝牙缓存的方法,但它要求设备根植,这对专业应用来说不是一个合理的解决方案。
我所研究的私有Android API都没有帮助我解决这个问题,而我发现的唯一一个与enforce service discovery cache cleanup类似的问题与此问题无关。
使用BLE数据包嗅探器我发现ADV_CONNECT_REQ
甚至没有从设备发送到外围设备,一段时间后Android堆栈会触发STATE_DISCONNECTED
中的BluetoothGattCallback
事件。
我不知道为什么在某些6.0设备中出现此问题而在其他设备中没有,因为蓝牙共享缓存似乎是问题所在。那里到底存储了什么?刚刚连接/配对的设备?我是唯一一个遇到这个问题的人吗?如果没有,你们怎么解决它?我不想指导最终用户如何清除蓝牙共享应用数据。
答案 0 :(得分:0)
有一种名为“removeBond”的隐藏方法。有时,无法清除设备,在这种情况下,您需要调用删除绑定。
来自here的代码
//remove authrization
Method method = null;
try {
method = gatt.getDevice().getClass().getMethod("removeBond", (Class[]) null);
method.invoke(gatt.getDevice(), (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
gatt.disconnect();
此外,您可以使用隐藏方法“刷新”刷新gatt服务。最初刷新方法适用于更新gatt服务,但在某些情况下会出现意外断开连接,您可能需要刷新才能正确连接您的gatt服务。
How to programmatically force bluetooth low energy service discovery on Android without using cache
答案 1 :(得分:0)
我的测试表明,这是Android蓝牙堆栈的一个更普遍的问题,GATT连接失败率约为20%,而iOS仅为2%。您可以查看我的详细测试结果here
部分问题是Android BLE链接监管超时在Android 4.3-9中被硬编码为20秒(在Android 10上为5秒,在iOS上为750 ms),因此如果连接断开,大多数Android设备将在20秒钟内无提示地重新连接失败。
但是长链路监管超时仍然不能说明第一次尝试连接失败的可能性很高,或者不能在很短的时间后断开连接。
我发现,以相同的Android设备为中央设备,不同的BLE外设具有不同的GATT连接失败率。我的办公桌上有一台设备,通过它我的Google Pixel 3a可以成功以接近100%的速率连接,并保持该连接数小时。我还有另外两个外围设备,其连接失败率接近20%,并且连接保持的时间不能超过15秒。