如何仅使用 CoreBluetooth 扫描信标

Posted

技术标签:

【中文标题】如何仅使用 CoreBluetooth 扫描信标【英文标题】:How to scan only for beacons with CoreBluetooth 【发布时间】:2018-03-06 15:39:31 【问题描述】:

我使用此功能扫描周围的 BLE,但接收到的信号过多。我只想处理来自信标的信号。

func centralManagerDidUpdateState(_ central: CBCentralManager) 
    centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])

I had used LightBlue 发现我的信标有 5 个服务:180A、FFA0、FFB0、FFF0 和 180F。

然后我尝试了这段代码,但没有找到该服务的外围设备。

let serviceUUIDs = [CBUUID(string: "FFA0")]

func centralManagerDidUpdateState(_ central: CBCentralManager) 
    centralManager.scanForPeripherals(withServices: serviceUUIDs, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])

而且 didDiscover 方法从未被调用

func centralManager(_ central: CBCentralManager,
                    didDiscover peripheral: CBPeripheral,
                    advertisementData: [String : Any],
                    rssi: NSNumber)

    if peripheral.name == "MY_BEACON_NAME" 
        print("peripheral: \(peripheral)")
        print("rssi = \(rssi)")
    

我做错了什么?

P。 S. 我不能在这个项目中使用 CoreLocation,只能使用 CoreBluetooth。

【问题讨论】:

第一次尝试...scanForPeripherals(withServices: nil,...) 有效吗?第二个,不,那是你的问题?然后...scanForPeripherals(withServices: serviceUUIDs...) 仅在它宣传该服务时才有效。换句话说,一个设备可以有各种服务,但它不必做广告。要知道他们宣传的是哪一个,请使用“nil”进行扫描,并在didDiscover 委托方法中记录advertisementData。它应该显示它实际宣传的服务。 【参考方案1】:

根据您的硬件信标所宣传的信标格式,可能无法使用 CoreBluetooth 进行检测。 CoreBluetooth 可以检测 Eddystone 格式和 AltBeacon 格式,但无法检测 iBeacon 格式。

需要理解的几点:

    信标格式不一定包含 GATT 服务 UUID,这是您在使用代码行 centralManager.scanForPeripherals(withServices: serviceUUIDs ... 时要过滤的内容。虽然 Eddystone 广告确实包含服务 UUID,但 iBeacon 和 AltBeacon 不包含,因为它们是一种不同类型的 BLE 广告,称为制造商广告。只有 GATT 广告具有服务 UUID。

    Eddystone 格式使用 FEAA 服务 UUID,您可以使用您描述的技术来过滤此信标类型。

    您只能检测没有 serviceUUID 过滤器的 AltBeacon 广告,因为它没有。

    您可以永远使用 CoreBluetooth 检测 iBeacon,因为 Apple 有特殊的代码过滤器可以阻止其 API 接收这些广告。您别无选择,只能在 ios 上使用 CoreLocation 进行 iBeacon 检测。

    许多信标硬件制造商还包括一些具有自己的服务 UUID 的补充 GATT 服务。这些服务执行配置或添加操作等功能。但是这些与信标功能无关,并且无法知道何时(如果有的话)这些服务 UUID 被广告,以及它们是否意味着什么。这些 UUID 绝对不同于一个信标制造商与下一个制造商。 LightBlue 检测到的服务 UUID 可能是补充服务,因此它们根本无助于解决此问题。

底线:没有简单的方法可以使用 CoreBluetooth 仅过滤您想要的信标。最好的办法是在 CoreBluetooth 之上编写自己的过滤软件,然后简单地忽略您不关心的数据包。

【讨论】:

感谢您的回答!据我所知,对于 android 应用程序,我们可以编写自己的过滤器并使用字节进行过滤,但是如何在 iOS 中做到这一点?我应该从哪里开始? 不幸的是,由于我上面描述的原因,您根本无法在 iOS 上为 iBeacon 和 AltBeacon 执行此操作。您只能对 Eddystone 信标执行此操作。 所以我什至不能为 iBeacon 和 AltBeacon 在 iOS 的 CB 之上编写自己的过滤器? 对不起,没有。与 Android 不同,iOS 没有 CoreBluetooth API 来公开蓝牙扫描过滤器(尽管 CoreLocation 确实在内部使用它们)。当然,您可以在委托回调中构建自己的软件过滤器。但这基本上只是一个忽略不想要的模式的 case 或 if 语句。

以上是关于如何仅使用 CoreBluetooth 扫描信标的主要内容,如果未能解决你的问题,请参考以下文章

CoreBluetooth 监控 100 个具有相同 UUID 且具有唯一输入的信标

当我使用我的 Android 设备作为使用 AltBeacon 的 ibeacon 时找不到 CoreBluetooth

信标测距与 BLE 扫描

如何停止信标监控

如何使用 android-beacon-library (altbeacon) 正确停止扫描信标

如何判断 CLLocationManager 是不是正在主动扫描信标?