Основное местоположение дает старое местоположение всякий раз, когда исходит из фона

У меня есть менеджер CoreLocation в VC, когда пользователь нажимает кнопку «получить направление», я инициализирую диспетчер местоположения, и приложение открывает направление карты Google с текущим местоположением и некоторым предварительно определенным местоположением пункта назначения.

Вот моя проблема: если приложение не находится в фоновом режиме, текущее местоположение почти всегда верно, но если приложение вызывается из фона в том же VC, и пользователь снова нажимает кнопку «получить направление», текущее местоположение обычно показывает старые местоположения. Короче говоря, меня беспокоит многозадачность, а отметка времени извлеченных местоположений не решила мою проблему.

IBAдействие:

   if ( self.locationManager ) {
        [_locationManager release];
        self.locationManager = nil;
    }
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;

    self.locationTimer = [NSTimer scheduledTimerWithTimeInterval:LOCATION_TIMER target:self selector:@selector(stopUpdatingLocationTimer) userInfo:nil repeats:NO];
    HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
    [self.locationManager startUpdatingLocation]; 

Делегат основного местоположения:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {


NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
NSLog(@"%f",locationAge);
if (locationAge > 3.0) 
    return;

if (newLocation.horizontalAccuracy < 0) 
    return;

if ( self.currentLocation == nil || self.currentLocation.horizontalAccuracy > newLocation.horizontalAccuracy ) {

    self.currentLocation = newLocation;

    if (self.currentLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy) {

        [self stopUpdatingLocations:YES];

    }

}

}


person ubaltaci    schedule 27.12.2011    source источник


Ответы (2)


В вашем примере locationAge является отрицательным представлением количества секунд с момента timestamp из newLocation. Это означает, что locationAge никогда не будет больше 3, и вы эффективно пропускаете каждое обновление через сито.

Установите locationAge следующим образом:

NSTimeInterval locationAge = [newLocation.timestamp timeIntervalSinceNow];
person Mark Adams    schedule 27.12.2011
comment
Марк, я вижу это в примере кода Apple LocateMe, я скопировал: NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; если (locationAge › 5.0) вернуть; Тогда мы говорим, что это неправильно? - person ubaltaci; 28.12.2011
comment
Да, они используют -timeIntervalSinceNow, так что это будет отрицательное значение, которое затем инвертируется дополнительным отрицательным значением. (Мне это кажется совершенно задним числом) Откуда вы знаете, что получаете старые обновления? Вы уверены, что им больше 3 секунд? - person Mark Adams; 28.12.2011
comment
Я уверен на 100%, потому что я тестировал на машине, сначала я открыл приложение и получил правильное направление для какого-то заранее определенного места, затем я проехал примерно 2-2,5 км, затем я снова запускаю приложение (из фонового состояния) и это дает мне неправильное местоположение, которое является старым. Я проверял 3-4 раза так, и все не так. - person ubaltaci; 28.12.2011
comment
Возможно ли, что вы просто видите последнее местоположение перед тем, как приложение уволилось, а новые местоположения не соответствуют ни одному из ваших требований к точности сразу? Вы проверяете на максимальную точность... - person Mark Adams; 28.12.2011
comment
Но я также использую NSTimer для остановки обновления, даже новые местоположения не соответствуют требованиям точности, я присвоил ей переменную currentLocation, как вы видите в фрагменте кода, я ожидаю, по крайней мере, небольших изменений в значениях координат, но мне очень не повезло. - person ubaltaci; 28.12.2011

Для тех, кто столкнулся с такой же проблемой,

Кроме того, некоторые учебные пособия, связанные с основным местоположением в Интернете, привели меня к этой проблеме.

Конечно, я держу CLLocation ivar в своем VC, всякий раз, когда CLLocation ivar устанавливает и вызываются карты Google, мое приложение переходит в фоновый режим.

Затем мое приложение вызывает пользователя из фонового режима и начинает обновлять местоположения,
и старая переменная CLLocation не равна нулю, и, вероятно, лучшая горизонтальная точность, чем новая. Следовательно;

if ( self.currentLocation == nil || self.currentLocation.horizontalAccuracy > newLocation.horizontalAccuracy )

эта строка вызывает проблемы, и старое местоположение в CLLocation ivar никогда не заменяется.

Итак, я изменил viewDidDisappear таким образом, присвоил значение nil переменной CLLocation и отлично работает.

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    [self.locationManager stopUpdatingLocation]; // CLLocationManager
    self.locationManager = nil; 
    [self.locationTimer invalidate]; // NSTimer
    self.locationTimer = nil;
    self.currentLocation = nil; // CLLocation 
}

p.s.: спасибо, Марк Адамс

person ubaltaci    schedule 28.12.2011