2012-03-21 8 views
8

Estoy escribiendo una aplicación que supervisa la ubicación del usuario. Tengo un objeto CLLocationManager que usa startMonitoringSignificantLocationChanges, por lo que puedo obtener actualizaciones de ubicaciones desde el fondo cuando la aplicación no se está ejecutando. Configuré mi aplicación didFinishLaunchingWithOptions, de modo que si obtengo una clave de ubicación, enciendo mi administrador para obtener la ubicación del usuario. Todo funciona bien, pero el problema es que cada vez que obtengo una ubicación del fondo, la precisión horizontal de esta ubicación es muy mala. En la mayoría de los casos es 1414 m.Location.HorizontalAccuracy demasiado malo al obtener la ubicación desde el fondo

¿Alguien sabe por qué la precisión horizontal es tan mala cuando la ubicación proviene del fondo? ¿Hay algo que pueda hacer para obtener ubicaciones con una mayor precisión en el fondo?

Cuando la aplicación se ejecuta todas las ubicaciones que obtengo son muy precisas, esto solo ocurre cuando la ubicación proviene del fondo. ¿Tiene 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 obtener ubicaciones en segundo plano.

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

Gracias!

+0

La investigación de alguien más aquí http://longweekendmobile.com/2010/07/22/iphone-background-gps-accurate-to-500-meters-not-enough-for-foot-traffic/ menciona "CLLocationManager tiene una tendencia a reportar eventos múltiples en un lapso de tiempo muy corto, incluso en el fondo (con menos de 10 segundos de diferencia) ... el segundo evento sería mucho más preciso que el primero " –

+0

Brian gracias por el enlace. Había información muy útil allí. Mencionaron allí que una ubicación es exacta a 500 metros cuando se obtiene desde el fondo, pero eso depende de la ciudad donde se encuentre. He estado probando mi aplicación aquí en Brasilia, Brasil, y la mejor precisión que he obtenido hasta ahora fue de 1200 m. –

Respuesta

11

La precisión de las ubicaciones devueltas por CLLocationManager viene determinada por el desiredAccuracy, que es por defecto, kCLLocationAccuracyBest, y por la precisión disponible del dispositivo. Por ejemplo, puede obtener ubicaciones menos precisas si la batería del dispositivo es baja, o puede obtener ubicaciones más precisas si todavía están en la memoria caché de otra aplicación.

Sin embargo, obtener coordenadas increíblemente precisas consume una cantidad significativa de energía de la batería y va a drenar el dispositivo. Las aplicaciones en segundo plano están probablemente limitadas a una resolución de precisión mucho menor para mejorar el rendimiento de la batería.

Las ubicaciones precisas requieren una gran cantidad de energía para usar la radio GPS, mientras que las ubicaciones menos precisas pueden confiar en las zonas Wi-Fi cercanas y las torres de telefonía móvil que se encuentran dentro del alcance del teléfono.

Como su aplicación se reanuda desde el fondo, el sistema intentará mejorar la precisión de los resultados que obtenga. Es un concepto complicado, pero eche un vistazo a la aplicación Maps en su teléfono. Al principio, el círculo que representa tu ubicación es muy grande; a medida que el sistema adquiera un sentido más preciso de su ubicación, el círculo se volverá más pequeño. Esta visualización representa el teléfono que usa más potencia para obtener una ubicación más precisa.

Verás un fenómeno similar con CLLocationManager mientras tu aplicación se reanuda desde el fondo: obtendrás una ubicación incorrecta y recibirás actualizaciones posteriores más precisas.

Es un compromiso entre la comodidad y la duración de la batería que Apple tuvo que hacer al diseñar sus API. La primera actualización de la ubicación de un usuario probablemente no sea tan precisa a menos que solo estuvieran usando la aplicación Mapas y la ubicación esté en la memoria caché.

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

9

Como su nombre indica: La notificación startMonitoringSignificantLocationChanges está solo allí para hacerle saber que la ubicación del usuario es significativamente diferente de la última marcada. Cuando reciba esa Notificación, actualizará su ubicación según la precisión deseada que desee. La notificación no lo hará por usted.Solo le informará que la ubicación ha cambiado para que pueda manejar la situación en consecuencia. Si no sabe cómo obtener una mayor precisión, puede consultar el código de muestra de Apple para LocateMe. Aquí hay un fragmento que almacena la precisión (bestEffortAtLocation) y luego prueba la precisión cada vez que se llama al delegado hasta que llega un mejor resultado en o se produce un tiempo 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 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 
} 

el crédito va a Apple porque este es un fragmento de recta de su LocateMe código de ejemplo:

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

Así que cuando llegue a la notificación y la necesidad Para obtener un mejor resultado, deberá actualizar la precisión y ver si eso le da un mejor resultado. t.

+0

Hubert, gracias por la respuesta. Este es en realidad el código exacto que estoy usando en mi aplicación, y funciona bien con la aplicación en ejecución. Pero si está en el fondo sigo probando la precisión cada vez que se llama al delegado, pero esa precisión siempre es mala. Creo que lo que Ash dijo aquí es correcto. Cuando la aplicación está en segundo plano, el teléfono no usará el GPS para recuperar la ubicación a fin de ahorrar batería, y la precisión de una ubicación obtenida solo desde una torre de telefonía móvil es mala, al menos en mi ciudad. Tal vez en una ciudad con más torres celulares disponibles, esta precisión podría ser un poco mejor. –

+0

Me complace que haya encontrado útil mi consejo: debería considerar marcarlo como una respuesta aceptada. –

Cuestiones relacionadas