CERCA SITEMAP FEED RSS 1280
Ultimo aggiornamento: 30 Agosto 2009

Location API

I sistemi location-based forniscono una serie di servizi dipendenti dall’attuale posizione geografica occupata da dispositivi mobili.
Tipicamente un sistema-location based determina dapprima la posizione geografica di un dispositivo mobile e quindi fornisce informazioni per personalizzare applicazioni e servizi.
Per comprendere meglio l’importanza di questi sistemi si pensi ad esempio alla possibilità di poter identificare istantaneamente la posizione geografica di una persona che sta richiedendo il soccorso di un’ambulanza a seguito di un incidente ed ancora la possibilità di poter recuperare informazioni relative alla presenza di luoghi di intrattenimento, di ristorazione e di altro ancora nel territorio (e di conseguenza ottenere le informazioni necessarie a raggiungere questi posti).
Le Location API (JSR-179) forniscono appunto un set di funzionalità necessarie allo sviluppo di servizi di questo tipo.
La posizione di un dispositivo può essere espressa in termini di coordinate spaziali (latitudine, longitudine ed altitudine) o attraverso una descrizione testuale (via, città, codice postale, numero civico): in ogni caso per determinarla si ricorre a metodi real-time.

La posizione di un dispositivo mobile può essere determinata nei seguenti modi:
  • Usando la rete del telefono mobile: l’ID del telefono mobile può essere utilizzato per determinare la stazione base di trasmissione (BTS) con il quale il dispositivo comunica ed identificare quindi la posizione della stazione BTS.
    Con questa tecnica la posizione viene determinata in maniera molto grossolana: un cellulare GSM per intenderci potrebbe trovarsi entro il raggio di 10 Km dalla stazione BTS con la quale comunica.
  • Sfruttando il sistema GPS (Global Positioning System) costituito da una rete di 24 satelliti che calcola i ritardi di propagazione del segnale fra un satellite e l’altro per determinare la posizione geografica del dispositivo.
    Tale sistema è costoso in quanto il dispositivo mobile deve essere dotato di un ricevitore GPS ma garantisce una buona precisione (fra 4 e 40 metri).
  • Sfruttando una rete locale: ad esempio all’interno di un edificio si potrebbe installare una rete di dispositivi Bluetooth e calcolare tramite triangolazioni la posizione del dispositivo mobile.
Naturalmente la precisione è un fattore molto importante per alcuni tipi di applicazioni e meno per altre: un’applicazione che ha lo scopo di guidare un turista all’interno di una città potrebbe ad esempio "accontentarsi" di un margine di errore di qualche decina di metri ma lo stesso margine di errore potrebbe risultare troppo grande per applicazioni di tipo scientifico.

Recupero della posizione

Le classi costitutive delle Location API sono raggruppate nel package javax.microedition.location: l’hardware del dispositivo determina quali metodi di posizionamento possono essere utilizzati.
La classe principale del package è la LocationProvider che rappresenta la sorgente delle informazioni di localizzazione.
Tale classe permette tramite l’utilizzo del metodo getInstance(Criteria criteria) di ottenere un location-provider che rispecchi determinati requisiti di accuratezza e precisione.

In particolare l’oggetto Criteria permette di stabilire:
  • l’accuratezza orizzontale setHorizontalAccuracy(int accuracy)
  • l’accuratezza verticale setVerticalAccuracy(int accuracy)
  • il massimo tempo di risposta al quale deve attenersi il LocationProvider setPreferredResponseTime(int time)
  • la massima potenza permessa setPreferredPowerConsumption(int level)
  • se il LocationProvider deve provvedere a stimare anche la velocità del dispositivo setSpeedAndCourseRequired(boolean speedAndCourseRequired)
  • se autorizzare o meno eventuali costi dovuti all’utilizzo di servizi o provider a pagamento setCostAllowed(boolean costAllowed)
  • se il LocationProvider deve recuperare informazioni relative alla descrizione testuale della posizione (ovvero indirizzo, stato, codice postale ...) setAddressInfoRequired(boolean addressInfoRequired)
