Le Google Location Services API per calcolare la posizione di un utente in Android

Individuare la posizione di un utente tramite le Google Location Services API contenute nel Google Play Services

Le Google Location Services API, a differenza del LocationManger, forniscono un meccanismo per la rilevazione utente più potente, di alto livello, che consente di ottimizzare il consumo della batteria e di automatizzare alcune attività come la scelta del provider. Le api sono state messe a disposizione dal 2012 da Google fanno parte del cosiddetto fused location provider e sono contenute nei Google Play Services, un servizio che viene eseguito in background da Android, consentono di ottenere la posizione dell’utente in poche righe di codice.

L’applicazione Google Play Services è scaricabile dal Play Store di Google e consente di accedere al tutte le funzionalità, anche quelle più recenti senza dover aggiornare l’intero sistema operativo. Consente inoltre di accedere ai servizi offerti senza doversi preoccupare del supporto dei singoli device e della versione di Android installata, sarà compito dei Google Play Services garantirne il funzionamento.

Schema Google Play services

I Google Play Services necessitano di un client library che consente alle applicazioni di comunicare ed interagire con il Google Play Services APK che contiene una serie di servizi indispensabili per il suo funzionamento. Per accedere al fused location provider occorre includere la libreria Google Play Services tramite Gradle e richiedere i permessi di ACCESS_COARSE_LOCATION e ACCESS_FINE_LOCATION.

Per poter utilizzare le API occorre creare un’istanza di Google Play Services API client attraverso il metodo GoogleApiClient.Builder() e attraverso il metodo getLastLocation() è possibile ricevere l’ultima posizione rilevata del dispositivo. La posizione ricevuta sarà contenuta in un oggetto di tipo Location al cui interno si trovano le coordinate geografiche espresse in termini di latitudine e longitudine.

Schema Google Play services library

Il fused location provider viene utilizzato per ricevere costantemente aggiornamenti ad intervalli regolari sulla posizione dell’utente in Android, in particolare si occupa di mostrare la posizione dal migliore provider attualmente disponibile. Il meccanismo della scelta del migliore provider disponibile è completamente trasparente all’utente. I dati ricevuti sono salvati in un oggetto di tipo LocationRequest il cui settaggio iniziale determina il livello di accuratezza dei dati ricevuti. Alcune delle opzioni dell’oggetto LocationRequest sono:

  • Update interval: attraverso il metodo setInterval() viene settata la velocità con cui si preferisce ricevere gli aggiornamenti sulla posizione. Questo valore è puramente indicativo, se il dispositivo riceve aggiornamenti più velocemente o più lentamente verranno utilizzati ugualmente;
  • Fastest update interval: consente di settare la massima velocità con cui la nostra applicazione riesce a gestire gli aggiornamenti. Settando male il metodo setFastestInterval() si può incorrere in problemi relativi all’aggiornamento dell’interfaccia grafica, ad esempio se si ricevono molti dati da gestire simultaneamente il dispositivo potrebbere avere problemi a gestire contemporaneamente una tale quantita di dati. Da linea guida, è consigliato settare il Fastest update interval come limite superiore dell’Update interval;
  • Priority: consente di impostare la priorità delle richieste effettuate al Google Play Services. Definendo il tipo di priorità, il fused location provider è fortemente influenzato su quali fonti utilizzare per la localizzazione. Sono supportate quattro tipologie di priorità:
    • PRIORITY_HIGH_ACCURACY: consente di ottenere la posizione più precisa possibile. In questo caso, il servizio di localizzazione è molto più propenso ad utilizzare GPS per il rilevamento;
    • PRIORITY_BALANCED_POWER_ACCURACY: viene utilizzata quando la precisione dall’applicazione può essere approssimata ad un isolato della città con l’accuratezza di circa 100 metri. Questa scelta è a basso consumo di energia ma offre un basso livello di accuratezza, di conseguenza la scelta di un’accuratezza “basse” è un’indicazione per il fused location provider di utilizzare le celle telefoniche e reti wireless per effettuare la localizzazione;
    • PRIORITY_LOW_POWER: con quest’impostazione la precisione è a livello di una città, la sua approssimativamente è di 10 chilometri.
    • PRIORITY_NO_POWER: viene utilizzata quando non si vuole consumare energia e si fermano le richieste di localizzazione, ma se qualche altra applicazione ricevesse delle informazioni anche la nostra applicazione vuole riceverli.

L’oggetto LocationRequest ha molti metodi come il metodo getSmallestDisplacement() che consente di impostare il numero minimo di metri che l’utente deve effettuare prima di ricevere un nuovo aggiornamento. L’applicazione Android richiede gli aggiornamenti utilizzando il metodo requestLocationUpdates() nella callback onConnected() che viene chiamato in automatico dopo la connessione al Google API Client. I dati saranno gestiti nel metodo onLocationChanged(), o tramite un PendingIntent, a seconda del tipo di richiesta. Quando non si utilizza la posizione dell’utente è consigliato fermare gli aggiornamento in modo da salvaguardare la batteria del dispositivo. Quando non è più necessario essere informati sulla posizione del’utente viene utilizzato il metodo stopLocationUpdates() per fermare gli aggiornamenti della posizione.

Ecco un esempio di come settare il GoogleApiClient e l’oggetto LocationRequest:

  public class MyLocationProvider
    implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {
    // ...

    public LocationProvider(Context context, Callback callback) {
      this.callback = callback;
      this.context = context;

      googleApiClient = new GoogleApiClient
        .Builder(this.context)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();

      // Create the LocationRequest object
      locationRequest = LocationRequest.create()
        .setPriority(LOCATION_PRIORITY)
        .setInterval(LOCALIZATION_INTERVAL)
        .setFastestInterval(LOCALIZATION_FASTEST_INTERVAL);
    }
    // ...
  }

Per i casi in cui è necessario avere maggiore precisione nella posizione dell’utente è possibile scartare posizioni non accurate in base al grado di precisione ricevuto:

  public class Position {
    private double latitude;
    private double longitude;
    private Location location;
    public static final int MINIMUM_ACCURACY = 20;

    // ...

    public boolean checkPositionAccuracy() {
      return location != null
        && location.hasAccuracy()
        && location.getAccuracy()
        <= MINIMUM_ACCURACY;     }     // ...   }

Indice:

In alternativa, per conoscere meglio il mondo Android ecco tutte le lezioni: Guida Android.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *