ios - 应用程序暂停后重新打开蓝牙 radio 不会调用centralManagerDidUpdateState

标签 ios objective-c bluetooth-lowenergy core-bluetooth

我的应用程序与低能耗外围设备连接。当外设超出范围时,我会收到 didDisconnect 方法回调,我只需在外设上调用 connect 即可,只要它回到范围内就会连接。

即使在后台,即使应用程序被 iOS 挂起,但由于我有一个挂起的连接,它会唤醒应用程序并连接。

但是,如果用户关闭蓝牙,所有外围设备都会进入断开状态,因此不会保留挂起的连接。如果应用程序被 iOS 暂停,并且用户在暂停后将其重新打开,则不会调用我的委托(delegate)方法,我在下面添加了初始化和状态恢复方法。

我在后台队列上初始化中央管理器,但每当我收到回调时,我都会让主队列执行任务:

- (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方法,因此我无法发送连接调用。

当我手动启动应用程序时,外围设备处于连接状态,但不会重新连接。

最佳答案

您是否正在监视 CBCentralManager 中的状态更改?当蓝牙关闭和打开时,您应该收到委托(delegate)回调,记录为 here :

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    if (central.state == CBManagerStatePoweredOn) {
        // reconnect/scan/etc
    }
}

听起来您正在使用核心蓝牙 State Preservation and Restoration ,它应该通知您这些状态更改。

此外,我现在无法尝试,但您也可以在蓝牙关闭时尝试重新连接,因为连接请求不会超时。

关于ios - 应用程序暂停后重新打开蓝牙 radio 不会调用centralManagerDidUpdateState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48030480/

相关文章:

ios - uibuttontypedetaildisclosure 自定义图像

android - 以编程方式绑定(bind)到 Android 上的 BLE 设备

java - 获取Android中蓝牙适配器的MAC地址

ios - ASIHTTPREQUEST 无内容长度响应(大型 PDF 文件)

ios - 如何在标题文本和表格 View 之间添加空格

ios - CADisplayLink iOS有什么用

ios - viewWillTransitionToSize 导致非旋转 View Controller 调整大小和重新定位

objective-c - 在没有 NSApplication 实例的情况下拥有 Mac OS X 应用程序是否可以?

ios - 将 UIButton 的触摸限制在指定区域

ios - 在 iOS 模拟器中测试蓝牙