我正在开发一个测试 BTLE 应用程序。用户可以选择启动中央或外围模式。如果 2 个设备都处于活动状态并且在范围内,它们会立即检测、连接和传递数据,但是......
如果 device1 在中心模式下启动,然后进入后台,则 device2 将超出范围并进入外围模式,当外围设备靠近后台中心时,中心检测外围设备并获取数据。
如果 device1 以外围模式启动并置于后台,则 device2 会超出范围并置于中央模式,然后进入范围,它不会检测到外围设备。(我最多等了 5 分钟)如果我再次按下“启动中央”按钮,它会立即检测到!
“启动中心”仅执行以下操作:
-(id)init{
if (self=[super init]) {
dispatch_queue_t peripheralQueue=dispatch_queue_create("com.Dev.peripheralQueue", 0);
dispatch_queue_t centralQueue=dispatch_queue_create("com.Dev.centralQueue", 0);
// Initiate Managers with restore keys for background mode
self.centralManager=[[CBCentralManager alloc]initWithDelegate:self
queue:centralQueue
options:@{CBCentralManagerOptionRestoreIdentifierKey: CM_RESTORE_KEY}];
self.peripheralManager=[[CBPeripheralManager alloc]initWithDelegate:self
queue:peripheralQueue
options:@{CBPeripheralManagerOptionRestoreIdentifierKey: PM_RESTORE_KEY}];
// 1. create The UUIDs
// 2. create the service and characteristics
//service is alloc/inited and published in did update state
}
return self;
}
-(void)switchToCentral
{
NSLog(@"BTM switchToCentral");
[self.peripheralManager stopAdvertising];
[self scan];
self.isCentral = YES;
}
- (void)scan
{
[self.centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]
options:@{ CBCentralManagerScanOptionAllowDuplicatesKey:@NO}];
NSLog(@"CM Scanning started");
}
我添加了以下可耻的 hack:
-(void)switchToCentral
{
NSLog(@"BTM switchToCentral");
[self stopBroadcasting];
[self scan];
self.isCentral = YES;
dispatch_async(dispatch_get_main_queue(), ^{
[NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(centralShouldRescan:)
userInfo:nil
repeats:YES];
});
}
-(void)centralShouldRescan:(NSTimer*)timer{
NSLog(@"BTM centralShouldRescan");
if (self.isCentral) {
NSLog(@"BTM centralShouldRescan isCentral");
[self stopBroadcasting];
[self scan];
}else{
NSLog(@"BTM centralShouldRescan isCentral");
[timer invalidate];
}
}
现在它可以工作了!我对此感到茫然。根据我的理解和经验,当 CBCentral 管理器开始扫描时,它会一直扫描直到停止,尤其是在前台时。