2015-09-07 4 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:» позвольте вызывать «saveLocation» только в том случае, если «lastSaveTime» более 5 минут назад if(lastSaveTime + 5 < thisSaveTime) { ... }, предполагая время, измеренное в секундах.

+0

Спасибо за дополнительные предложения, я изменил desiredAccuracy к kCLLocationAccuracyTenMeters и увеличил distanceFilter от 10 до 30. Вопрос о lastSaveTime: у меня нет, что, таким образом вы предлагаете мне создать NSTimer для последнего сохранения времени или некоторой переменной NSDate в NSUserDefaults в последний раз, когда она была сохранена? –

+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]; 

Try This .... !!

+0

Привет, PJ, ваш ответ появился в очереди обзора ответов низкого качества. Пожалуйста, обновите свой ответ, чтобы лучше объяснить, что именно делает ваш код. Кроме того, пожалуйста, прочитайте [ответ] –

0
  1. Запустить услугу, когда пользователь перемещает и останавливает обслуживание, когда . Точность меньше, чем точность locatonManager.
  2. Администратор местоположения должен автоматически приостанавливаться & попытаться использовать резюме мест делегировать.

  3. Проверить время последнего местонахождения и новое место.

  4. Это уменьшит заряд батареи.

Смежные вопросы