上下文
我正在构建一个针对 5.0+ 的 Android 应用程序,它使用 BLE 连接到多个外围设备。这些外围设备中的每一个都有许多(~10)个特性。理想情况下,我想订阅这些特征中每一个特征的更改通知。
但是,我从阅读中了解到,Android 的蓝牙实现对可以同时激活的通知数量实现了硬性限制。 This question标识在 Android 蓝牙 implementation 中定义限制的位置,并且还注意到限制是如何随时间变化的:
Max concurrent active notifications (
BTA_GATTC_NOTIF_REG_MAX
):
- 4 on Android 4.3
- 7 on Android 4.4
- 15 on Android 5.0+
这些数字由 Dave Smith 在 video 中确认其中还建议:
- 这些限制对设备是全局的(即,如果其他一些应用订阅了 2 个通知,我的应用可用的通知数量将减少 2 个);
- 这些限制不应因 Android 操作系统级别以外的任何因素而变化(即它们应独立于制造商、实际硬件功能等)
问题
但是,在 5.0+ 设备上进行测试时,我发现我显然能够成功订阅多于 15 个通知。到目前为止,我已经观察到这一点:
- 运行 7.1.1 的 Pixel XL
- 运行 6.0.1 的银河 S6
- 运行 5.X 的 Nexus 5
这些通知订阅通过两种方式获得成功:
- GATT 运行状态为
GATT_SUCCESS
; - 该应用能够从所有目标特征接收有关特征变化的通知。
这是好坏参半的消息。一方面,更多“真实”的通知 ==> 更少的手动轮询 ==> 更好的用户体验。另一方面,无法创建导致“真实”通知设置失败的条件意味着我无法轻松编写或测试手动回退代码,一旦此应用程序发布给真实用户,肯定会(?)需要这些代码。
问题
- 这种忽略限制的行为是预期的吗? (我没能在别处找到它的描述。)
- 是否有任何已知的设备最多只能发送 15 条通知,我可以使用这些设备来测试不愉快的路径?
最佳答案
API 的设计非常糟糕。这个实现使用固定大小的数组而不是动态数组这一事实可能是用 C 语言编写库时的遗留问题。
实际上是内部 C++ 库 returns an error当它无法分配通知条目时。不幸的是,该错误只会被记录下来,不会传播到消费应用程序的 Java 层 (source)。这意味着开发人员无法确定(在代码中)何时达到限制。
无论如何,BTA_GATTC_NOTIF_REG_MAX
限制是针对每个 BluetoothGatt
对象的,因此如果连接了另一个应用程序,它不应干扰您的通知注册。您甚至可以在同一个应用程序中将两个 BluetoothGatt
对象连接到同一个设备,这样可以获得双倍数量的通知注册槽。
插槽的最大数量已定义 here .操作系统级别是唯一定义此值的说法是不正确的,因为制造商可以自由更改此值。例如,我知道三星在他们的一些设备中增加了最大连接数(否则硬编码为 7),因此他们也可能增加了这个值。
我无法解释您是如何在 Google 手机上成功订阅超过 15 条通知的。您是否在单个设备或多台设备上配置了超过 15 个通知?
关于Android 低功耗蓝牙特性通知计数限制 : does this vary by device?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42771904/