ASP.Net  »  Articoli  »  Silverlight 

Windows Phone 7: API e feature del telefono

di: Roberto Brunetti     30 Giugno 2010

Location Service

Anche in questo caso diamo uno sguardo prima al codice partendo dal form, che ormai abbiamo imparato a chiamare Page, per poi concentrarci su qualche dettaglio sul servizio di localizzazione.

Figura 5. Interfaccia utente per testare il Location Service
(clic per ingrandire)

Interfaccia utente per testare il Location Service

La Page consente di attivare e di fermare il servizio e mette a disposizione sei TextBlock: i primi 5 consentono di visualizzare la latitudine, la longitudine, l'altezza e l'orientamento (per ques'ultimo occorre verificare nelle prossime versioni il supporto e l'interazione con la bussola: in questa prima versione è possibile ricavare l'orientamento se il device è in movimento).

Ovviamente serve un movimento del device per calcolare la velocità che visualizzeremo nel penultimo TextBlock. L'ultimo elemento della user interface è dedicato ad accogliere le informazioni di stato sul servizio. Il codice necessita delle reference a System.Device.Location per utilizzare la classe GeoCoordinateWatcher e i relativi eventi:

using System.Device.Location

namespace _30_LocationService
{

  public partial class MainPage : PhoneApplicationPage
  {
    GeoCoordinateWatcher watcher;
	
  public MainPage()
  {
    InitializeComponent();
    SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
  }	
  
  private void StarTrack_Click(Object sender, RoutedEventArgs e)
  {
    if(watcher == null)
	{
	  watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Low);
	  //watcher.MovementThreshold = 20;
	}
	
	n
    IsolatedStorageSettings.ApplicationSettings["Data"] = DateTime.Now.ToString();
	
	// N.B. Save automatico quando si chiude l'applicazione
	// se stateless è bene salvare subito
	IsolatedStorageSettings.ApplicationSettings.Save();
  }
  
}

Dopo aver definito per semplicità l'oggetto watcher a livello di Page, nel metodo StartTrack_Click inizializzamo l'oggetto con una nuova istanza di GeoCoordinateWatcher. Come si nota è possibile passare un livello di accuratezza che servirà al device per fornire informazioni da GPS, Wi-Fi o rete cellulare in base alle preferenze: in pratica è inutile utilizzare un sistema molto preciso che consuma molta batteria se non abbiamo bisogno di calcolare gli spostamenti inferiori a 20 metri, così come è possibile invece impostare GeoPositionAccuracy.High per ottenere dati molto precisi pur consumando più batteria. MovementThreshold è un altro parametro sulla stessa linea: consente di impostare il limite di notifica per evitare che una applicazione venga informata troppo frequentemente su spostamenti minimi e ininfluenti rispetto all'applicazione stessa.

Il metodo StartTrack_Click prosegue con l'aggancio a due eventi che, rispettivamente, consentono di capire se stiamo ricevendo dati dal servizio di Location e qual è la nostra posizione. Il codice del pulsante Stop si commenta da solo. Il codice del primo evento è il seguente:

  void watcher_StatusChanged(Object sender, GeoPositionStatusChangedEventArgs e)
  {
    Deployment.Current.Dispatcher.BeginInvoke(() => MyStatusChanged(e));
  }


  void MyStatusChanged(GeoPositionStatusChangedEventArgs e)
  {
    switch (e.Status)
	{
	  case GeoPositionStatus.Disabled:
        // Controllo disabilitazione del servizio da parte dell'utente
        if(watcher.Permission == GeoPositionPermission.Denied)
		{
		  StatusTextBlock.Text = "Hai disabilitato il servizio";
		}
		else
		{
		  StatusTextBlock.Text = "Il servizio non funziona"; 
		}
		break;
      
	  case GeoPositionStatus.Initializing:
	    StartTrackButton.IsEnabled = false;
	    break;
	  
	  case GeoPositionStatus.NoData:
	    StatusTextBlock.Text = "Non riesco a recuperare le informazioni";
		StopTrackButton.IsEnabled = true;
	    break;
	  
	  case GeoPositionStatus.Ready:
	    StatusTextBlock.Text = "Dati disponibili";
		StopTrackButton.IsEnabled = true;
	    break;
	}
  }	

A parte rimarcare il fatto che gli eventi sono notificati da un thread secondario che impone, sin da Windows Forms versione 1, di chiedere al thread principale di effettuare una operazione sulla Page, l'evento è molto semplice da descrivere: in base a GeoPositionStatusChangedEventArgs sappiamo se il servizio è stato disabilitato dall'utente (o non abilitato per la nostra applicazione), se il servizio è in fase di inizializzazione, se riesce a leggere dati nonostante il suo apparente funzionamento oppure sta leggendo dati dalle sue fonti.

Con lo stesso approccio, passiamo al thread principale anche le informazioni sui dati stessi:

  void watcher_PositionChanged(Object sender, GeoPositionChangedEventArgs e)
  {
    Deployment.Current.Dispatcher.BeginInvoke(() => MyPositionChanged(e));
  }

  void MyPositionChanged(GeoPositionChangedEventArgs e)
  {
    
	LatitudeTextBlock.Text = e.Position.Location.Latitude.ToString("0.000");
	LongitudeTextBlock.Text = e.Position.Location.Longitude.ToString("0.000");
	altitudeTextBlock.Text = e.Position.Location.Altitude.ToString("0.000");
	courseTextBlock.Text = e.Position.Location.Course.ToString("0.000");
	speedTextBlock.Text = e.Position.Location.Speed.ToString("0.000");
  }

Il risultato è visualizzabile anche sull'emulatore, a patto di non aver scelto "Accuracy = High" e di avere una connessione Wi-Fi o cellulare (o, ma non sono riuscito a eseguire test, anche un GPS sul PC). Eseguendo il progetto otteniamo i valori sulla posizione corrente.

Figura 6. L'applicazione che gira sull'emulatore
(clic per ingrandire)

L'applicazione che gira sull'emulatore

Ovviamente Speed e Course sono "NaN" in quanto eseguiamo il test sull'emulatore. È possibile simulare l'invio di dati al servizio utilizzando le Reactive Extension (Rx Framework) di .NET.

Alla prossima

Roberto Brunetti si occupa di sviluppo mobile sin dal 1997. Ha scritto numerosi articoli, libri e pubblicazioni, partecipato a numerose conferenze italiane e internazionali. Si occupa di architetture distribuite, Windows Azure e dal momento dell'uscita della primo SDK, di Windows Phone 7. Roberto è uno dei fondatori del gruppo DevLeap con il quale eroga formazione e consulenza. La sua azienda, ThinkAhead, oltre allo sviluppo mobile, è specializzata su Windows Azure, piattaforma su cui Roberto ha scritto il suo ultimo libro. Potete seguire il lavoro di Roberto sul suo blog.

Guide ASP.Net

Guida Windows Azure Code Snippets

Le migliori pratiche per far girare le applicazioni "in the cloud",...

Guida ASP.NET MVC Best Practices

Un workflow dettagliato e ricco di suggerimenti pratici per...

Guida ASP.NET Starter Kit

Un modo semplice per imparare ad utilizzare le tecnologie Microsoft...

Altre guide

Newsletter @Microsoft Dev

Ogni giovedì, direttamente nella tua e-mail: articoli, guide, tutorial e script ASP, ASP.Net, SQL server e IIS.

Iscriviti alla newsletter

Altre newsletter

Corsi in aula

Corso Progettazione database

11 Maggio 2012 a Milano
Disponibilità: 6 Posti

Amministratore di Reti Windows Server 2008

11 Giugno 2012 a Milano
Disponibilità: 5 Posti

Nessun corso previsto