2012-03-21 6 views
8

Sto scrivendo un'app che monitora la posizione dell'utente. Ho un oggetto CLLocationManager che utilizza startMonitoringSignificantLocationChanges, quindi posso ottenere gli aggiornamenti delle posizioni dallo sfondo quando l'app non è in esecuzione. Ho impostato la mia applicazione suFinishLaunchingWithOptions, quindi se ottengo una chiave di posizione, accendo il mio gestore per ottenere la posizione dell'utente. Tutto funziona bene, ma il problema è che ogni volta che ottengo una posizione dallo sfondo, l'accuratezza orizzontale di questa posizione è pessima. Nella maggior parte dei casi è 1414 m.Location.HorizontalAccuratezza eccessiva quando si ottiene la posizione dallo sfondo

Qualcuno sa perché la precisione orizzontale è così grave quando la posizione viene dallo sfondo? C'è qualcosa che posso fare per ottenere posizioni con una maggiore accuratezza in background?

Quando l'app è in esecuzione, tutte le posizioni che ottengo sono molto accurate, questo accade solo quando la posizione viene dallo sfondo. Questo ha qualcosa a che fare con il numero di torri cellulari che ho nella mia città? Stavo pensando che forse il dispositivo non utilizza gps di nodi wifi per ottenere posizioni in background.

In ogni caso, qualsiasi aiuto qui è apprezzato. Per favore condividi i tuoi pensieri.

Grazie!

+0

La ricerca di qualcun altro qui http://longweekendmobile.com/2010/07/22/iphone-background-gps-accurate-to-500-meters-not-enough-for-foot-traffic/ menzioni "CLLocationManager ha un tendenza a segnalare più eventi in un brevissimo arco di tempo, anche in background (meno di 10 secondi di distanza) ... il secondo evento sarebbe molto più preciso del primo " –

+0

Brian grazie per il link. C'erano alcune informazioni molto utili lì. Hanno menzionato che una posizione è precisa a 500m quando viene acquisita dallo sfondo, ma dipende dalla città in cui ti trovi. Ho testato la mia app qui a Brasilia, in Brasile, e la precisione migliore che ho ottenuto finora è stata di 1200m. –

risposta

11

L'accuratezza delle posizioni restituite da CLLocationManager è determinata dallo desiredAccuracy, che è l'impostazione predefinita, kCLLocationAccuracyBest, e dalla precisione disponibile del dispositivo. Ad esempio, potresti ottenere posizioni meno precise se la batteria del dispositivo è scarica o potresti ottenere posizioni più precise se sono ancora memorizzate nella cache da un'altra app.

Tuttavia, ottenendo coordinate incredibilmente accurate drena una notevole quantità di energia dalla batteria e scarica il dispositivo. Le applicazioni in background sono probabilmente limitate a una risoluzione di precisione molto più bassa per migliorare le prestazioni della batteria.

Le posizioni precise richiedono molta potenza per utilizzare la radio GPS, mentre posizioni meno precise possono fare affidamento su hotspot Wi-Fi nelle vicinanze e sulle torri cellulari nel raggio di portata del telefono.

Mentre l'applicazione riprende dallo sfondo, il sistema cercherà di migliorare la precisione dei risultati ottenuti. È un concetto complicato, ma dai un'occhiata all'applicazione Maps sul tuo telefono. All'inizio, il cerchio che rappresenta la tua posizione è molto grande; poiché il sistema ottiene un senso più preciso della tua posizione, il cerchio diventa più piccolo. Questa visualizzazione rappresenta il telefono che utilizza più energia per ottenere una posizione più precisa.

Vedrai un fenomeno simile con CLLocationManager mentre la tua app riprende dallo sfondo: riceverai una posizione inaccurata e riceverai aggiornamenti successivi più accurati.

È un compromesso tra la convenienza e la durata della batteria che Apple ha dovuto effettuare durante la progettazione delle proprie API. Il primo aggiornamento alla posizione di un utente probabilmente non sarà così accurato a meno che non stessero semplicemente utilizzando l'applicazione Maps e il percorso sia memorizzato nella cache.

Il miglior consiglio che posso darti è quello di ascoltare gli aggiornamenti successivi dal responsabile della posizione e aggiornare di conseguenza l'interfaccia utente. In bocca al lupo!

9

Come dice il nome: La notifica startMonitoringSignificantLocationChanges è solo lì per farti sapere che la posizione dell'utente è significativamente diversa dall'ultima selezionata. È il tuo lavoro quando ricevi la notifica per aggiornare la tua posizione in base alla precisione desiderata che desideri. La notifica non lo farà per te.Ti farà solo sapere che la posizione è cambiata in modo da poter gestire la situazione di conseguenza. Se non sai come ottenere una migliore accuratezza potresti voler controllare il codice di esempio di Apple per LocateMe.Qui è uno snippet che memorizza la precisione (bestEffortAtLocation) quindi verifica l'accuratezza ogni volta che viene chiamato il delegato fino a quando non si ottiene un risultato migliore o si verifica un timeout .:

- (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 
} 

il merito va ad Apple perché questo è un frammento direttamente dal loro LocateMe codice di esempio:

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

Così, quando si ottiene la notifica e la necessità per ottenere un risultato migliore è necessario aggiornare la precisione e vedere se questo ti dà un risultato migliore t.

+0

Hubert, grazie per la risposta. Questo è in realtà il codice esatto che sto utilizzando nella mia app e funziona perfettamente con l'applicazione in esecuzione. Ma mentre è in sottofondo continuo a testare per la precisione ogni volta che viene chiamato il delegato, ma quell'accuratezza è sempre negativa. Penso che quello che Ash ha detto qui sia giusto. Quando l'app è in background, il telefono non usa il GPS per recuperare la posizione per risparmiare batteria, e l'accuratezza di una posizione ottenuta da una torre cellulare è pessima, almeno nella mia città. Forse in una città con più torri cellulari disponibili questa precisione potrebbe essere un po 'meglio. –

+0

Sono felice che tu abbia trovato utile il mio consiglio: dovresti considerare di contrassegnarlo come una risposta accettata. –

Problemi correlati