Location.HorizontalAccuracy demasiado malo al get location desde el background

Estoy escribiendo una aplicación que supervisa la location del usuario. Tengo un object CLLocationManager que utiliza startMonitoringSignificantLocationChanges, por lo que puedo get actualizaciones de ubicaciones desde el background cuando la aplicación no se está ejecutando. He configurado mi aplicación didFinishLaunchingWithOptions, así que si obtengo una key de location, enciendo a mi administrador para get la location del usuario. Todo funciona bien, pero el problema es que cada vez que obtengo una location del background, la precisión horizontal de esta location es muy mala. En la mayoría de los casos es 1414 m.

¿Alguien sabe por qué la precisión horizontal es tan mala cuando la location proviene del background? ¿Hay algo que pueda hacer para get ubicaciones con mayor precisión en segundo plano?

Cuando la aplicación se está ejecutando, todas las ubicaciones que obtengo son muy precisas, esto solo ocurre cuando la location proviene del background. ¿Tiene eso algo que ver con la cantidad de torres celulares que tengo en mi ciudad? Estaba pensando que tal vez el dispositivo no use gps de nodos wifi para get ubicaciones en segundo plano.

De todos modos, cualquier ayuda aquí es apreciada. Por favor comparta sus pensamientos.

¡Gracias!

La precisión de las ubicaciones devueltas por CLLocationManager está determinada por la desinetworkingAccuracy , que es por defecto, kCLLocationAccuracyBest , y por la precisión disponible del dispositivo. Por ejemplo, puede get ubicaciones less precisas si la batería del dispositivo es baja, o puede get ubicaciones más precisas si aún se almacenan en caching desde otra aplicación.

Sin embargo, get coorderadas increíblemente precisas descarga una cantidad significativa de energía de la batería y drena el dispositivo. Es probable que las aplicaciones en segundo plano estén limitadas a una resolución de resolución mucho menor para mejorar el performance de la batería.

Las ubicaciones precisas requieren mucha potencia para usar la radio GPS, mientras que las ubicaciones less precisas pueden depender de los puntos wifi cercanos y las torres celulares dentro del scope del teléfono.

A medida que la aplicación se reanude desde el background, el sistema tratará de mejorar la precisión de los resultados que obtenga. Es un concepto complicado, pero echa un vistazo a la aplicación Maps en tu teléfono. Al principio, el círculo que representa su location es muy grande; A medida que el sistema obtiene un sentido más preciso de su location, el círculo se vuelve más pequeño. Esta visualización representa el teléfono que usa más energía para get una location más precisa.

Verá un fenómeno similar con CLLocationManager medida que su aplicación se reanude desde el background: obtendrá una location incorrecta y recibirá actualizaciones posteriores más precisas.

Es un compromiso entre la conveniencia y la duración de la batería que Apple tuvo que hacer al diseñar sus API. La primera actualización de la location de un usuario probablemente no sea tan precisa a less que solo esté usando la aplicación Maps y que la location esté almacenada en caching.

El mejor consejo que puedo darle es escuchar las actualizaciones posteriores del administrador de la location y actualizar su UI en consecuencia. ¡Buena suerte!

Como su nombre indica: La notificación startMonitoringSignificantLocationChanges solo está ahí para hacerle saber que la location del usuario es significativamente diferente a la última marcada. Es su trabajo cuando recibe esa Notificación para actualizar su location de acuerdo con la precisión deseada que desee. La notificación no hará eso por usted. Solo va a hacerle saber que la location ha cambiado para que pueda ocuparse de la situación en consecuencia. Si no sabe cómo get una mejor precisión, puede desear ver el código de muestra de Apple para LocateMe. Aquí hay un fragment que almacena la precisión (bestEffortAtLocation) y luego testing la precisión cada vez que se llama al delegado hasta que se obtiene un resultado mejor en o se produce un time de espera .:

 - (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 desinetworking 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 pnetworkingetermined "real" measure of // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout. // if (newLocation.horizontalAccuracy <= locationManager.desinetworkingAccuracy) { // 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(@"Acquinetworking Location", @"Acquinetworking 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 } 

El crédito va a Apple porque este es un fragment directamente de su código de ejemplo LocateMe:

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

Entonces, cuando recibas la notificación y necesites get un resultado mejor, deberás actualizar la precisión y ver si eso te da un mejor resultado.