Android BLE 堆栈缓存服务?

问题描述

我正在开发第一个低功耗蓝牙应用。我控制着两端——服务器在 Arduino Nano 33 BLE 上运行——它有一个 nRF 芯片组。

服务器有点奇怪 - 它实际上运行两组代码中的一组,具体取决于它的启动方式(主要是因为我只有一个 Nano BLE)。所以它可以是两个服务器中的一个(相同的 MAC 地址),但服务器 A 支持一个服务及其特征集,服务器 B 支持一个具有其特征的服务。两种服务显然都有唯一的 UUID。

问题是,当应用程序已连接到 - 比如说 - A,并且服务器关闭并以伪装 B 重新打开时,在连接和发现服务时,应用程序仍然“发现”A 服务 UUID,而不是 B。

反复重启服务器没有任何区别,在 Android 设备上禁用和重新启用蓝牙,或重新启动应用程序也没有区别。唯一有效的是完全重启 Android 设备。

在我看来,BLE 堆栈正在缓存它认为特定服务器 MAC 地址的功能

无法找到解决方法(不要认为我可以更改 Nano BLE MAC 地址),但是当我运行 nRF 诊断 Android 应用程序时,它确实找到了正确的服务,因此必须是可能的。不过这样做总是先经过 BLE 扫描过程,因此可能会刷新任何缓存。

但是,我真的不想强制执行扫描,因此非常感谢您提供任何评论或有关如何清除任何缓存的详细信息。

解决方法

停止按下:

找到了一个答案:'Android Bluetooth not discovering the characteristic after changing UUID'

似乎 BLE 堆栈会在不确定的时间内缓存服务等,以加快未来的服务发现。如果 MAC 地址的服务确实发生了变化(就像我的一样),那就有点问题了,但我认为这不是真正预期的行为(尽管据我所知并没有被禁止)。不知道缓存了多长时间,但我注意到它在一夜之间自行解决了 - 当然,然后在下一次更改时出错了。

有一个内部 BluetoothGatt.refresh() 方法可以清除缓存 - 但它没有发布。该链接显示了如何通过反射来实现它,它似乎确实有效。在运行 6.0.1 的旧 Nexus 7 2013 上,就是这样。不确定以后的操作系统,因为这些天谷歌似乎不赞成反射。即将在运行 Android 11 的 Pixel 2 上试用。