Richiedere gli aggiornamenti di posizione

Un uso appropriato delle informazioni sulla posizione può essere vantaggioso per gli utenti della tua app. Ad esempio, se l'app aiuta l'utente a trovare la strada mentre cammina o guida oppure se monitora la posizione degli asset, deve rilevare la posizione del dispositivo a intervalli regolari. Oltre alla posizione geografica (latitudine e longitudine), potresti voler fornire all'utente ulteriori informazioni, ad esempio l'orientamento (direzione orizzontale di marcia), l'altitudine o la velocità del dispositivo. Queste e altre informazioni sono disponibili nell'oggetto Location che la tua app può recuperare dal provider di posizione integrato. In risposta, l'API aggiorna periodicamente la tua app con la migliore posizione disponibile, in base ai provider di posizione attualmente disponibili come Wi-Fi e GPS (Global Positioning System). L'accuratezza della posizione è determinata dai provider, dalle autorizzazioni di accesso alla posizione che hai richiesto e dalle opzioni che imposti nella richiesta di posizione.

Questa lezione mostra come richiedere aggiornamenti regolari sulla posizione di un dispositivo utilizzando il metodo requestLocationUpdates() nel provider di posizione combinato.

Visualizza l'ultima posizione nota

L'ultima posizione nota del dispositivo fornisce una comoda base da cui iniziare, assicurando che l'app abbia una posizione nota prima di avviare gli aggiornamenti periodici della posizione. La lezione relativa al recupero dell'ultima posizione nota mostra come ottenere l'ultima posizione nota chiamando il numero getLastLocation(). Gli snippet nelle sezioni seguenti presuppongono che la tua app abbia già recuperato l'ultima posizione nota e l'abbia archiviata come oggetto Location nella variabile globale mCurrentLocation.

Inviare una richiesta di posizione

Prima di richiedere aggiornamenti sulla posizione, l'app deve connettersi ai servizi di geolocalizzazione ed effettuare una richiesta di posizione. Nella lezione Modifica delle impostazioni di geolocalizzazione viene mostrato come fare. Una volta effettuata una richiesta di posizione, puoi avviare gli aggiornamenti regolari chiamando il numero requestLocationUpdates().

A seconda della forma della richiesta, il provider di località fuso richiama il metodo di callback LocationCallback.onLocationResult() e gli passa un elenco di oggetti Location oppure invia un elemento PendingIntent che contiene la località nei dati estesi. La precisione e la frequenza degli aggiornamenti dipendono dalle autorizzazioni di accesso alla posizione che hai richiesto e dalle opzioni impostate nell'oggetto richiesta di posizione.

Questa lezione mostra come ricevere l'aggiornamento utilizzando l'approccio di callback LocationCallback. Richiama requestLocationUpdates(), passando la tua istanza dell'oggetto LocationRequest e un elemento LocationCallback. Definisci un metodo startLocationUpdates() come mostrato nel seguente esempio di codice:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

private fun startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper())
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

private void startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper());
}

Tieni presente che lo snippet di codice riportato sopra fa riferimento a un flag booleano, requestingLocationUpdates, utilizzato per monitorare se l'utente ha attivato o disattivato gli aggiornamenti della posizione. Se gli utenti hanno disattivato gli aggiornamenti della posizione, puoi informarli sui requisiti di geolocalizzazione della tua app. Per ulteriori informazioni su come conservare il valore del flag booleano tra le istanze dell'attività, consulta Salvare lo stato dell'attività.

Definisci il callback di aggiornamento della località

Il provider di località integrato richiama il metodo di callback LocationCallback.onLocationResult(). L'argomento in arrivo contiene un oggetto elenco Location contenente la latitudine e la longitudine della posizione. Il seguente snippet mostra come implementare l'interfaccia LocationCallback e definire il metodo, quindi recuperare il timestamp dell'aggiornamento della posizione e visualizzare la latitudine, la longitudine e il timestamp nell'interfaccia utente della tua app:

Kotlin

private lateinit var locationCallback: LocationCallback

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            for (location in locationResult.locations){
                // Update UI with location data
                // ...
            }
        }
    }
}

Java

private LocationCallback locationCallback;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                // Update UI with location data
                // ...
            }
        }
    };
}

Interrompere gli aggiornamenti sulla posizione

Valuta se vuoi interrompere gli aggiornamenti della posizione quando l'attività non è più attiva, ad esempio quando l'utente passa a un'altra app o a un'altra attività nella stessa app. Questo può essere utile per ridurre il consumo energetico, a condizione che l'app non abbia bisogno di raccogliere informazioni anche quando è in esecuzione in background. Questa sezione mostra come interrompere gli aggiornamenti nel metodo onPause() dell'attività.

Per interrompere gli aggiornamenti della posizione, chiama removeLocationUpdates(), passandogli un valore LocationCallback, come mostrato nel seguente esempio di codice:

Kotlin

override fun onPause() {
    super.onPause()
    stopLocationUpdates()
}

private fun stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

Java

@Override
protected void onPause() {
    super.onPause();
    stopLocationUpdates();
}

private void stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback);
}

Utilizza un valore booleano, requestingLocationUpdates, per monitorare se gli aggiornamenti della posizione sono attualmente attivati. Nel metodo onResume() dell'attività, controlla se gli aggiornamenti della posizione sono attualmente attivi e attivali in caso contrario:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

Salva lo stato dell'attività

Una modifica alla configurazione del dispositivo, ad esempio un cambiamento dell'orientamento dello schermo o della lingua, può causare l'eliminazione dell'attività corrente. L'app deve quindi archiviare tutte le informazioni necessarie per ricreare l'attività. Un modo per farlo è tramite uno stato dell'istanza archiviato in un oggetto Bundle.

Il seguente esempio di codice mostra come utilizzare il callback onSaveInstanceState() dell'attività per salvare lo stato dell'istanza:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    outState?.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates)
    super.onSaveInstanceState(outState)
}

Java

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
            requestingLocationUpdates);
    // ...
    super.onSaveInstanceState(outState);
}

Definisci un metodo updateValuesFromBundle() per ripristinare i valori salvati dall'istanza precedente dell'attività, se disponibili. Richiama il metodo dal metodo onCreate() dell'attività, come mostrato nel seguente esempio di codice:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    updateValuesFromBundle(savedInstanceState)
}

private fun updateValuesFromBundle(savedInstanceState: Bundle?) {
    savedInstanceState ?: return

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY)
    }

    // ...

    // Update UI to match restored state
    updateUI()
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    updateValuesFromBundle(savedInstanceState);
}

private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        return;
    }

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY);
    }

    // ...

    // Update UI to match restored state
    updateUI();
}

Per saperne di più sul salvataggio dello stato dell'istanza, consulta il riferimento della classe Attività Android.

Nota: per uno spazio di archiviazione più permanente, puoi archiviare le preferenze dell'utente nel SharedPreferences dell'app. Imposta la preferenza condivisa nel metodo onPause() della tua attività e recupera la preferenza in onResume(). Per ulteriori informazioni sul salvataggio delle preferenze, consulta Salvataggio di insiemi di valori-chiave.

Risorse aggiuntive

Per saperne di più, consulta le seguenti risorse:

Campioni

  • App di esempio per dimostrare la ricezione degli aggiornamenti della posizione in Android.