Una volta definito un oggetto di tipo Criteria è possibile ricavare il LocationProvider che ne soddisfa i requisiti come nel seguente esempio:
...

Criteria criteria = new Criteria();
criteria.setHorizontalAccurancy(10);
criteria.setVerticalAccurancy(10);
criteria.setPreferredResponseTime(5);
criteria.setCostAllowed(false);

...

LocationProvider provider = LocationProvider.getInstance(criteria);

...
La classe LocationProvider mette a disposizione dei metodi per recuperare lo stato del location-provider stesso e la locazione del dispositivo mobile.

In particolare:
  • getState() ne cattura lo stato (disponibile, fuori servizio, temporaneamente non disponibile)
  • getLocation(int timeout) recupera la posizione del dispositivo mobile secondo i requisiti di precisione specificati nell’oggetto Criteria utilizzato per ottenere un’istanza del LocationProvider ed entro il tempo specificato come parametro (in secondi). Se il LocationProvider non riesce a localizzare il dispositivo entro il tempo indicato il metodo genera una LocationException.
  • getLastKnownLocation() recupera le informazioni relative all’ultima posizione stimata.
L’oggetto Location ottenuto mediante il metodo getLocation(int timeout) è rappresentativo della posizione del dispositivo mobile.

E’ possibile pertanto recuperare tutte le informazioni relative alla posizione stimata:
  • getAddressInfo() restituisce la descrizione testuale della posizione sotto forma di un oggetto AddessInfo.
  • getLocationMethod() restituisce il metodo utilizzato per determinare la posizione del dispositivo
  • getQualifiedCoordinates() restituisce le coordinate della posizione ed il relativo grado di precisione in forma di un oggetto QualifiedCoordinates
  • getSpeed() restituisce la velocità del dispositivo
  • getTimeStamp() restituisce l’istante di tempo al quale è stata recuperata la posizione del dispositivo.
...

Location posizione = provider.getLocation(40);

float velocita = posizione.getSpeed();
QualifiedCoordinates coordinate = posizione.getQualifiedcoordinates();

...

Monitoraggio di posizione e prossimità

Le interfacce LocationListener e ProximityListener permettono di definire degli oggetti per il monitoring della posizione del dispositivo e della prossimità dello stesso ad alcune aree sensibili.
Il LocationListener viene collegato al LocationProvider mediante il metodo setLocationListener(LocationListener listener, int interval, int timeout, int maxAge) in cui occorre specificare l’intervallo di aggiornamento (ogni tot secondi si procede alla stima di una nuova posizione), il timeout (ovvero il tempo massimo consentito al LocationProvider per stimare la posizione) ed infine la massima età entro la quale l’oggetto Location verrà considerato valido).

Il LocationListener definisce due metodi:
  • locationUpdated(LocationProvider provider, Location location) invocato quando la posizione del dispositivo mobile viene aggiornata
  • providerStateChanged(LocationProvider provider, int newState) che viene invocato quando lo stato del LocationProvider viene aggiornato (ad esempio da disponibile a fuori servizio)
...

public class PositionMonitor implements LocationListener
{
   public void locationUpdated(LocationProvider provider, Location location)
   {
      ...
   }

   public void providerStateChanged(LocationProvider provider, int newState)
   {
      ...
   }
}

...

PositionMonitor monitorposizione = new PositionMonitor()

provider.setLocationListener(monitorposizione,30,10,20);

...
Per definire un oggetto che si occupi di effettuare il monitorino di prossimità del dispositivo mobile rispetto ad alcune zone sensibili occorre implementare l’interfaccia ProximityListener che definisce essenzialmente due metodi:
  • monitoringStateChanged(boolean isMonitoringActive) che viene invocato ad ogni cambiamento di stato del monitorino
  • proximityEvent(Coordinates coordinates, Location location) che viene invocato quando il dispositivo mobile si trova in prossimità dell’area sensibile definita
