CoreBluetooth stop 广告不停止

Posted

技术标签:

【中文标题】CoreBluetooth stop 广告不停止【英文标题】:CoreBluetooth stopadvertising does not stop 【发布时间】:2018-07-29 00:43:51 【问题描述】:

我有一个使用 CoreBluetooth 的 ios 应用。

既能做广告,又能连线就好了。

当我在外设管理器对象上调用 stopAdvertising 时,它不会停止广告。我等了大约 10 分钟,它仍然显示在我的蓝牙文件扫描仪中,我仍然可以连接到它。

我的 iPhone 是装有最新软件的 iPhone X。

我没有发现任何可以检测到的错误,并且 isAdvertising 保持正确。

有人知道为什么它不会停止广告吗?

【问题讨论】:

请编辑您的问题以显示相关代码,但猜测您没有在 CBPeripheralManager 的正确实例上调用 stopAdvertising 好吧,我不确定现在发生了什么。我将调试代码放入外围管理器对象的 NSLog 并运行了一些测试,它似乎在我的简单测试中停止了广告。看起来它可能与连接/断开连接有关。我确实验证了同一个外围管理器对象是我调用停止广告的对象。当我有更多信息时,我会做更多的测试并回到这篇文章。 我也看到过同样的事情。你有没有找到答案?我在 iPhone 7 和 Xr 之间进行测试。 还注意到,如果您重新启动手机,会暂时自行修复。我可以按预期开始广告和停止广告。但最终,问题又回来了。 【参考方案1】:

根据我在 iOS 上使用 GATT 的经验,我注意到在调用 stopAdvertising 方法后,我也必须调用 removeAllServices 方法(它只删除官方文档 here 中提到的您的服务)。

但是,如果有任何客户端扫描我的 GATT 服务器或连接到它,我必须等待他们停止观看它以使其不再被发现。

【讨论】:

【参考方案2】:

我有类似的经验,当应用程序处于前台时,启动和停止广告效果很好。为了遇到问题,我需要执行以下操作:

    在前台启动广告 将应用置于后台 将应用置于前台

此时广告包长这样:


    kCBAdvDataHashedServiceUUIDs =     (
        <my service UUID>
    );
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataRxPrimaryPHY = 0;
    kCBAdvDataRxSecondaryPHY = 0;
    kCBAdvDataServiceUUIDs =     (
        <my service UUID>
    );
    kCBAdvDataTimestamp = "617105621.560463";
    kCBAdvDataTxPowerLevel = 12;

其中kCBAdvDataHashedServiceUUIDs 字符串是CBAdvertisementDataOverflowServiceUUIDsKey 常量。因此,广告包在服务和溢出区域中都包含广告服务 UUID。 此时,如果我停止广告,广告包就会变成背景中的那个(我在第 2 步后观察到的一样)


    kCBAdvDataHashedServiceUUIDs =     (
        <my service UUID>
    );
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataRxPrimaryPHY = 0;
    kCBAdvDataRxSecondaryPHY = 0;
    kCBAdvDataTimestamp = "617105621.560463";
    kCBAdvDataTxPowerLevel = 12;

此时,扫描我的 UUID 的 iOS 应用将通过 centralManager:didDiscoverPeripheral:advertisementData:RSSI: 回调方法接收通知。

如果我在广告应用程序中杀掉广告应用程序,我也会遇到同样的情况。

几点说明:

isAdvertising 报告了正确的值(所以当我停止广告时,即使存在我刚才描述的问题,它也会报告 NO) 我尝试了类似 Darion Badlydone 建议的清理方法 从设置中停用和激活蓝牙可修复广告问题

【讨论】:

【参考方案3】:

嗯,这个问题已经讨论了很多。我也将此作为错误报告给 Apple,但他们似乎并没有积极改变这一点。 这个问题的原因是你iphone中的所有应用程序共享同一个overflowserviceuuid区域,包括你iphone设置中的默认蓝牙。这意味着如果您的应用程序覆盖 GATT 堆栈中的溢出区域(通过移动到后台),即使您杀死您的应用程序,此 uuid 也会生效,因为您的默认蓝牙仍在使用此共享溢出区域工作,这就是其他手机的原因会找到你的。 此外,解决此问题的解决方法很少,具体取决于业务场景。

【讨论】:

那么,这些解决方法是什么?对问题背景的分析很有趣,但不是(完整的)解决方案。 我有一个几乎完整的解决方案,适用于 android 和 iOS 设备,甚至适用于可穿戴设备,但有以下限制:1. 电池消耗 2. Appstore 审计 3. 您可以在后台进行联系人跟踪但是从iOS14开始你不能自动打开/关闭该功能。只需宣传一项新的特殊服务即可再次覆盖溢出。 你可以edit你的答案来改进它,不要把那种信息放在评论里。不过,这里回答的目的是帮助他人解决问题。请仅在您实际上可以分享更具体的内容时才写答案。【参考方案4】:

您无法停止广告是因为您曾经将应用程序置于后台状态,这将覆盖溢出区域。即使您调用 stopAdvertising 它也会停止前台广告。然而,正如我所说,由于所有应用程序共享相同的溢出区域,该区域将保持广告(默认蓝牙设置)。为了解决这个问题,当您调用 stopadvertising 时,您必须使用另一个无意义的 uuid(如 0001)再次覆盖 GATT 堆栈。

【讨论】:

以上是关于CoreBluetooth stop 广告不停止的主要内容,如果未能解决你的问题,请参考以下文章

CoreBluetooth 发现外设广告数据格式

使用 AltBeacon 库以 CoreBluetooth 格式做广告

CoreBluetooth 广告,但无法从其他设备看到

iPhone 4S 上的 Corebluetooth 故障?

如何正确停止线程

在后台使用 iBeacon 或 CoreBluetooth 识别 iOS 设备