2015-09-07 63 views
1

我在应用程序中进行背景位置跟踪,并且它常常发射方式。我不确定设置更新位置的最小时间间隔的最佳技术是什么。我只想每2分钟左右保存一次位置数据。有人说使用NSTimer,但我不知道如何或在哪里将其纳入当前的代码。以下是我在AppDelegate中的所有位置跟踪代码,是否有人知道用于降低位置更新频率的最佳技术,因为我的当前代码是?iOS:降低背景位置更新的频率

- (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"); 
} 

此外,由于很多我在做什么是由各种教程编译,欢迎指出任何事情我做不正确地在性能和电池使用条款。谢谢!

回答

3

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

  • 降低要求的精度(setDesiredAccuracy)非常大的(不是“kCLLocationAccuracyBest”,但实际上“kCLLocationAccuracyKilometer”)
  • 减少回调“didUpdateLocations:”通过在“distanceFilter”设定大的阈值计数从回调
  • 返回如果不需要写入(与其他标准,如时间)

任何方式,我没有看到这里需要额外的计时器。你想要做的就是从粗略的精度开始(如果可以的话),并且另外将distanceFilter设置为较高的值(例如超过10米)。

你可以额外做的是这样的:在你的“didUpdateLocations:”回调中,如果“lastSaveTime”大于5分钟前if(lastSaveTime + 5 < thisSaveTime) { ... }假设时间以秒为单位进行测量,则只调用“saveLocation”。

+0

感谢额外的建议,我已经改变了desiredAccuracy到kCLLocationAccuracyTenMeters并增加从10 distanceFilter至30题约lastSaveTime:我没有这一点,所以你建议我创建一个NSTimer最后保存时间或NSUserDefaults中的一些NSDate变量上次保存时间? –

+0

嗨,你不一定需要一个计时器:你基本上只是使用一个时间间隔来衡量两次后续回调之间经过了多少时间。看到这个:http://stackoverflow.com/questions/4371757/how-can-i-calculate-the-difference-between-two-dates –

+0

好吧,可能对内存/电池使用征税反正。我将保存一个NSDate到最后保存日期的NSUserDefaults,然后返回,如果它少于几分钟。 –

1

正如你已经宣布你

-(void) initializeRegionMonitoring 

距离过滤器的值,以10

self.locationManager.distanceFilter = 10; 

因此,在用户移动10米,你didUpdateLocations将被调用,

如果您想最小化此代理方法的调用,那么您必须增加distanceFilter的值。

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

试试这个.... !!

+0

嗨PJ,你的答案出现在低质量答案审查队列中。请更新您的答案,更好地解释您的代码的确切功能。另外,请阅读[回答] –

0
  1. 当用户移动并在 位置停止服务时启动服务。精确度低于locatonManager的准确度。
  2. 位置管理器应该自动暂停&尝试使用简历 位置委托。

  3. 检查上次位置和新位置的时间。

  4. 这会减少一些电池。