2012-02-27 8 views
19

Problema: Sembra che non sia possibile interrompere Core Location dall'invio di aggiornamenti alla mia app/tracciamento.perché self.locationManager stopUpdatingLocation non interrompe l'aggiornamento della posizione

Che cosa sto facendo: Nel mio viewWillAppear chiamo self.locationManager e passarlo a un metodo per mostrare posizione dell'utente sulla mappa (un'istanza di MKMapView). Il getter è sovrascritto per verificare la disponibilità del servizio, per vedere se è autorizzato. Se è così, è allocs/inits e startMonitoringSignificantLocationChanges e returns.

In viewDidDisappear, chiamo [self.locationManager stopUpdatingLocation]. Ma ancora posso vedere l'icona della posizione nella barra di stato. Anche quando interrompo l'app toccando due volte il pulsante Home e chiudendolo, l'icona è ancora lì ... anche dopo un lungo periodo di tempo (più di 10 minuti). Quando apro l'app Impostazioni, mi viene comunicato che la mia app utilizza ancora i servizi di localizzazione (icona viola).

Domanda: Cosa mi manca qui? Perché l'aggiornamento della posizione non si ferma?

Grazie in anticipo.

+0

Se hai due domande (anche se sono correlate) dovresti fare due domande separate. – benzado

+0

Nevermind seconda parte della domanda. L'ho tirato fuori. Ho trovato la risposta. Grazie. – Canopus

+0

[versione Swift] (http://stackoverflow.com/a/42936517/1634890) –

risposta

15

L'opposto di startMonitoringSignificantLocationChanges non è stopUpdatingLocation, è stopMonitoringSignificantLocationChanges.

Probabilmente si desidera sostituire startMonitoringSignificantLocationChanges con startUpdatingLocation per ottenere aggiornamenti più regolari, a meno che non si disponga di un motivo specifico per il monitoraggio solo per modifiche significative della posizione.

Per ulteriori dettagli, consultare lo CLLocation documentation.

+0

Ho provato entrambi. In effetti, è stato stopMonitoringSignificantLocationChanges quando ho scritto il codice per la prima volta, ma poiché non ha smesso di aggiornarlo, l'ho modificato in stopUpdatingLocation. Sto cercando di mostrare la posizione di determinati tipi di attività sulla mappa, quindi ho bisogno solo della posizione dell'utente una volta. Non ho bisogno di seguirlo. – Canopus

+2

Mi piacerebbe ancora utilizzare 'startUpdatingLocation' per il tuo scenario, chiamando' stopUpdatingLocation' nel tuo 'CLLocationManagerDelegate' una volta che hai una posizione con sufficiente accuratezza per le tue esigenze. – jnic

+2

Vedo che questa risposta è stata verificata come corretta. La risposta di jnic è valida, ma sospetto che la risposta che ho fornito di seguito sia quella corretta. – Christopher

11

Anche io ho riscontrato lo stesso problema di Canopus. Sembra che anche se stopUpdatingLocation è chiamato il puntatore di navigazione risiede ancora sulla barra di stato se ho abilitato showUserLocation. Forse questo è un bug? Potrebbe essere come sto correndo e testando con iOS 4.2.1 e questo problema potrebbe essere stato risolto in un successivo SDK.

Penso che se si chiama stopUserLocation si fermerebbe anche a mostrare la posizione dell'utente poiché la vista in cui la sto usando è già scomparsa e successivamente è stata rilasciata.

Sembra che sia necessario impostare showUserLocation su NO prima di interrompere gli aggiornamenti della posizione utente.

In ogni caso, nel mio metodo viewDidLoad Ho il seguente codice:

self.mapView.showsUserLocation = YES; 

Codice a ...

- (void)viewWillDisappear:(BOOL)animated 
{  
    if (locationManager) 
    { 
     mapView.showsUserLocation = NO; 
     [locationManager stopUpdatingLocation]; 
    } 

    [super viewWillDisappear:animated]; 
} 

- (void)dealloc 
{ 
    if (locationManager) 
    { 
     [locationManager release]; 
     locationManager = nil; 
    } 

    (other code) 
} 
+0

Questa risposta ha funzionato per me. –

+0

Anche questo ha funzionato per me! – CainaSouza

+4

Questo perché stopUpdatingLocation dice semplicemente al LocationManager che il tuo locationManager non è più interessato agli aggiornamenti di posizione. mapView ha il proprio locationManager che sta ancora richiedendo aggiornamenti di posizione mentre mostraUserLocation è abilitata. L'hardware GPS non è disattivato finché non c'è più nulla in attesa di aggiornamenti di posizione, quindi l'indicatore rimane acceso. – aranasaurus

2

Ho risolto questa impostazione nil alla proprietà locationManager dopo delegato

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    // Your code getting coordinates 
    //Here set nil 
    locationManager = nil; 

} 
+0