L’oggetto ProximityListener viene collegato ad un LocationProvider mediante il metodo addProximityListener(ProximityListener listener, Coordinates coordinates, float proximityRadius) in cui occorre specificare le coordinate ed il raggio della zona sensibile. Quando la posizione del dispositivo mobile si trova all’interno dell’area definita dalle coordinate del centro ed il raggio il metodo proximityEvent (Coordinates coordinates, Location location) del ProximityListener viene invocato.
...

public class MonitorProssimita implements ProximityListener
{
   public void proximityEvent(Coordinates coordinates, Location location)
   {
      ...
   }

   public void monitoringStateChanged(boolean isMonitoringActive)
   {
      ...
   }

}

...

Coordinates coordinate = new Coordinates(10f,30f,2f);
Provider.addProximityListener(new MonitorProssimita(),coordinate,10f);

...

Definizione di landmark

Un LandMark rappresenta una posizione conosciuta e identificata con un nome noto all’utente. La classe LandMark altro non è che un contenitore di informazioni: un nome identificativo, una descrizione testuale opzionale, delle coordinate geografiche ed infine un AddressInfo opzionale.
  • getAddressInfo() restituisce l’AddressInfo associato al LandMark
  • getDescription() ritorna la descrizione associata al LandMark
  • getName() restituisce il nome del LandMark
  • getQualifiedCoordinates() restituisce le coordinate del LandMark ed i relativi gradi di accuratezza
  • setAddressInfo(AddressInfo addressInfo) setta l’AddressInfo del LandMark
  • setDescription(String description) imposta la descrizione del LandMark
  • setName(String name) imposta il nome del LandMark
  • setQualifiedCoordinates(QualifiedCoordinates qualifiedCoordinates) imposta le coordinate del LandMark
I LandMark, generalmente organizzati in categorie e condivisi fra tutte le applicazioni J2ME, vengono memorizzati in un LandMarkStore che fornisce appunto metodi per memorizzare, cancellare e recuperare LandMark.
  • addCategory(java.lang.String categoryName) aggiunge una categoria al LandMarkStore
  • addLandmark(Landmark landmark, java.lang.String category) aggiunge un LandMark ad una categoria
  • createLandmarkStore(java.lang.String storeName) crea un LandMarkStore utilizzando il nome specificato
  • deleteCategory(java.lang.String categoryName) cancella la categoria indicata come parametro
  • deleteLandmark(Landmark lm) cancella il LandMark specificato dal LandMarkStore
  • deleteLandmarkStore(java.lang.String storeName) cancella il LandMarkStore indicato come parametro
  • getCategories() restituisce le categorie presenti nel LandMarkStore
  • getInstance(java.lang.String storeName) restituisce un’istanza del LandMarkStore indicato
  • getLandmarks() restituisce tutti i LandMark memorizzati nel LandMarkStore
  • getLandmarks(java.lang.String category, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) restituisce tutti i LandMark appartenenti alla categoria indicata e aventi una posizione compresa fra le coordinate indicate
  • getLandmarks(java.lang.String category, java.lang.String name) restituisce il LandMark specificato dal nome ed appartenente alla categoria indicata
  • listLandmarkStores() restituisce una lista di tutti i LandMarkStore memorizzati all’interno del dispositivo J2ME
  • removeLandmarkFromCategory(Landmark lm, String category) rimuove un LandMark da una determinata categoria
  • updateLandmark(Landmark lm) aggiorna un LandMark
...

LandMarkStore store = LandMarkStore.createLandMarkStore("servizi");
store.addCategory("pizzerie");
LandMark landmark = new LandMark("pizzeria la Margherita","Ottima pizzeria etc..etc",new QualifiedCoordinates(10f,20f,2f,3f,3f),null);
store.addLandMark(landmark,"pizzeria");

...