DevCorner: le ultime posizioni note [METEO]

Roberto Orgiu
Roberto Orgiu
DevCorner: le ultime posizioni note [METEO]

Nelle puntate precedenti dello sviluppo della nostra app per il meteo, abbiamo iniziato a vedere come effettuare le richieste di rete e ottenere quindi le informazioni che ci interessano, ma abbiamo anche sottolineato come l'AsyncTask non sia esattamente il modo migliore per svolgere operazioni che si possono rivelare anche molto lunghe, come le richieste di rete.

LEGGI ANCHE: App per i feed RSS

Per semplicità, vi lasciamo qui di seguito i link alle precedenti puntate, in modo che, qualora ne aveste bisogno, possiate tranquillamente dare un'occhiata alle spiegazioni:

  1. Prima puntata
  2. Seconda puntata

Vediamo quindi di cosa andremo ad occuparci oggi: abbiamo visto le richieste di rete, ma come facciamo a localizzare l'utente? Ecco quindi presentato il nostro compito odierno!

Per prima cosa, dobbiamo richiedere al sistema di concederci di utilizzare il servizio di geolocalizzazione:

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

Dopodiché, chiediamo al LocationManager di fornirci le ultime coordinate note rilevate dalla rete telefonica e dal sensore GPS, utilizzando poi il metodo getTime() degli oggetti di tipo Location che ci restituiscono i due servizi per capire quale sia la posizione più recente.

Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location lastKnownLocationNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

Ora, utilizzando un oggetto GeoCoder ed il suo metodo getFromLocation(), estrapoliamo il nome della città in cui si trova il nostro utente:

Geocoder geocoder = new Geocoder(context, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
String cityName = addresses.get(0).getLocality();

Avremmo potuto richiedere la posizione esatta dell'utente ma, ai fini della nostra applicazione, la posizione esatta non è totalmente necessaria, ci possiamo accontentare dell'ultima posizione nota, tanto più che, in caso l'utente si fosse spostato e avesse, per qualche motivo, disattivato la connessione ad internet, non potremmo comunque richiedere le informazioni al server.

Eliminato l'AsyncTask, la maniera più semplice per effettuare le operazioni sopra descritte in maniera asincrona rispetto all'esecuzione del thread principale è servirci di un IntentService: questo componente, girando in background, si occuperà di gestire, in sequenza ed una alla volta, tutte le operazioni che gli andremo a richiedere tramite un Intent esplicito e il metodo startService nella nostra Activity:

Intent locationIntent = new Intent(this, BackOps.class);
locationIntent.setAction(BackOps.GET_LOCATION);
startService(locationIntent);

Ora, ad ogni chiamata a startService, verrà invocato il metodo onHandleIntent del nostro servizio, nel quale potremo decidere che operazioni svolgere a seconda dell'Intent ricevuto.

Per rispondere quindi all'Activity che ci ha richiesto i dati, andiamo ad utilizzare nuovamente gli Intent ma, questa volta, ci baseremo su un oggetto molto simile alla squadra sendBroadcast() e BroadcastReciver: limitando alla sola nostra applicazione i dati, possiamo affidarci al LocalBroadcastManager, che funziona in maniera del tutto analoga rispetto ai componenti elencati, limitando però la visibilità dei dati. Vediamo quindi come il servizio invia i dati all'Activity:

Intent locationIntent = new Intent(C.LOCATION_BROADCAST_ACTION).putExtra(C.LOCATION_BROADCAST_EXTRA, cityName);
LocalBroadcastManager.getInstance(this).sendBroadcast(locationIntent);

E come l'Activity li riceve:

LocalBroadcastManager.getInstance(this).registerReceiver(mServiceReceiver, mLocationFilter);

Siamo arrivati alla fine di questa puntata e, come di consueto, vi lasciamo sul nostro forum tutte le risorse di supporto a questa lezione.