连续扫描iOS CoreBluetooth Central Manager?

时间:2013-05-16 01:19:58

标签: ios bluetooth core-bluetooth bluetooth-lowenergy peripherals

低能耗蓝牙规范并未说明外设是否可以一次连接到多个中心,但我的测试经验告诉我他们不能。

因为我的应用程序需要与外围设备的非占有关系(即没有连接,这会阻止其他连接),并且需要不断更新其RSSI值,我正在寻找一种方法来连续扫描外设并捕获它们的RSSI值。

scanForPeripheralsWithServices方法似乎扫描一定的间隔然后停止。我相信我最好的选择是一次扫描3秒,stopScan,等待(几秒钟),然后重新开始扫描。重复。

有人能指出更好的方法吗?例如,配置外围设备以连接到多个Central?

3 个答案:

答案 0 :(得分:8)

外围设备无法连接到多个中心。但是如果你需要捕获RSSI,那么你甚至不需要连接。扫描设备可以使用此功能检索RSSI:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

答案 1 :(得分:5)

至于上一个答案,如果您只对RSSI感兴趣,可以直接将其纳入委托方法:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

BTW,默认情况下CBCentralManager只会调用此方法一次。如果每次CBCentralManager收到广告数据包时都需要调用此回调,则需要使用设置为CBCentralManagerScanOptionAllowDuplicatesKey的选项YES启动扫描:

NSDictionary *scanningOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey: @YES};
[centralManager scanForPeripheralsWithServices:nil options:scanningOptions];

请注意,如果没有严格要求,Apple会阻止使用此选项。

请参阅:iOS Developer Library -Best Practices for Interacting with a Remote Peripheral Device

答案 2 :(得分:1)

我用这段代码解决了这类问题,基本上只是在每次处理广告时重新启动扫描。我遇到了同样的问题,CBCentralManager实例会停止收听外围设备。

(将CBCentralManagerScanOptionAllowDuplicatesKey设为@YES并未完全解决问题。)

假设该类实现了CBCentralManagerDelegate:

- (id) init {
    self.central = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
    [self initScan];
}

- (void) initScan {
    [self.central stopScan];
    [self.central scanForPeripheralsWithServices:nil
                                         options:[NSDictionary dictionaryWithObjectsAndKeys:@NO, CBCentralManagerScanOptionAllowDuplicatesKey, nil]];
}

- (void) centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI {

    //
    // Do stuff here
    //

    [self initScan];
}