核心蓝牙后台广播和扫描

31

我一直在尝试设置一个应用程序,使设备既可以扫描外围设备,又可以作为外围设备进行广告推送。目标是通过蓝牙发现,当两个设备靠近时在后台唤醒它们。根据苹果文档,似乎你应该能够在后台运行BLE(启用蓝牙中心和蓝牙外围后台模式),并且当一个设备在前台时,我的应用程序可以正常工作。 首先,我这样广告推送数据:

NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey:@"my-peripheral",
                              CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:identifier]]};

// Start advertising over BLE
[peripheralManager startAdvertising:advertisingData]; 

然后我将设备设置为扫描数据:

NSArray *services = @[[CBUUID UUIDWithString:identifier]];

[centralManager scanForPeripheralsWithServices:services options:nil];
然而,当两者进入后台(设备必须被锁定)时,蓝牙无法被发现。
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

这个方法在任何设备上都没有被调用。我该怎么解决?谢谢。

3个回答

51

很抱歉,您尝试的操作不起作用。我也曾经尝试过同样的事情。

问题在于前台和后台扫描的差异。当您在前台扫描设备时,可以扫描任何东西。但是在后台,您必须指定要扫描的实际服务UUID。好吧,这其实不是个问题,因为您知道要查找的UUID。

外围设备: 在前台广播作为外围设备与普通的蓝牙外围设备一样。但是在后台,它的空间非常有限,因此外围设备的UUID会被隐藏而不进行广播。只有在中心设备(在前台的iPhone)请求信息时,才会唤醒您的应用程序并显示其UUID。

因此,两者相互抵消。由于后台扫描只能扫描具有特定UUID的设备,而后台外围设备无法广播其UUID,它们彼此无法看到。

您的设备(无论是外围还是中心)中的1个必须处于前台才能工作。

这个问题已经在苹果蓝牙邮件列表上讨论过多次。


3
谢谢Darren。这非常不幸,而且苹果公司没有更清楚地说明这一点令人有些沮丧。你知道有没有任何解决方法可以在两个设备上后台使用BLE吗?此外,你知道为什么当我的iPhone处于锁屏状态时(并在手机上做其他事情而不是在应用程序中),扫描仍然有效吗?我认为这被视为后台行为,因此不会工作? - Kyle Rosenbluth
1
您可以在此处阅读更多信息:https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html#//apple_ref/doc/uid/TP40013257-CH7-SW1,它提到了UUID的“特殊溢出区”。 - Darren
1
据我所知,这方面没有任何解决办法。我有两个应用想法,需要用到这个,但我花了一周的时间尝试让它工作,却没有成功。在后台运行时能否找到,有时会命中,有时会失误。这取决于设备正在进行哪些操作。此外,如果您以前连接过该外围设备,则也会影响事情的进行。 - Darren
只是补充一下,如果您继续使用前台模式来运行某个设备的项目,请务必使用CoreBluetooth中的恢复模式,以便使中心/外设始终可用。 - Darren
1
为什么这个回答被踩了?它可能不是人们想要的答案,但它是正确的! - Darren
显示剩余5条评论

8

你需要详细说明你是如何测试的,因为从理论上看它应该是有效的。你可能会面临两个主要问题:

1.) 当 iOS 设备处于后台时,扫描速度会变慢。

  • 当在前台进行扫描时,设备很可能会立即发现旁边正在广告的另一个设备,但后台发现可能需要长达 ~60 倍的时间。iOS 系统不会假定用户更喜欢某个 app 拥有比其他 app 更好的 Bluetooth 功能(或者仅有一个 app 想要使用它)。由于这是共享功能,他们希望用户在各种 app 中有统一的体验。你可以查看 技术规范 以更好地了解苹果公司在底层所做的事情。

2.) 在进入后台之前,你的设备可能已经相互发现过了。

  • 我们必须记得,当我们进入后台时,Apple 会禁用 CBCentralManagerScanOptionAllowDuplicatesKey 扫描标志。由于你甚至没有指定此标志,它默认值为 NO。所以,如果它们甚至已经相互发现过一次,当它们在后台时,你将不会得到另一个回调。

1
谢谢您的回复。我测试应用程序的方法是在我的iPad mini上运行它,锁定iPad,然后走大约200英尺。然后将其加载到我的iPhone上。在iPhone上,将应用程序置于前台(插入计算机并在didDiscoverPeripheral处设置断点),然后开始向前走,直到触发断点。然后,我将此过程重复一遍,但将应用程序置于后台并锁定iPhone。XCode没有中断点。令人惊讶的是,如果我进入锁定屏幕,则会立即触发断点。关于您提到的两个问题,我无法看出我的方法存在问题。有任何想法吗? - Kyle Rosenbluth
2
@KyleRosenbluth 我正在测试类似的东西,只是通过打开和关闭蓝牙来实现。 - vaughan

5

我个人需要这样的功能,因此我开发了一个开源组件:https://github.com/omergul123/Discovery

如果您想在对等应用程序在后台运行时交换ID,则该组件可能非常有用。


1
当中央设备和外围设备都在后台运行时,这是否有效? - JamesPlayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接