12.5: Il LocationManager: localizzare l’utente pt.1

Condividi su:

Lo sfruttamento delle mappe non è nulla senza la possibilità di poter localizzare l’utente e quindi dargli una posizione all’interno della mappa. Ormai qualsiasi dispositivo Android in circolazione dispone di un sistema di localizzazione come ad esempio il GPS; senza considerare altri metodi come la triangolazione delle celle radio o dell’hotspot che serve la connessione.





In questo articolo vedremo come poter gestire la posizione dell’utente e per farlo tralasceremo temporaneamente Google Maps. Sperimenteremo con un nuovo progetto, quindi createne uno nuovo con activity vuota, tanto non useremo alcuna view.

Una volta aperto il progetto, il primo passo da fare è registrare all’interno del manifest la necessità di dover accedere alla posizione, quindi aggiungeremo il seguente tag prima di <application>:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

In questo modo richiediamo al sistema il permesso per accedere alla localizzazione precisa, quella che fa uso del GPS.

Fatto ciò possiamo procedere col codice, che inseriremo all’interno di MainActivity.

Sostanzialmente faremo uso di due oggetti, il primo, facente parte della classe LocationManager e il secondo invece di tipo LocationListener.

Un LocationManager permette l’accesso al servizio di sistema adibito alla localizzazione fornendo anche i metodi necessari a sfruttare questo servizio. Banalmente è un oggetto che si interpone tra un servizio a più basso livello della piattaforma e la nostra app.
Il LocationListener invece si comporta come tutti gli altri listener, monitora i cambiamenti sulla posizione ricevuta dal LocationManager e ci permette di agire di conseguenza.

Vediamo come sfruttare questi due oggetti:

public class MainActivity extends AppCompatActivity {
    //Dichiariamo un LocationManager per poter poi accedere al servizio di localizzazione
    private LocationManager locationManager;
    //Dichiariamo un LocationListener usato per rimanere in ascolto di cambi di posizione
    private LocationListener locationListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Istanziamo il LocationManager recuperando il servizio di localizzazione
        locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
        //Istanziamo il listener che monitorerà cambi nella posizione
        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                /*
                 * Metodo invocato quando cambia la posizione
                 */

                //Visualizzazione della posizone nel log
                Log.d("Location: ", location.toString());
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                /*
                 * Metodo invocato quando cambia lo stato del provider, ad esempio quando questo non
                 * è in grado di recuperare la posizione, oppure quando è ritornato disponibile dopo
                 * un periodo di non disponibilità
                 */
            }

            @Override
            public void onProviderEnabled(String provider) {
                /*
                 * Metodo invocato quando il provider viene abilitato dall'utente
                 */
            }

            @Override
            public void onProviderDisabled(String provider) {
                /*
                 * Metodo invocato quando l'utente disabilita il provider o quando è già disabilitato
                 * al momento della chiamata del metodo "requestLocationUpdates()"
                 */
            }
        };
    }
}

Per prima cosa abbiamo dichiarato i due oggetti tra i field della classe, dopodiché abbiamo provveduto ad istanziarli all’interno dell'”onCreate()”.
Per il LocationManager sfruttiamo l’apposito getter della classe Context per recuperare l’handle del servizio di sistema che ci interessa. È richiesto un casting esplicito poiché dobbiamo forzare il servizio ricevuto dal getter verso un LocationManager. I servizi disponibili sono codificati all’interno di stringhe, quindi sfruttiamo quella relativa al servizio di cui necessitiamo.

Il listener invece lo istanziamo richiamando il suo costruttore. Questo comporta l’override di alcuni metodi astratti, così come accade per tutti i listener. Questi metodi verranno invocati al verificarsi di determinate condizioni.

A noi interessa monitorare i cambi di posizione, quindi sfrutteremo il metodo “onLocationChanged()” che come parametro ha proprio un oggetto di tipo Location, che contiene appunto i dati geografici della posizione.
Banalmente inseriremo nel log la stringa ottenuta da questo oggetto.

Per gli altri metodi potete consultare la documentazione, comunque all’interno del codice vi ho accennato con un commento quando vengono invocati. Qui si parla di provider e vi starete chiedendo di cosa si tratta. Banalmente il fornitore della posizione, che può essere il GPS, come il sistema di triangolazione delle celle.
Ad esempio il metodo “onProviderDisabled()” viene invocato quando l’utente disabilità la localizzazione o questa è già disabilitata, quindi qui potrete inserire del codice necessario per richiedere all’utente l’attivazione della localizzazione.

Se provate l’app…all’interno del log non troverete alcunché. Per prima cosa c’è da dire che di fatto la posizione non è cambiata, quindi il log non viene proprio scritto. Il problema è che se anche provaste a cambiare posizione, ad esempio sfruttando un’app per la posizione fittizia, se state usando un device reale per i vostri test; oppure cambiando le coordinate tra le proprietà dell’emulatore, se sfruttate AVD, ancora non avrete riscontri.

Il motivo è semplice, il listener va registrato, così come facciamo quando settiamo quello relativo ai click sui pulsanti.

Per farlo sfruttiamo il metodo “requestLocationUpdate()” del LocationManager aggiungendo la seguente istruzione in coda all’istanziazione del listener:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

Col primo parametro stabiliamo il provider (sono codificati all’interno di stringhe della stessa classe). A noi interessa una posizione precisa (tra l’altro quella per cui abbiamo registrato il permesso), quindi sfrutteremo il GPS.
Col secondo e terzo parametro indichiamo l’intervallo minimo in millisecondi e la distanza minima in metri tra gli aggiornamenti di posizione.
Infine con l’ultimo parametro indichiamo il listener adibito al monitoraggio della localizzazione, di fatto lo registriamo.

Settando i parametri di intervallo e distanza minimi su 0, il metodo “onLocationChanged()” verrà invocato ad ogni minimo spostamento a prescindere dal tempo.


Conclusioni

Se adesso provate di nuovo l’app e variate la posizione, al 99% ancora non otterrete riscontri. Quasi sicuramente starete sfruttando delle API target superiori alle 23, questo significa che l’app potrà girare anche su Android 6.0 e versioni successive.
Il permesso di accesso alla localizzazione è classificato come pericoloso, quindi sulle nuove versioni di Android non è sufficiente richiederlo al sistema attraverso il manifest, ma va richiesto esplicitamente all’utente al momento dell’esecuzione dell’app o quando necessario.
Se vi trovate in questa situazione Android Studio vi segnalerà anche un errore su quest’ultima istruzione e vi proporrà di inserire il codice necessario a controllare se il permesso è stato concesso. Potete già fare questo passaggio, ma ce ne occuperemo nel prossimo articolo.

Condividi su:

label, , ,

About the author