我正在构建一个与iBeacons一起使用的应用程序。我正在监视特定的信标,并想知道我的手机何时进入和退出某个区域。进入适当的工作,我知道退出与他们相关的30秒超时。但是,我遇到了一个我只能描述为退出时超时重置的内容。这是一个例子:
第二个例子:
我知道这些信标应该退出,因为我正在使用硬件版本3.2的estimote信标,它可以实现翻转到睡眠模式,因此信标在颠倒时会停止广播。因此,与第二示例的情况一样,即使我分别监视每个信标,也可以在注册退出之前检测到整整一分钟的信标。有没有人知道是否有任何解决方法,或者这只是iOS信标监控中的一个错误?
有趣的是,如果你同时退出超过2个信标,其中一个将在30之后退出,其余的将在30秒后退出,因此Apple能够检测到这些不同的信号无论是UUID,主要还是次要组合,都会单独退出
这是我的程序的基本功能:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:@"B9407F30-F5F8-466E-AFF9-25556B57FE6D" ] identifier:@"beacon"];
[self.locationManager startMonitoringForRegion:region];
[self.locationManager requestStateForRegion:region];
self.view.backgroundColor = [UIColor redColor];
}
- (CLLocationManager *)locationManager {
if (!_locationManager) {
NSLog(@"location manager alloc init");
_locationManager = [[CLLocationManager alloc] init];
[_locationManager requestAlwaysAuthorization];
_locationManager.delegate = self;
}
return _locationManager;
}
#pragma mark - CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(@"didStartMonitoringRegion: %@", region);
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(@"didEnterRegion: %@", region);
if ([region isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
if (beaconRegion.major && beaconRegion.minor) {
NSLog(@"entered specific!");
} else {
NSLog(@"entered the general region!");
NSLog(@"will start Ranging!");
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
}
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(@"didExitRegion: %@", region);
if ([region isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
if (beaconRegion.major && beaconRegion.minor) {
NSLog(@"stop monitoring %@ %@", beaconRegion.major, beaconRegion.minor);
[self.locationManager stopMonitoringForRegion:beaconRegion];
} else {
NSLog(@"will stop ranging on %@", beaconRegion.proximityUUID.UUIDString);
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
}
}
}
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region {
for (CLBeacon *beacon in beacons) {
NSLog(@"ranging %@ %@", beacon.major, beacon.minor);
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beacon.proximityUUID major:beacon.major.shortValue minor:beacon.minor.shortValue identifier:[NSString stringWithFormat:@"%@ %@ %@", beacon.proximityUUID.UUIDString, beacon.major, beacon.minor]];
if (![self.locationManager.monitoredRegions containsObject:beaconRegion]) {
[self.locationManager startMonitoringForRegion:beaconRegion];
}
}
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
NSLog(@"didDetermineStateForRegion %@", region);
}
我正在监视一个特定的UUID,然后当我遇到UUID时,我会开始测试它。然后,我开始监视我在该UUID中遇到的每个特定信标。当我不再遇到任何使用该UUID的信标时,我会停止测距。这个错误对我不利,因为它有效地迫使我延长30秒,我想限制以节省电池
答案 0 :(得分:0)
如果目标是尽快停止测量以节省电池,则无需依赖监控区域退出。相反,您可以简单地为每个检测到的信标维护时间戳。如果上次检测到该信标的时间戳超过过去的X秒,则可以停止测距。如果您愿意,这将允许您将其自定义为甚至不到30秒。
如果你选择走这条路线,你应该注意的一件事是,如果你得到一个RSSI为0的信标的测距回调,那么这表明在最后一个周期没有检测到它。因此,您只需要使用非零RSSI更新回调时间戳。
我意识到这更像是一种解决方法,而不是直接解决您所询问的问题,所以只有在您找不到更直接的解决方案来解决监控区域退出时间差异时,我才会提供此解决方案。