当外围设备超出范围时,我的应用程序连接低能耗外设,我得到didDisconnect
方法回调,我只需在外围设备上调用连接,只要它回到连接范围内,就会连接。
即使在后台,如果应用程序被iOS暂停,但由于我有待处理的连接,它会唤醒应用并连接。
但是,如果用户关闭蓝牙,则所有外围设备都将进入断开状态,因此没有待处理的连接。如果应用程序被iOS暂停,并且用户在暂停后重新打开它,我的代理方法都没有被调用,我在下面添加了我的初始化和状态恢复方法。
我在后台队列上初始化我的中央管理器,但每当收到回调时,我都会获得执行任务的主队列:
- (void)initialize {
if (!self.centralManager) {
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0) options:@{ CBCentralManagerOptionRestoreIdentifierKey:@"CBCentralManagerIdentifierKey" }];
}
}
我的中央状态回调方法
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
dispatch_async(dispatch_get_main_queue(), ^{
[SFUtil writeLog:@"centralManagerDidUpdateState"];
if (central.state == CBManagerStatePoweredOff) {
[SFUtil writeLog:@"CBManagerStatePoweredOff"];
[[NSNotificationCenter defaultCenter] postNotificationName:CB_MANAGER_BLUETOOTH_POWERED_OFF object:nil];
}
else if (central.state == CBManagerStatePoweredOn) {
[SFUtil writeLog:@"CBManagerStatePoweredOn"];
[self restoreConnections]; // here I reconnect to already known devices, retrieved from calling central method of retrievePeripheralsWithIdentifiers
[[NSNotificationCenter defaultCenter] postNotificationName:CB_MANAGER_BLUETOOTH_POWERED_ON object:nil];
}
});
}
我的中心恢复方法:
- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *, id> *)dict {
dispatch_async(dispatch_get_main_queue(), ^{
[DataManagerInstance startBackgroundTaskIfInBackground]; // Here, I start a background task.
[self initialize];
});
}
当用户重新打开应用程序时,我需要在后台重新连接到外围设备,但是当用户从控制中心或设置重新打开蓝牙时,永远不会调用centralManagerDidUpdateState方法。我无法发送连接电话。
当我手动启动应用程序时,外围设备处于连接状态,但不会重新连接。
答案 0 :(得分:2)
您是否正在监控CBCentralManager
中的状态变化?关闭和打开蓝牙后,您应该获得代理回调,记录here:
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBManagerStatePoweredOn) {
// reconnect/scan/etc
}
}
听起来您正在使用Core Bluetooth State Preservation and Restoration,它应该会通知您这些状态更改。
此外,我现在无法尝试,但是当蓝牙关闭时,您也可以尝试重新连接,因为连接请求不会超时。