APP进入后台后,蓝牙扫描必须指明servicesId
NSArray *servicesArray = @[[CBUUID UUIDWithString:D_Transfer_Service_UUID]];
[self.centralManager scanForPeripheralsWithServices:servicesArray
options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @(YES)}];
- 当APP处于前台时,如果第一个参数设置成nil,那么centralManager会返回所有被发现的外设,否则,只有有广播这些uuid服务的外设才会被返回;
- 当APP处于后台时,如果第一个参数为nil,那么centralManager不会返回任何外设,因此如果你希望你的APP支持蓝牙后台运行,那么你需要设置明确的servicesId
APP进入后台后,只能扫描到广播包扫不到扫描包
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
- 外设进行广播时,广播内容包括广播包和扫描包
- 当APP处于前台时,蓝牙可以扫到外设广播的全部内容,即:advertisementData实际上整合了外设广播的广播包和扫描包
- 当APP处于后台时,蓝牙只能扫到外设广播的广播包,扫不到扫描包,即:advertisementData只包含广播包内容,所以如果你的APP需要支持后台运行,那么你需要告知嵌入式工程师把广播内容全部放到广播包中
外设名称更改后,扫描到的仍然是旧的名称
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
假设外设初始名称为WatchName-A,你用WatchName-A进行了扫描连接,然后嵌入式工程师把外设名称更改为WatchName-B,你再次扫描时会发现你扫描到的设备名仍然是WatchName-A,这时无论你重启手机蓝牙还是重启手机都会发现设备名依然是WatchName-A,因此如果你在发现设备后通过[peripheral.name isEqualToString:@"WatchName-B"]
来确定你的设备,你将会错误的认为外设坏了没有进行广播,因此更安全的方法是你通过广播包中的名称来确定你的设备名,即:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
NSData *manufacturerData = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey];
NSString *name = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if ([name isEqualToString:@"WatchName-B"] || [peripheral.name isEqualToString:@"WatchName-B"]) {
...
}
...
}
网友评论