如何每 5 秒或当用户移动阈值而不耗尽电池时获得高精度位置?
Posted
技术标签:
【中文标题】如何每 5 秒或当用户移动阈值而不耗尽电池时获得高精度位置?【英文标题】:How can I get high accuracy location every 5 seconds or when user moves a threshold without draining the battery? 【发布时间】:2016-08-25 03:17:43 【问题描述】:我有一个需要定期获取准确位置的定位应用。目前,我不断在didUpdateLocation
中获取位置,但我只每 5 秒记录一次位置。我对定期或在含义变化时获得准确位置的解决方案感兴趣。我想要以下两种情况之一或两种情况:
(非常准确,我需要 10m 的所需精度)
该应用程序也需要在后台运行,并且如果用户切换到另一个应用程序,仍必须记录位置。
我曾考虑每 5 秒打开/关闭一次定位,但不确定这是否是最佳做法。我也知道还有allowDeferredLocationUpdatesUntilTraveled
,但我相信它只适用于后台模式。我希望有一个解决方案可以在应用程序正在使用和后台模式下节省电池。请分享您针对我的用例的解决方案和最佳实践。
【问题讨论】:
【参考方案1】:我确实使用定位服务编写了一个应用程序,应用程序必须每 10 秒发送一次位置信息。而且效果很好。
只需按照 Apple 的文档使用 "allowDeferredLocationUpdatesUntilTraveled:timeout" 方法即可。
步骤如下:
必需:为更新位置注册后台模式。
创建 LocationManger 和 startUpdatingLocation,准确度和过滤距离随心所欲:
-(void) initLocationManager
// Create the manager object
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
_locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
_locationManager.desiredAccuracy = 45;
_locationManager.distanceFilter = 100;
// Once configured, the location manager must be "started".
[_locationManager startUpdatingLocation];
要让应用在后台使用“allowDeferredLocationUpdatesUntilTraveled:timeout”方法永远运行,您必须在应用移至后台时使用新参数重新启动updateLocation,如下所示:
- (void)applicationWillResignActive:(UIApplication *)application
_isBackgroundMode = YES;
[_locationManager stopUpdatingLocation];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[_locationManager setDistanceFilter:kCLDistanceFilterNone];
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[_locationManager startUpdatingLocation];
应用程序通过“locationManager:didUpdateLocations:”回调正常获取更新位置:
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
// store data
CLLocation *newLocation = [locations lastObject];
self.userLocation = newLocation;
//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];
但是您应该根据您的目的处理“locationManager:didFinishDeferredUpdatesWithError:”回调中的数据
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error
_deferringUpdates = NO;
//do something
注意:我认为每次应用在后台/前台模式之间切换时,我们都应该重置 LocationManager 的参数。
希望这会有所帮助
【讨论】:
您是否还需要在 applicationWillEnterForeground 等某处设置 _isBackgroundMode = NO? 当然根据你的需要改变它以上是关于如何每 5 秒或当用户移动阈值而不耗尽电池时获得高精度位置?的主要内容,如果未能解决你的问题,请参考以下文章