如果先连接其他应用程序,CoreBluetooth 不会发现心率监视器

CoreBluetooth not discovering hear-trate monitor if other app is connected first

我希望我的用户能够使用我的应用程序跟踪他们的心率。所以我为此使用 CBCentralManager 。如果没有其他应用程序连接到心率传感器,一切正常。我遇到的问题是如果我开始 f.e。首先是 Strava 或 Endomondo。然后我再也找不到任何设备了。反过来一切都很好,所以我想我在某处缺少一个选项?

我目前在做什么:

我像这样实例化我的 CBCentralManager

centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)

这将导致连接的委托方法被触发

 func centralManagerDidUpdateState(_ central: CBCentralManager) {

    let heartRateServiceUUID = CBUUID(string: "180D")
    let services = [heartRateServiceUUID]

    switch central.state {

    case .poweredOn:
        centralManager.scanForPeripherals(withServices: services, options: nil)

从那以后没有找到外围设备。

但是,当我强行退出其他应用程序(如 Endomondo 或 Strava)然后启动我的应用程序时,一切正常。

更新: 看起来 BLE4.0 芯片组只支持一个连接,所以当 centralmanager 连接到 BLE4.0 设备时,它停止广播并建立连接层。

BLE4.1 芯片组增加了对多角色连接的支持。心率传感器可能使用支持多个连接的更新 BLE 技术。 https://e2e.ti.com/blogs_/b/connecting_wirelessly/archive/2016/11/30/bluetooth-low-energy-multi-role-demystified

目前还不清楚为什么您的应用程序无法在其他应用程序已连接的情况下连接。你能 post 你所有的代码吗?

我的旧答案: "Core bluetooth and Bluetooth Low Energy can only handle one connection for each peripheral which means that if your app(CBCentralManager) establish a connection with a peripheral(UUID) it establish a message layer between the central and peripheral so other apps cant interfere the connection to that peripheral unless you disconnect the first app. This is how Bluetooth Low Energy works."

Apple 指南和示例: https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html#//apple_ref/doc/uid/TP40013257-CH1-SW1

苹果核心蓝牙API: https://developer.apple.com/reference/corebluetooth

好的,我刚刚自己找到了主要问题的解决方案。所以任何可能有同样问题的人:

  1. 连接到设备后,请记住它的 UUID
  2. 当你想重新连接时不需要扫描,只需使用centralManager.retrievePeripherals(withIdentifiers: [the id's of the devices you know])
  3. 这会给你一个 CBPeripherals 的列表,你可以像搜索它们一样简单地连接到它们。

唯一我还不知道的是: 即使我卸载 Endomondo,首先启动我的应用程序,他们仍然可以发现我的心率监测器......我想即使他们记得 UUID,我想它也会在 UserDefaults 中,所以他们无法使用 centralManager.retrievePeripherals(...)。所以我仍然想知道我需要改变什么才能让它发挥作用...

有关如何连接到您已知的设备的完整详细信息,请参阅 Best Practices For Interacting With A Remote Peripheral Device

您遇到的主要问题是大多数 BLE 设备在建立连接后会停止广播。由于它们不是广告,因此您无法在扫描中看到它们。在这种特殊情况下,BLE 设备连接到您 运行 所在的 iPhone,但这不会改变任何东西。还不是打广告。

为了解决这个问题,您需要使用 retrieveConnectedPeripherals(withServices:) 向 iPhone 询问具有您所需服务的已连接设备。这是一个非常快速的同步调用,您通常应该在调用 scan​For​Peripherals(with​Services:​options:​).

之前执行此操作

您通常还应该执行其他几个步骤。精确的顺序和逻辑在一定程度上取决于您的情况,但上面链接的流程图将引导您完成一种方法。基本上它看起来像这样:

  • 调用 retrieve​Peripherals(with​Identifiers:​) 查找您已知其标识符的外围设备。请注意,这只是告诉您系统知道外围设备;这并不意味着它目前就在附近。对其调用 connect 可能永远不会成功。

  • 调用 retrieveConnectedPeripherals(withServices:) 查找已连接到此 iPhone 的外围设备并通告您的服务。您仍然需要为您的流程调用 connect,但它应该会成功。

  • 如果全部失败,则调用scan​For​Peripherals(with​Services:​options:​)