Location.Hor HorizontalAcraracy слишком плохо при получении местоположения из фона - PullRequest
9 голосов
/ 21 марта 2012

Я пишу приложение, которое отслеживает местоположение пользователя.У меня есть объект CLLocationManager, который использует startMonitoringSignificantLocationChanges, поэтому я могу получать обновления местоположений из фона, когда приложение не запущено.Я настроил свое приложение didFinishLaunchingWithOptions, поэтому, если я получаю ключ местоположения, я запускаю своего менеджера, чтобы узнать местоположение пользователя.Все работает нормально, но проблема в том, что каждый раз, когда я получаю местоположение из фона, Точность по горизонтали для этого местоположения очень плохая.В большинстве случаев это 1414 м.

Кто-нибудь знает, почему горизонтальная точность настолько плоха, когда местоположение исходит из фона?Могу ли я что-нибудь сделать, чтобы получить местоположения с большей точностью в фоновом режиме?

Когда приложение работает, все местоположения, которые я получаю, очень точные, это происходит только тогда, когда местоположение происходит из фона.Это как-то связано с количеством вышек сотовой связи, которые у меня есть в моем городе?Я подумал, может быть, устройство не использует GPS узлов Wi-Fi, чтобы получить местоположение в фоновом режиме.

В любом случае, любая помощь здесь приветствуется.Пожалуйста, поделитесь своими мыслями.

Спасибо!

Ответы [ 2 ]

14 голосов
/ 25 марта 2012

Точность местоположений, возвращаемых CLLocationManager, определяется desiredAccuracy, который по умолчанию равен kCLLocationAccuracyBest, и доступной точностью устройства. Например, вы можете получить менее точные местоположения, если батарея устройства разряжена, или вы можете получить более точные местоположения, если они все еще кэшируются из другого приложения.

Однако получение невероятно точных координат разряжает значительную часть энергии аккумулятора и разряжает устройство. Приложения в фоновом режиме, вероятно, ограничены гораздо более низким разрешением точности для улучшения характеристик батареи.

Точные местоположения требуют большого количества энергии для использования радио GPS, в то время как менее точные местоположения могут полагаться на близлежащие точки доступа Wi-Fi и вышки сотовой связи в пределах досягаемости телефона.

Когда ваше приложение возобновит работу в фоновом режиме, система попытается повысить точность результатов, которые вы получите. Это сложная концепция, но взгляните на приложение «Карты» на вашем телефоне. Сначала круг, представляющий ваше местоположение, очень большой; по мере того, как система получает более точное представление о вашем местоположении, круг становится меньше. Эта визуализация показывает, что телефон использует больше энергии, чтобы получить более точное местоположение.

Вы увидите аналогичное явление с CLLocationManager, когда ваше приложение возобновит работу в фоновом режиме: вы получите неточное местоположение и получите последующие, более точные обновления.

Это компромисс между удобством и временем автономной работы, который Apple пришлось искать при разработке своих API. Первое обновление местоположения пользователя, вероятно, будет не таким точным, если только оно не использует приложение «Карты» и местоположение не будет кэшировано.

Лучший совет, который я могу вам дать, - выслушать последующие обновления от менеджера местоположений и соответственно обновить ваш пользовательский интерфейс. Удачи!

9 голосов
/ 30 марта 2012

Как следует из названия: уведомление startMonitoringSignificantLocationChanges предназначено только для того, чтобы вы знали, что местоположение пользователя значительно отличается от последнего проверенного.Это ваша работа, когда вы получаете это уведомление, чтобы обновить ваше местоположение в соответствии с желаемой точностью. Уведомление не сделает это для вас.Он только сообщит вам, что местоположение изменилось, чтобы вы могли соответственно справиться с ситуацией.Если вы не знаете, как получить более высокую точность, вы можете проверить пример кода Apple для LocateMe. Вот фрагмент, в котором хранится точность (bestEffortAtLocation), затем проверяется точность каждый раз, когда делегат вызывается, пока не будет получен лучший результат.или истекло время ожидания .:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    // store all of the measurements, just so we can see what kind of data we might receive
    [locationMeasurements addObject:newLocation];
    // test the age of the location measurement to determine if the measurement is cached
    // in most cases you will not want to rely on cached measurements
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
    if (locationAge > 5.0) return;
    // test that the horizontal accuracy does not indicate an invalid measurement
    if (newLocation.horizontalAccuracy < 0) return;
    // test the measurement to see if it is more accurate than the previous measurement
    if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
        // store the location as the "best effort"
        self.bestEffortAtLocation = newLocation;
        // test the measurement to see if it meets the desired accuracy
        //
        // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
        // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
        // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
        //
        if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
            // we have a measurement that meets our requirements, so we can stop updating the location
            // 
            // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
            //
            [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")];
            // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
        }
    }
    // update the display with the new location data
} 

Кредит предоставляется Apple, потому что это фрагмент кода непосредственно из их образца кода LocateMe:

http://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801-Intro-DontLinkElementID_2

Поэтому, когда вы получаете уведомление и хотите получить лучший результат, вам нужно обновить точность и посмотреть, даст ли это лучший результат.

...