iOS:降低后台位置更新的频率

时间:2015-09-07 14:32:52

标签: ios objective-c cllocationmanager cllocation

我正在应用中进行背景位置跟踪,并且它经常发射。我不确定设置更新位置的最短时间间隔的最佳技巧是什么。我只想每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");
}

此外,由于我正在做的很多是从各种教程编译,请随时指出我在性能或电池使用方面做错的事情。谢谢!

4 个答案:

答案 0 :(得分:4)

在其他(开源)项目中,我看到了以下策略来节省电力:

  • 请求的准确度(setDesiredAccuracy)非常大(不是" kCLLocationAccuracyBest",但实际上" kCLLocationAccuracyKilometer")
  • 减少回调" didUpdateLocations:"通过在" distanceFilter"
  • 中设置一个较大的阈值来计数
  • 如果不需要写入(使用其他条件,如时间),则从回调返回

任何方式我都不认为这里需要额外的计时器。您想要做的是从粗略的准确性开始(如果可以!)并另外将distanceFilter设置为较高的值(例如,超过10米)。

你还可以做的是:在你的&#34; didUpdateLocations:&#34;回调,让&#34; saveLocation&#34;只有在&#34; lastSaveTime&#34;超过5分钟前​​if(lastSaveTime + 5 < thisSaveTime) { ... }假设时间以秒为单位。

答案 1 :(得分:1)

正如您在

中声明的那样
-(void) initializeRegionMonitoring

距离过滤器的值为10

self.locationManager.distanceFilter = 10;

因此,在用户移动到10米后,您的didUpdateLocations将被调用,

如果您想最小化此委托方法的调用,则必须增加distanceFilter的值。

答案 2 :(得分:0)

  1. 当用户移动并在何时停止服务时启动服务 地点。准确度低于locatonManager的准确度。
  2. 位置管理员应自动暂停&amp;尝试使用简历 地点代表。

  3. 检查最后位置和新位置的时间。

  4. 这会减少一些电池。

答案 3 :(得分:-1)

self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
[self.locationManager startUpdatingLocation];

试试这个.... !!