2016-02-17 19 views
10

Ho sviluppato un'applicazione che viene utilizzata per trovare la posizione corrente del dispositivo. Ho usato Fused Location API per ottenere la posizione corrente.Applicazione che riceve posizione errata fino all'applicazione di Google Maps incorporata incorporata

Mi trovo di fronte a un problema molto strano, in alcuni dispositivi non riesco a ottenere la posizione attuale accurata fino a quando non apro Google Map, una volta che apro Google Map e di nuovo alla mia applicazione in quel momento l'applicazione restituisce la posizione esatta.

Ecco la mia richiesta di posizione.

mLocationRequest = new LocationRequest(); 
mLocationRequest.setInterval(UPDATE_INTERVAL); 
mLocationRequest.setFastestInterval(FATEST_INTERVAL); 
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
mLocationRequest.setSmallestDisplacement(DISPLACEMENT); // 10 meters 

Qualcuno può dirmi che cosa è sbagliato? Il tuo aiuto è molto apprezzato.

+0

Qual è il tuo LocationRequest? –

+3

Dai, hai 33k punti. Dovrei indovinare i valori concreti? Per favore mettilo nella domanda non nei commenti. L'alta precisione è stata abilitata nelle impostazioni del telefono? Quanti aggiornamenti di posizione hai ricevuto? Su quali dispositivi hai provato? Qual è la versione della libreria GMS utilizzata? Tutto ciò che puoi pensare aiuta. –

+1

Stato membro da 5 anni, codice postinng ancora presente nei commenti. Oh boy ... – 2Dee

risposta

3

Così Waze e abbiamo usato FusedLocation in passato e abbiamo affrontato un sacco di problemi. L'API è interrotta. Ci sono alcuni dispositivi che non lo perfezionano correttamente. Riconoscimento di attività che ha fuso un relè molto non funzionante e riconosce il personale correttamente. Terminiamo, per tornare all'API di Location Manager.

Qui il frammento:

Init location manager e iniziare a richiedere gli aggiornamenti sul thread diverso. Io personalmente registrare ascoltatori separate per ogni fornitore

if (mLocationManager == null) { 
     LOGGER.info("Location track,start called first time. Creating Location Manager"); 
     mLocationManager = (LocationManager) mContextWeakReference.get() 
       .getSystemService(Context.LOCATION_SERVICE); 

     mLocationHandlerThread 
       = new HandlerThread("LocationThread", Thread.NORM_PRIORITY); 
     mLocationHandlerThread.start(); 
     // Now get the Looper from the HandlerThread 
     // NOTE: This call will block until the HandlerThread gets control and initializes its Looper 
     Looper looper = mLocationHandlerThread.getLooper(); 
     Location networkLastKnownLocation = null; 
     Location gpsLastKnownLocation = null; 
     mGpsLocationListener = new GpsLocationListener(); 
     mNetworkLocationListener = new NetworkLocationListener(); 

     // Register the listener with the Location Manager to receive location updates 
     if (mLocationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER)) { 
      mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
        LOCATION_REQUEST_INTERVAL_MILLIS, SMALLEST_DISPLACEMENT_METERS, 
        mGpsLocationListener, 
        looper); 

      gpsLastKnownLocation = mLocationManager 
        .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     } else { 
      setGpsProviderAvailable(false); 
     } 
     if (mLocationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER)) { 
      networkLastKnownLocation = mLocationManager 
        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
        LOCATION_REQUEST_INTERVAL_MILLIS, SMALLEST_DISPLACEMENT_METERS, 
        mNetworkLocationListener, 
        looper); 
     } 

     setLastKnownLocationDifferentProviders(gpsLastKnownLocation, 
       networkLastKnownLocation); 

    } 

E gli ascoltatori sono:

public class GpsLocationListener implements LocationListener { 

