iOS: 降低后台位置更新频率
iOS: Decrease frequency of background location updates
我正在一个应用程序中进行后台位置跟踪,但它触发得太频繁了。我不确定设置更新位置的最小时间间隔的最佳技术是什么。我只想每 2 分钟左右保存一次位置数据。有人说要使用 NSTimer,但我不确定如何或在何处将其合并到我当前的代码中。下面是我在 AppDelegate 中的所有位置跟踪代码,有人知道根据我当前的代码降低位置更新频率的最佳技术吗?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
{
isBackgroundMode = NO;
_deferringUpdates = NO;
self.locationManager = [CLLocationManager new];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
[self initializeRegionMonitoring];
}
-(void) initializeRegionMonitoring {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// notify changes when the device has moved x meters
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self saveLocation];
//tell the centralManager that you want to deferred this updatedLocation
if (isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:60];
}
}
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
}
-(void) saveLocation {
// save information database/ communication with web service
}
- (void)applicationWillResignActive:(UIApplication *)application {
isBackgroundMode = YES;
[self.locationManager stopUpdatingLocation];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[self.locationManager startUpdatingLocation];
}
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return true;
}
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[self saveLocation];
completionHandler(UIBackgroundFetchResultNewData);
NSLog(@"Fetch completed");
}
此外,由于我所做的很多工作都是从各种教程中编译而来的,请随时指出我在性能或电池使用方面做错的任何事情。谢谢!
在其他(开源)项目中,我看到了以下节能策略:
- 将要求的精度 (setDesiredAccuracy) 降低很多(不是 "kCLLocationAccuracyBest",但实际上是 "kCLLocationAccuracyKilometer")
- 通过在 "distanceFilter"
中设置较大的阈值来减少回调 "didUpdateLocations:" 计数
- Return 如果不需要写入(使用其他条件,例如时间),则来自回调
无论如何,我认为这里不需要额外的计时器。你想要做的是从一个粗略的精度开始(如果可以的话!),另外将你的 distanceFilter 设置为一个高值(例如超过 10 米)。
您还可以做的是:在您的 "didUpdateLocations:" 回调中,仅当 "lastSaveTime" 超过 5 分钟前才调用 "saveLocation" 假设 if(lastSaveTime + 5 < thisSaveTime) { ... }
以秒为单位的时间。
正如您在
中声明的那样
-(void) initializeRegionMonitoring
距离过滤器的值到 10
self.locationManager.distanceFilter = 10;
因此,当用户移动到 10 米后,您的 didUpdateLocations
将被调用,
如果你想尽量减少这个委托方法的调用,那么你就得增加distanceFilter
的值。
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
试试这个....!!
- 当用户移动时启动服务,当用户移动时停止服务
地点。精度低于 locatonManager 的精度。
位置管理器应自动暂停并尝试使用恢复
地点代表。
检查上次位置和新位置的时间。
这会减少一些电量。
我正在一个应用程序中进行后台位置跟踪,但它触发得太频繁了。我不确定设置更新位置的最小时间间隔的最佳技术是什么。我只想每 2 分钟左右保存一次位置数据。有人说要使用 NSTimer,但我不确定如何或在何处将其合并到我当前的代码中。下面是我在 AppDelegate 中的所有位置跟踪代码,有人知道根据我当前的代码降低位置更新频率的最佳技术吗?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
{
isBackgroundMode = NO;
_deferringUpdates = NO;
self.locationManager = [CLLocationManager new];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
[self initializeRegionMonitoring];
}
-(void) initializeRegionMonitoring {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// notify changes when the device has moved x meters
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self saveLocation];
//tell the centralManager that you want to deferred this updatedLocation
if (isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:60];
}
}
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
}
-(void) saveLocation {
// save information database/ communication with web service
}
- (void)applicationWillResignActive:(UIApplication *)application {
isBackgroundMode = YES;
[self.locationManager stopUpdatingLocation];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[self.locationManager startUpdatingLocation];
}
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return true;
}
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[self saveLocation];
completionHandler(UIBackgroundFetchResultNewData);
NSLog(@"Fetch completed");
}
此外,由于我所做的很多工作都是从各种教程中编译而来的,请随时指出我在性能或电池使用方面做错的任何事情。谢谢!
在其他(开源)项目中,我看到了以下节能策略:
- 将要求的精度 (setDesiredAccuracy) 降低很多(不是 "kCLLocationAccuracyBest",但实际上是 "kCLLocationAccuracyKilometer")
- 通过在 "distanceFilter" 中设置较大的阈值来减少回调 "didUpdateLocations:" 计数
- Return 如果不需要写入(使用其他条件,例如时间),则来自回调
无论如何,我认为这里不需要额外的计时器。你想要做的是从一个粗略的精度开始(如果可以的话!),另外将你的 distanceFilter 设置为一个高值(例如超过 10 米)。
您还可以做的是:在您的 "didUpdateLocations:" 回调中,仅当 "lastSaveTime" 超过 5 分钟前才调用 "saveLocation" 假设 if(lastSaveTime + 5 < thisSaveTime) { ... }
以秒为单位的时间。
正如您在
中声明的那样-(void) initializeRegionMonitoring
距离过滤器的值到 10
self.locationManager.distanceFilter = 10;
因此,当用户移动到 10 米后,您的 didUpdateLocations
将被调用,
如果你想尽量减少这个委托方法的调用,那么你就得增加distanceFilter
的值。
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
试试这个....!!
- 当用户移动时启动服务,当用户移动时停止服务 地点。精度低于 locatonManager 的精度。
位置管理器应自动暂停并尝试使用恢复 地点代表。
检查上次位置和新位置的时间。
这会减少一些电量。