在应用程序暂停后重新打开蓝牙无线电不会调用centralManagerDidUpdateState [英] Turning bluetooth radio back on after the app is suspended doesn't call centralManagerDidUpdateState

查看:1019
本文介绍了在应用程序暂停后重新打开蓝牙无线电不会调用centralManagerDidUpdateState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当外围设备超出范围时,我的应用程序与低能耗外围设备连接,我得到didDisconnect方法回调,我只是在外围设备上调用connect,只要它回到范围内就进行连接.

My app connects with a low energy peripheral when the peripheral goes out of range, I get didDisconnect method callback, I simply call connect on the peripheral and whenever it comes back into range it connects.

即使在后台,如果该应用已被iOS暂停,但由于我有待处理的连接,它也会唤醒该应用并进行连接.

Even in the background, if the app is suspended the by the iOS but since I have a pending connection, it wakes the app up and connects.

但是,如果用户关闭蓝牙,则所有外围设备都将处于断开状态,因此不会保留任何待处理的连接.如果该应用已被iOS暂停,并且用户在暂停后将其重新打开,则没有调用我的委托方法,我在下面添加了初始化和状态恢复方法.

However, if the user turns the Bluetooth off, all the peripherals go into disconnected state, hence no pending connection remains. If the app is suspended by the iOS, and the user turns it back on after suspension, none of my delegate methods are called, I have added my initialization and state restoration methods below.

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

I initialize my central manager on background queue but whenever I receive a callback, I get the main queue to execute tasks:

- (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方法.我无法发送连接呼叫.

I need to reconnect to the peripheral in the background when user reopens the app, but since centralManagerDidUpdateState method is never call when user turns the bluetooth back on from control centre or from settings. I cannot send the connect call.

当我手动启动该应用程序时,外围设备处于连接状态,但没有重新连接.

When I manually launch the app, peripheral is in connecting state but doesn't reconnect.

推荐答案

您是否正在监视CBCentralManager中的状态更改?开启和关闭蓝牙时,您应该得到委托回调,记录在这里:

Are you monitoring for state changes in the CBCentralManager? You should get a delegate callback when Bluetooth is turned off and on, documented here:

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

听起来您正在使用核心蓝牙

It sounds like you are using Core Bluetooth State Preservation and Restoration, which is supposed to notify you on these state changes.

此外,我现在无法尝试,但是由于连接请求不会超时,您可能还可以在蓝牙关闭时尝试重新连接.

Also, I can't try it out right now, but you might be able to also attempt-reconnect when bluetooth is off since connect requests do not time out.

这篇关于在应用程序暂停后重新打开蓝牙无线电不会调用centralManagerDidUpdateState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