我想做的是:iPhone处于睡眠状态,后台位置管理器正在扫描beaconRegion。在后台,位置管理器正在扫描一个beaconRegion。如果这个区域被识别,我的应用程序应该开始进行信标测距,以验证与信标的距离。当离开该区域时,信标测距应该停止。
所以这是我的代码。
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region
{
NSLog(@"********** Beacon Region entered: %@", region);
self.locationManager.allowsBackgroundLocationUpdates = YES;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
[self doBeaconRanging:(CLBeaconRegion *)region];
}
-(void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray<CLBeacon *> *)beacons
inRegion:(CLBeaconRegion *)region
{
NSLog(@"locationManager didRangeBeacons inRegion.");
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations {
NSLog(@"locationManager didUpdateLocations");
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLRegion *)region
{
NSLog(@"********** Beacon Region left **********");
[self.locationManager stopUpdatingLocation];
NSSet *regions = [self.locationManager monitoredRegions];
for(CLBeaconRegion *region in regions)
{
[self.locationManager stopRangingBeaconsInRegion:region];
}
}
当应用程序在前台输入区域时,这很好用, didEnterRegion被触发,信标测距开始。即使我把应用程序和iPhone进入睡眠状态,信标测距也会一直持续下去(只是为了测试,在真实的应用程序中,我将在大约3分钟后停止信标测距)。
但是,当 didEnterRegion 在 iPhone 锁定时被启动时,行为就不同了。位置更新和信标测距开始,但只有约10秒。10秒。10秒后,iPhone回到睡眠状态,位置更新和信标测距停止。当我唤醒应用程序时,位置更新立即开始,信标测距也是如此。但当然,我不想唤醒应用程序。一切都应该在后台运行,而不需要打开应用程序。
如果我在应用处于前台时启动位置更新,并且从未停止过,那么一切都会很好。即使在后台运行几个小时后,位置更新也一直在进行。但我认为由于电池寿命的原因,这是没有办法的。
如何才能在应用程序处于后台时,当didEnteredRegion被触发时开始更新位置?
默认情况下,iOS上的信标测距更新在后台被阻止,除了这些事件之一后的前10秒。
除上述情况外,还可以通过启动后台任务,将这些事件发生后允许后台测距的时间从10秒延长到30秒(iOS 12及更早版本为180秒)。
最后,您可以通过在Info.plist中额外声明一个位置背景模式,并使用CoreLocation来调用以下功能,将30秒的时间延长到无限期。startUpdatingLocation
. 位置更新上的3公里精度足以让测距无限期的进行下去,而不至于用GPS烧电池。
请注意,如果你在Info.plist中声明背景位置,你可能会有麻烦获得AppStore的批准,除非你正在构建一个看似导航的应用程序。 同时要注意,持续的后台定位会消耗大量的电池,尽管比持续使用GPS要少。