    @Override 
    public void onLocationChanged(Location location) { 
     LOGGER.info("Location track ,onLocationChanged location={}", location); 
     switch (location.getProvider()) { 
      case LocationManager.GPS_PROVIDER: 
       if (mLocationManager != null) { 
        mLocationManager.removeUpdates(mNetworkLocationListener); 
       } 
       break; 
     } 
     setLastKnownLocation(location); 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
     LOGGER.info("onStatusChanged: {}, status: {}", provider, status); 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
     LOGGER.info("onProviderEnabled: " + provider); 
     if (provider.equals(LocationManager.GPS_PROVIDER)) { 
      setGpsProviderAvailable(true); 
     } 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
     LOGGER.info("onProviderDisabled: " + provider); 
     if (provider.equals(LocationManager.GPS_PROVIDER)) { 
      setGpsProviderAvailable(false); 
     } 
    } 
} 

public class NetworkLocationListener implements LocationListener { 

    @Override 
    public void onLocationChanged(Location location) { 
     LOGGER.info("Location track ,onLocationChanged location={}", location); 
     switch (location.getProvider()) { 
      case LocationManager.NETWORK_PROVIDER: 
       setLastKnownLocation(location); 
       break; 
     } 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
     LOGGER.info("onStatusChanged: {}, status: {}", provider, status); 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
     LOGGER.info("onProviderEnabled: " + provider); 
     if (provider.equals(LocationManager.GPS_PROVIDER)) { 
      setGpsProviderAvailable(true); 
     } 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
     LOGGER.info("onProviderDisabled: " + provider); 
     if (provider.equals(LocationManager.GPS_PROVIDER)) { 
      setGpsProviderAvailable(false); 
     } 
    } 
} 

Non dimenticato di annullare la registrazione e fermare tutte le discussioni :)

+0

Ho sempre bisogno di un thread separato per questo listener? Il mio utente cammina relativamente lentamente e non ho bisogno di aggiornamenti ad alta frequenza; Inoltre, la posizione viene semplicemente spinta per un'ulteriore elaborazione: nulla si bloccherà sul thread dell'interfaccia utente. –

+0

Un'altra domanda: c'è tutta questa saggezza su come filtrare gli aggiornamenti di posizione "sbagliati". –

+1

1. No. Per questo non è necessario un thread separato. È possibile utilizzare lo stesso thread dell'interfaccia utente per ottenere onLocationChange 2. È tutta un'altra storia :) È necessario scrivere il libro come filtrare le posizioni errate –

0

Non ne sono sicuro, ma l'ultima volta che ho visto qualcosa del genere, quel telefono non aveva GPS dedicato. Aveva solo un GPS.

Dopo essermi occupato in giro per un sacco di tempo mi sono reso conto che questo era il motivo per cui non stavo ottenendo una posizione precisa. Ma dopo aver aperto le mappe, per qualche ragione la posizione era accurata. Google sicuramente fa molte altre cose nelle mappe per ottenere una posizione precisa sulle mappe anche se il telefono non ha GPS dedicato. Basta controllare i dispositivi e le loro specifiche hardware.

0

Durante la creazione di LocationRequest, è necessario impostare setPriority() su PRIORITY_NO_POWER.

PRIORITY_NO_POWER significa che la tua app non otterrà mai alcuna posizione a meno che non sia stata richiesta da altre app nel telefono per le località e ricevuta. Maggiori informazioni allo LocationRequest.

+0

Mostra come il problema può essere * riprodotto * in modo affidabile, non come può essere risolto. –

0

Ragazzi testate su dispositivo Marshmallow o versione precedente?
Nei dispositivi di cui sopra Lollipop, è necessario richiedere l'autorizzazione di posizione in fase di esecuzione. Consulta questo link http://developer.android.com/training/permissions/requesting.html
Quindi non avresti l'autorizzazione per la posizione, quindi non restituirebbe la posizione precisa ma quando avvierai la tua app Mappa che dispone già dell'autorizzazione Gps, aggiornerà la tua posizione nel servizio di riproduzione di Google. In questo modo, inoltre, inizierai a mostrare la posizione corretta perché la posizione viene in definitiva recuperata dal servizio di riproduzione di Google.

+0

Non è corretto. L'app è contrassegnata come Lollipop di destinazione, e quindi anche su Marshmallow le autorizzazioni funzionano alla vecchia maniera. Inoltre, gli aggiornamenti di posizione arrivano, solo meno precisi rispetto a Maps. Inoltre, se si passa al fornitore di localizzazione GPS da fuso, gli aggiornamenti funzionano correttamente. –