Questo non sarà in grado di impostare locationManager su zero, ho ottenuto un errore di mancata corrispondenza di tipo quando sto cercando di impostare il suo valore su zero. –

+0

Funziona perfettamente su Swift 3, grazie! – cubycode

+0

si prega di mostrare più codice per quanto riguarda locationManager, è una variabile? dove nei documenti dice che dovremmo nominare il manager? –

1

La mia app richiede l'autenticazione "sempre". Solo una determinata funzione all'interno dell'app lo richiede. Se l'utente disattiva la funzione e poi chiude l'app, possiamo interrompere gli aggiornamenti della posizione (con l'obiettivo di risparmiare batteria e rimuovere l'icona della posizione dalla barra di stato). Anch'io pensavo che l'interruzione non funzionasse perché dopo la chiusura dell'app l'icona della posizione nella barra di stato era ancora lì anche se la mia app era l'unica in esecuzione sul mio telefono con accesso alla posizione e "su app close" ho appena detto di smettere di aggiornare le posizioni .

Per me la soluzione era quella di essere un po 'più paziente e poi ho capito che ci vogliono iOS circa 10-15 secondi per spegnere posizione hardware e aggiornare la barra di stato. Non ho dovuto rinunciare al mio responsabile della posizione o a qualcosa di speciale, ho appena interrotto gli aggiornamenti sulla chiusura dell'app, ho aspettato 15 secondi e ho osservato che iOS rimuoveva l'icona della posizione dalla barra di stato. Spero che questo aiuti qualcuno là fuori!

+0

mostrare un codice per favore –

1

Stavo lavorando con CLLocationManager in Swift e penso sia pertinente sia a Swift che a Objective-C ma, ho appena creato un booleano che aggiorno a true ogni volta che ho ricevuto l'aggiornamento di posizione. Dal momento che nel mio caso ho solo bisogno che una volta su lancio .. Esempio,

// my boolean to stop location updates 
var alreadyUpdatedLocation = Bool() 

Inoltre, nel mio caso ho creato una funzione di supporto che ogni volta che ricevo i dati/posizione dell'utente, mi basta chiamare il mio stopUpdatingLocation come questo,

// helper function to stop updates 
func stopUpdationgLocation() { 

    // since I received my data within a block, I don't want to just return whenever it wants to :)  
    dispatch_async(dispatch_get_main_queue()) { 

     // the building stop updating location function call 
     self.locationManager.stopUpdatingLocation() 

     // my own trick to avoid keep getting updates 
     self.alreadyUpdatedLocation = true 

    } 
} 

Poi, dove mai si utilizzano gli aggiornamenti della posizione che avete ricevuto, si potrebbe fare questo ...

// avoiding multiple calls after I have received user location 
if(self.alreadyUpdatedLocation) { 
     return 
} 

Spero che aiuta!

+0

keep cycle trouble ahead –

0

provare questo ..

if ([CLLocationManager significantLocationChangeMonitoringAvailable]) 
      { 
       [self.locationManager startMonitoringSignificantLocationChanges]; 


      } 

[[self locationManager] stopUpdatingLocation]; 
1

Swift:

La mappa E location manager sia bisogno di essere fermato:

override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillDisappear(animated) 
     locationManager.stopMonitoringSignificantLocationChanges()    
     locationManager.stopUpdatingLocation() 
     mapView.showsUserLocation = false 

    } 

È possibile eseguire il debug/controllo servizi di localizzazione utilizzo proprio lì in Xcode, nel navigatore di debug sotto Energy Impact.

+0

Per i miei scopi, spengo anche showUserLocation quando l'app va in background (ascolta per la notifica '.UIApplicationDidEnterBackground') e riaccendilo quando ottengo' .UIApplicationDidBecomeActive' e il viene mostrata la vista ('if self.isViewLoaded && (self.view.window! = nil)'). Nel mio caso, la visualizzazione della mappa utilizzando il GPS è indipendente da quando l'app utilizza il gestore località per altri scopi in primo piano e in background. Su un dispositivo, la posizione "freccia" indica che si spegne dopo circa 10 secondi. – James

0

Se si utilizza le mappe di Google SDK per iOS, ho scoperto che se si chiama

locationManager.stopUpdatingLocation() 

e hanno ancora

mapView.isMyLocationEnabled = true 

quindi l'icona GPS rimane.

Quello che ho scelto di fare è inizialmente mostrare la posizione dell'utente sulla mappa e poi spegnerlo dopo 8 secondi. Questo ha funzionato per me utilizzando l'SDK GoogleMaps. Ho aggiunto questo viewDidLoad:

DispatchQueue.main.asyncAfter(deadline: .now() + 8.0, execute: { 
      self.locationManager.stopUpdatingLocation() 
      self.mapView.isMyLocationEnabled = false 
     }) 

si potrebbe mettere lo stesso codice in viewWillDisappear se si preferisce non avere l'icona del GPS nella barra di stato quando si segue un altro punto di vista.