Che informazioni possiamo scoprire sul device e sull’utente da una applicazione Windows Phone 7?

Print Content | More

screenshot_11-23-2010_19.36.31.73

All’interno di un’applicazione Windows Phone abbiamo modo di recuperare alcune informazioni sul device e sull’utente che sta utilizzando la nostra applicazione. Queste informazioni ci possono essere utili per diversi motivi: diagnostica, monitoring delle performance, identificazione univoca dell’utente, ecc.

Il modo in cui possiamo recuperare queste informazioni è un po’ diverso da quanto siamo abituati a fare con le altre librerie di Windows Phone: abbiamo infatti a disposizione due classi, dal nome DeviceExtendedProperties e UserExtendedProperties (facenti parte del namespace Microsoft.Phone.Info), che espongono un metodo GetValue(string Key), che accetta come parametro una stringa che rappresenta l’informazione che vogliamo recuperare. Ogni informazione è infatti identificata da una chiave univoca.

La classe DeviceExtendedProperties permette di recuperare informazioni sul device e richiede che nel manifest dell’applicazione (il file WmAppManifest.xml) sia specificata la capability ID_CAP_IDENTITY_DEVICE.

Vediamo l’elenco di tutte le chiavi disponibili e la relativa descrizione:

  • DeviceManufacturer: ritorna una stringa con il nome del produttore del telefono (ad esempio, LG).
  • DeviceName: ritorna una stringa con il nome del device (ad esempio, Optimus 7)
  • DeviceUniqueId: ritorna un array di byte che identifica univocamente il device. Non posso esistere due device diversi che ritornano lo stesso unique id.
  • DeviceFirmwareVersion: ritorna una stringa che identifica la versione del firmware installato sul device. Attenzione, non coincide con la versione del sistema operativo!
  • DeviceHardwareVersion: ritorna una stringa che identifica la versione del’hardware installato sul device.
  • DeviceTotalMemory: ritorna un long integer con la memoria ROM totale installata sul device.
  • ApplicationCurrentMemoryUsage: ritorna un long integer con la quantità di memoria attualmente utilizzata dall’applicazione espressa in byte.
  • ApplicationPeakMemoryUsage: ritorna un long integer con la massima quantità di memoria utilizzata durante il ciclo di vita dell’applicazione, espressa in byte.

La classe UserExtendedProperties permette, in realtà, di recuperare una sola informazione, ovvero l’Anonymous Live Id, tramite la chiave ANID. Come saprete, ad ogni device deve essere associato un Live Id principale che viene utilizzato per diversi scopi (XBox Live, acquisti sul Marketplace, Zune Pass, ecc.). L’Anonymous Live Id è una stringa che identifica univocamente tale Live Id: vi permette perciò di identificare in maniera univoca l’utente senza però violarne la privacy, dato che non sarete a conoscenza dell’indirizzo mail associato all’account.

Questo tipo di informazione può essere molto utile ad esempio se vogliamo gestire la classifica online di un gioco e salvare un id univoco del giocatore che ha fatto quel punteggio: in questo modo ci assicureremo (al contrario di quanto avverrebbe se usassimo il DeviceUniqueId) che tale id rimarrà sempre lo stesso anche se l’utente dovesse cambiare device (sempre ovviamente che acquisti un altro device Windows Phone 7 Smile)

L’utilizzo della classe UserExtendedProperties richiede che nel manifest sia specificata la capability ID_CAP_IDENTITY_USER.

Esiste infine una terza classe, chiamata Environment (facente parte del namespace System), che ci permette di scoprire alcune informazioni utili come la versione del sistema operativo correntemente installata sul device. Vedremo tra poco come utilizzarla.

Una semplice applicazione che mostra tutte le informazioni sul nostro device

Realizziamo ora una semplice applicazione che mostrerà a video tutte le informazioni disponibili sul nostro device e sul nostro account Live.

Partiamo dallo XAML, molto semplice: un Pivot con all’interno due PivotItem (che corrispondono a due diverse pagine). Il primo PivotItem è dedicato alle informazioni sul device e contiene una serie di TextBlock organizzati all’interno di una Grid: ogni riga della Grid contiene una label che identifica la proprietà che stiamo visualizzando e una con il valore vero e proprio.

Il secondo PivotItem è dedicato invece alle informazioni sull’utente e mostra l’Anonymous Live Id.

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--ContentPanel - place additional content here-->
    <controls:Pivot Title="WP7 Info">
        <controls:PivotItem Header="Device">
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="63*" />
                    <RowDefinition Height="77*" />
                    <RowDefinition Height="71*" />
                    <RowDefinition Height="79*" />
                    <RowDefinition Height="79*" />
                    <RowDefinition Height="81*" />
                    <RowDefinition Height="76*" />
                    <RowDefinition Height="81*" />
                    <RowDefinition Height="29" />
                    <RowDefinition Height="29" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="228*" />
                    <ColumnDefinition Width="228*" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="Manufacturer:"></TextBlock>
                <TextBlock Grid.Row="0" Grid.Column="1" x:Name="txtDeviceManufacturer"></TextBlock>

                <TextBlock Grid.Row="1" Grid.Column="0" Text="Name:"></TextBlock>
                <TextBlock Grid.Row="1" Grid.Column="1" x:Name="txtDeviceName"></TextBlock>

                <TextBlock Grid.Row="2" Grid.Column="0" Text="Unique Id:"></TextBlock>
                <TextBlock Grid.Row="2" Grid.Column="1" x:Name="txtDeviceUniqueId"></TextBlock>

                <TextBlock Grid.Row="3" Grid.Column="0" Text="Firmware Version:"></TextBlock>
                <TextBlock Grid.Row="3" Grid.Column="1" x:Name="txtDeviceFirmwareVersion"></TextBlock>

                <TextBlock Grid.Row="4" Grid.Column="0" Text="Hardware Version:"></TextBlock>
                <TextBlock Grid.Row="4" Grid.Column="1" x:Name="txtDeviceHardwareVersion"></TextBlock>

                <TextBlock Grid.Row="5" Grid.Column="0" Text="Total Memory:"></TextBlock>
                <TextBlock Grid.Row="5" Grid.Column="1" x:Name="txtDeviceTotalMemory"></TextBlock>

                <TextBlock Grid.Row="6" Grid.Column="0" Text="Current Memory Usage:"></TextBlock>
                <TextBlock Grid.Row="6" Grid.Column="1" x:Name="txtCurrentMemoryUsage"></TextBlock>

                <TextBlock Grid.Row="7" Grid.Column="0" Text="Peak Memory Usage:"></TextBlock>
                <TextBlock Grid.Row="7" Grid.Column="1" x:Name="txtPeakMemoryUsage"></TextBlock>

                <TextBlock Grid.Row="8" Grid.Column="0" Text="OS Version:"></TextBlock>
                <TextBlock Grid.Row="8" Grid.Column="1" x:Name="txtOSVersion"></TextBlock>

                <TextBlock Grid.Row="9" Grid.Column="0" Text="OS Platform:"></TextBlock>
                <TextBlock Grid.Row="9" Grid.Column="1" x:Name="txtOSPlatform"></TextBlock>
            </Grid>
        </controls:PivotItem>
        <controls:PivotItem Header="User">
            <StackPanel>
                <TextBlock Text="Anonymous Live Id"></TextBlock>
                <TextBlock x:Name="txtAnonymousLiveId" Margin="0,20,0,0" TextWrapping="Wrap"></TextBlock>
            </StackPanel>
        </controls:PivotItem>
    </controls:Pivot>
</Grid>

Nel code behind (il file MainPage.xaml.cs) andiamo invece a recuperare le varie proprietà e a visualizzarle nella TextBox appropriata. Di seguito riporterò un esempio per ognuna delle tipologie di informazioni (device, utente e versione del sistema operativo). In fondo al post troverete il link al codice sorgente, dove potrete visualizzare il progetto completo.

Device

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    DispatcherTimer timer=new DispatcherTimer();
    timer.Interval=new TimeSpan(0,0,0,1);
    timer.Tick += new EventHandler(timer_Tick);
    timer.Start();
}

void timer_Tick(object sender, EventArgs e)
{
    txtCurrentMemoryUsage.Text = string.Format("{0} byte",
                                               DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"));

    txtPeakMemoryUsage.Text = string.Format("{0} byte",
                                            DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage"));
}

L’utilizzo della classe DeviceExtendedProperties è molto semplice: ci basta chiamare il metodo GetValue passandogli la chiave che corrisponde all’informazione che vogliamo recuperare (nell’esempio ApplicationCurrentMemoryUsage e ApplicationPeakMemoryUsage). Quello che otterremo sarà un object che, con un semplice cast ad una stringa, conterrà l’informazione desiderata.

La particolarità di questo esempio è che sfruttiamo un timer per poter aggiornare ogni secondo l’informazione sulla memoria disponibile nel sistema: ApplicationCurrentMemoryUsage e ApplicationPeakMemoryUsage sono infatti le uniche due proprietà esposte dalla classe DeviceExtendedProperties che non sono statiche, dato che il loro valore può variare durante l’esecuzione (cosa invece impossibile, ad esempio, per il produttore o il modello del device).

Proprio per questo motivo nel progetto d’esempio tutte le altre etichette vengono invece valorizzate direttamente nel metodo MainPage_Loaded, che viene invocato quando il caricamento della pagina è stato completato.

Utente

La classe UserExtendedProperties funziona allo stesso modo della classe DeviceExtendedProperties: quello che voglio mostrarvi è però un approccio alternativo all’utilizzo del metodo GetValue per recuperare l’informazione richiesta, che è disponibile anche per la classe DeviceExtendedProperties

Vediamo il codice:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    object ANID = null;

    if (UserExtendedProperties.TryGetValue("ANID", out ANID) && ANID != null)
        txtAnonymousLiveId.Text = ANID.ToString();
}

Il metodo che utilizziamo si chiama TryGetValue e produce lo stesso effetto di GetValue: ritornare l’informazione richiesta. La differenza è che il metodo ritorna un booleano, che ci dice se il recupero della proprietà è andato a buon fine o meno: in caso positivo, il risultato viene inserito all’interno della variabile che viene passata al metodo come parametro di out (nel nostro esempio, ANID).

In questo modo, non dobbiamo preoccuparci di gestire l’eventuale eccezione che potrebbe scatenarsi nel momento in cui l’informazione che stiamo cercando di recuperare non esista: l’esempio non è stato fatto a caso con l’Anonymous Live Id. Se testate questo codice con l’emulatore o con un device per il quale non è stato ancora associato un Live Id, il metodo TryGetValue vi ritornerà false.

Questo tipo di approccio non è una novità del mondo .NET: ci sono tante altre classi che implementano un sistema analogo (ad esempio, la classe Int32 implementa il metodo TryParse che viene utilizzato per la conversione da stringhe a numeri interi e vi permette di gestire facilmente l’eccezione che si scatenerebbe se cercate di convertire una stringa che non rappresenta un numero, ad esempio “foo”).

Versione del sistema operativo

Per recuperare la versione del sistema operativo occorre utilizzare un’altra classe, chiamata Environment, che espone le seguenti informazioni sul sistema operativo tramite la proprietà OSVersion

  • Platform: la piattaforma su cui è basato l’OS.
  • Version: è una proprietà composta, che contiene le seguenti informazioni sul numero di versione del sistema operativo:
    • Major Number
    • Minor Number
    • Build Number
    • Revision Number

Ecco un esempio di codice in cui valorizziamo un’etichetta con la piattaforma e il numero di versione:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    txtOSVersion.Text = string.Format("{0}.{1}.{2}.{3}", Environment.OSVersion.Version.Major,
                                              Environment.OSVersion.Version.Minor, Environment.OSVersion.Version.Build,
                                              Environment.OSVersion.Version.Revision);

    txtOSPlatform.Text = Environment.OSVersion.Platform.ToString();
}
La versione attuale di Windows Phone 7 restituisce Win CE come Platform e 7.0.7004 –1 come OSVersion.

Maneggiare con cura

Due sono le considerazioni importanti da tenere ben presente quando vogliamo utilizzare queste due classi.

La prima è ricordarsi di impostare le capabilities corrette nel file manifest, altrimenti otterrete un eccezione quando cercherete di recuperare delle informazioni sul device o sull’utente.

La seconda è di usarle solo se strettamente necessario: l’utilizzo della classe DeviceExtendedProperties o UserExtedendedProperties fa sì che sul Marketplace, prima del download dell’applicazione, l’utente venga avvisato del fatto che l’applicazione che sta scaricando accede a informazioni sul suo device o sul suo account. Tale messaggio potrebbe far desistere gli utenti maggiormente sensibili al tema privacy, perciò assicuriamoci che le informazioni che stiamo recuperando siano veramente indispensabili.

Di seguito trovate il link per scaricare il codice sorgente del progetto.


Windows Phone , Microsoft

0 comments

Related Post


(will not be published)
(es: http://www.mysite.com)


  1. #1 da http://qmatteoq.tostring.it/blog/post/coding4fun-una-nuova-libreria-di-microsoft-per-lo-sviluppo-di-applicazioni-per-windows-phone-7-parte-1-i-controlli-2-parte

    qmatteoq.tostring.it - Coding4Fun: una nuova libreria di Microsoft per lo sviluppo di applicazioni per Windows Phone 7 – Parte 1: i controlli (2&#176; parte)