Gestire l'accelerometro nelle applicazioni Silverlight per Windows Phone

di Marco De Sanctis, in Windows Phone,

Un accelerometro è un dispositivo hardware in grado di determinare le forze che agiscono sul device; sicuramente, quindi, viene misurata la gravità, ma nulla impedisce di utilizzarlo per rilevarne delle altre, associate ad esempio agli spostamenti del telefono.
Le funzionalità dell'accelerometro sono esposte dal Windows Phone SDK tramite la classe Accelerometer presente nell'assembly Microsoft.Phone.Sensors (e nell'omonimo namespace), che dobbiamo referenziare manualmente in quanto non incluso per default nel template di progetto Windows Phone Application. Tipicamente, possiamo istanziarla nel costruttore della pagina, come nell'esempio, sottoscrivendone l'evento ReadingChanged:

public AccelerometerDemo()
{
  InitializeComponent();

  var accelerometer = new Accelerometer();
  accelerometer.ReadingChanged += accelerometer_ReadingChanged;

  accelerometer.Start();
}

Tramite il metodo Start, attiviamo le funzionalità di misura, facendo in modo che, ogni volta che sia disponibile una nuova rilevazione, venga sollevato l'evento ReadingChanged. Un analogo metodo Stop serve invece a sospendere le attività.
Prima di addentrarci ulteriormente nel codice, è importante spendere qualche riga per spiegare il sistema di coordinate utilizzato per rappresentare le misure. La classe AccelerometerReadingEventArgs, infatti, contiene tre proprietà X, Y e Z, con in particolare con l'asse Z orientato nel verso uscente dallo schermo.


L'accelerometro misura le forze che agiscono sul telefono, convenzionalmente indicando con 1 il valore della forza di gravità. Ad esempio, se manteniamo il telefono in posizione perfettamente verticale, come mostra la figura, essa agisce in senso contrario all'asse Y, generando la misura (0, -1, 0).
A questo punto, abbiamo tutte le informazioni necessarie per visualizzare (e interpretare correttamente) i dati che riceviamo dal gestore tramite l'evento ReadingChanged, mostrandoli magari all'interno di una TextBlock in pagina come nell'esempio:

private void accelerometer_ReadingChanged(
    object sender, AccelerometerReadingEventArgs e)
{
  string text = string.Format(
    "X: {0:0.###}\nY: {1:0.###}\nZ: {2:0.###}, 
    e.X, e.Y, e.Z);

  this.Dispatcher.BeginInvoke(() => this.textBlock.Text = text);
}

L'uso del Dispatcher per visualizzare il risultato sullo schermo è necessario perché l'evento viene sollevato in un thread secondario: anche in Windows Phone, infatti, gli elementi dell'interfaccia utente possono essere modificati solo dal thread principale. Se ci limitassimo a scrivere il codice dell'esempio, l'applicazione genererebbe una UnauthorizedAccessException a runtime, causata da un accesso cross-thread agli elementi della UI.

Come abbiamo accennato all'inizio di questo paragrafo, l'accelerometro può essere utilizzato anche per misurare le forze che agiscono sul telefono, dato che i valori misurati sui tre assi rappresentano proprio le accelerazioni subite dal telefono lungo di essi. Tramite la formula in figura 12.5, banale per chi ha dei piccoli rudimenti di algebra, possiamo calcolarne l'intensità totale.


Con il device fermo, in qualsiasi posizione, questo dato sarà sempre prossimo a 1 (ossia, ancora una volta, la forza di gravità), ma in generale possiamo utilizzarlo per diversi scopi. Il codice dell'esempio 12.13 è simile al precedente, ma cerca di determinare, in base all'intensità rilevata, se il device è in movimento o meno.

private void accelerometer_ReadingChanged(
  object sender, AccelerometerReadingEventArgs e)
{
  var magnitude = Math.Sqrt(
    Math.Pow(e.X, 2) + 
    Math.Pow(e.Y, 2) + 
    Math.Pow(e.Z, 2));

  string text = string.Format(
    "X: {0:0.###}\nY: {1:0.###}\nZ: {2:0.###}\n\n" + 
    "Current Acceleration: {3:0.###}", 
    e.X, e.Y, e.Z, magnitude);

  bool moving = Math.Abs(magnitude - 1) > .04;

  this.Dispatcher.BeginInvoke(() => 
  {
    this.textBlock.Text = text;
    if (moving)
    {
      this.textIsMoving.Foreground = new SolidColorBrush(Colors.Red);
      this.textIsMoving.Text = "In movimento";
    }
    else
    {
      this.textIsMoving.Foreground = new SolidColorBrush(Colors.Green);
      this.textIsMoving.Text = "Non in movimento";
    }
  }); 
}

Anche in questo caso, il codice è piuttosto semplice e si limita a verificare se l'accelerazione complessiva differisce da quella gravitazionale di una determinata soglia, visualizzando poi un messaggio a video che indica se stiamo muovendo o meno il device.

Questo script è tratto dal libro 'Sviluppare applicazioni per Windows Phone':
http://books.aspitalia.com/Windows-Phone/

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi