Wp7 Factor: un concorso sullo sviluppo di applicazioni Windows Phone
Posted by qmatteoq in Windows Phone on Tuesday 28 December 2010 at 10:00 AM
Da qualche giorno Microsoft Italia ha lanciato un concorso molto interessante, rivolto agli sviluppatori italiani interessati al mondo Windows Phone. Il concorso è molto semplice e richiede solamente di sviluppare e pubblicare sul Marketplace una o più applicazioni (gratuite o a pagamento) tra il 20 Dicembre 2010 e il 7 Aprile 2011. Il concorso si svilupperà in due fasi.
Prima fase – Estrazione casuale
Tra tutte le app caricate sul Marketplace in questo periodo (contano anche gli aggiornamenti) ne verrà estratta una casualmente ogni settimana, che si aggiudicherà uno Zune Pass annuale (dal valore di 99 €). Ogni applicazione (ovviamente) potrà vincere una e una sola volta.
Per chi non lo sapesse, lo Zune Pass è una forma di abbonamento che vi permette di scaricare a piacimento tutta la musica disponibile sul Marketplace e di riprodurla sui vostri pc, device Windows Phone e console XBox 360. La musica scaricata è protetta da DRM e sarà valida fino al momento in cui Zune Pass è attivo: una volta scaduto, la musica scaricata non sarà più attiva (se cercherete di riprodurla, verrà mostrato un messaggio di errore).
Seconda fase – Le community
Ogni sviluppatore, seguendo una procedura che verrà pubblicata a breve sul sito Microsoft, avrà modo di segnalare la propria applicazione ad uno dei siti partner che aderiscono all’iniziativa. Per ognuna delle community italiane coinvolte verrà istituita una giuria, che selezionerà le 3 migliori applicazioni tra quelle proposte, le quali accederanno al contest finale, per un totale di 27 applicazioni.
Infine, entro il 31 Maggio 2011 una apposita giuria valuterà le 27 applicazioni e voterà le 3 migliori: il vincitore si aggiudicherà un buono da 3000 € spendibile presso Media World, mentre il secondo e il terzo classificato un buono da 1000 € a testa, sempre spendibile presso Media World.
Come vedete, i premi sono veramente allettanti e se avevate una mezza idea di iniziare a sviluppare per questa piattaforma questo concorso sicuramente è un buon incentivo. Anche se non siete dei programmatori professionisti non importa: l’importante è che le applicazioni non siano un mero pretesto per partecipare al concorso, ma rispettino comunque i requisiti di usabilità, stabilità e funzionalità richiesti dalle guidelines. E’ ovvio poi che più alta sarà la qualità delle applicazioni (in termini di innovazione e di design), maggiori saranno le probabilità di accedere alla fase finale e aggiudicarvi i premi più “succosi”.
Vi lascio con l’indirizzo del sito ufficiale del concorso, dove trovate tutti i dettagli e il regolamento completo: http://www.microsoft.it/msdn/concorso
Che informazioni possiamo scoprire sul device e sull’utente da una applicazione Windows Phone 7?
Posted by qmatteoq in Windows Phone Tutorials on Wednesday 22 December 2010 at 10:00 AM
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
)
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.
I report di vendita del Marketplace
Posted by qmatteoq in Windows Phone Marketplace on Monday 20 December 2010 at 10:00 AM
Dopo aver pubblicato la nostra applicazione sul Marketplace, una delle informazioni che sicuramente ci interesserà maggiormente sapere è quante persone hanno scaricato la nostra applicazione e, se questa è a pagamento, quanto abbiamo guadagnato. Fortunatamente, da pochi giorni, Microsoft ha attivato la piattaforma di reporting dell’App Hub, che ci permette di avere tutte le informazioni necessarie per capire “il successo” della nostra applicazione.
Entrando nella sezione Reports, accessibile dal menu laterale di navigazione dell’App Hub, vedremo due informazioni:
- La prima, al centro, è un grafico che ci mostra l’andamento dei download nell’ultimo mese, giorno per giorno.
- La seconda, nella colonna a destra, è il numero di volte che l’applicazione è stata scaricata nell’ultimo mese.
Cliccando sul grafico, accediamo ad una sezione più dettagliata, in cui possiamo filtrare i report e mostrare informazioni più precise. Di default, verrà visualizzato lo stesso grafico che c’era in home page (la view di nome daily). Le altre due modalità di visualizzazione disponibili sono:
- Cumulative: questo grafico vi mostrerà la velocità di crescita della vostra applicazione, mostrando il numero cumulativo di download giorno per giorno. Più la linea del grafico sarà ripida, maggiore sarà cresciuto il numero di download giornaliero della vostra applicazione.
- Data: questa vista non mostra un grafico, ma i dati “grezzi” relativi al numero di download nel periodo selezionato, raggruppati per paese e applicazione.
Tutti i tre tipi di view sono filtrabili in base ai seguenti parametri:
- Start date e End date: l’arco temporale al quale si riferiscono i dati mostrati.
- Country / Region: è possibile visualizzare i report relativi solamente ad uno specifico paese, nel caso in cui la nostra sia un’applicazione distribuita in tutti gli store internazionali.
- Application: nel caso abbiamo pubblicato più di un’applicazione, è possibile scegliere se visualizzare i dati cumulativi di tutte le nostre app oppure solo quelli relativi ad una di esse.
Infine, sempre dalla home page della sezione Reports si accede ad una sottosezione chiamata Payout Reports, che vi permette di visualizzare le statistiche relative ai guadagni. Anche in questo caso il funzionamento è simile, anche se più semplificato, dato che non esistono view: dalla pagina principale si seleziona semplicemente il tipo di report che si vuole (con gli stessi filtri visti in precedenze, quindi periodo temporale, paese e applicazione) e si preme il pulsante Get report. Verrà generato il report richiesto e reso disponibile per la visualizzazione.
Qualche informazione sui pagamenti
Assieme all’attivazione della sezione dei report, Microsoft ha pubblicato qualche informazione più precisa sul sistema di pagamento: essi inizieranno ad essere evasi dalla fine di Gennaio 2011, dopodichè avranno regolare cadenza mensile. Il bonifico verrà inviato nel momento in cui raggiungerete una quota minima di 200 dollari: nel caso in cui non la raggiungiate in un mese, il pagamento verrà posticipato al primo mese utile (ovviamente in questo caso il guadagno del mese corrente viene sommato a quelli precedenti per i quali non avete ricevuto il pagamento). Se un mese, ad esempio, guadagnate solamente 100 dollari, il mese successivo ve ne basterà guadagnare altrettanti per ricevere il pagamento relativo ai due mesi (100 + 100 = 200).
E per l’advertising?
Microsoft ha reso disponibile un controllo nativo per l’implementazione della pubblicità nelle proprie applicazioni, il cui utilizzo è veramente semplice (qui trovate la documentazione e qui il download). Il problema è che, attualmente, la piattaforma non è disponibile in Europa: questo significa che potrete inserire il controllo nelle vostre applicazioni, ma che i banner visualizzati saranno solamente relativi a prodotti e servizi made in USA. Inoltre, non sarà possibile riscuotere gli introiti derivanti dalla pubblicità: è prevista però per l’anno prossimo l’apertura della piattaforma anche al mercato europeo.
Il processo di submit di un’app nel Marketplace: alcuni consigli
Posted by qmatteoq in Windows Phone , Marketplace Tutorials on Friday 17 December 2010 at 10:00 AM
Dopo aver visto come creare un account sull’App Hub e come pubblicare un’applicazione, ecco qualche consiglio sui casi d’uso più comuni che si possono verificare usando il portale di Microsoft.
A quali informazioni ho accesso?
Entrando nella sezione Windows Phone dell’App Hub, troverete l’elenco di tutte le applicazioni che avrete inviato, con indicato lo stato corrente, che può essere:
- Published to Marketplace: l’applicazione è stata approvata ed è disponibile sul Marketplace.
- Ready for testing: l’applicazione è stata inviata al team di certificazione ed è pronta per essere testata.
- Testing in progress: l’applicazione è stata presa in carico dal team di certificazione.
- Submission in progress: durante il processo di submit avete la possibilità, in qualsasi momento, di salvare le informazioni inserite fino a quel momento e di concludere l’operazione in un secondo momento. Questo è lo stato che viene mostrato quando esiste una “bozza” di submit in corso.
Cliccando sul pulsante View details accederete alla pagina di dettaglio, in cui verranno riepilogate tutte le informazioni che avete inserito in fase di pubblicazione. In questa pagina troverete una versione della vostra applicazione per ogni submission che avete in corso. Questo significa che ci sarà sempre un’icona per la versione attualmente sul Marketplace e una per l’eventuale update in fase di certificazione, submission o rifiutato. Questo perchè le operazioni che potete compiere sono diverse: in più in questo modo avete la possibilità di agire solo su una specifica versione, così da poter abilitare, ad esempio, la trial solamente solo sull’update e non sulla versione originale (nel caso in cui l’abbiate implementata in un secondo momento).
Nel momento in cui il vostro update sarà stato approvato, l’App Hub tornerà a mostrare una sola versione.
La mia applicazione è stata rifiutata: cosa è successo?
La prima cosa da fare è scoprire i motivi per cui è stata rifiutata: entrando nell’App Hub troverete la vostra applicazione in stato Testing failed. Entrate nel dettaglio e, nel menu a tendina Action, selezionate l’opzione View test results: vi verrà proposto il download di un report in PDF. Questo è sicuramente uno dei punti di forza dell’App Hub: il report infatti è molto dettagliato e per ogni problematica riscontrata vi indicherà:
- Una descrizione del problema.
- La motivazione per la quale quel problema viola le guidelines.
- Una spiegazione passo per passo di come riprodurre il problema.
- Il numero di prove fatte dal tester e in quanti casi è riuscito a riprodurlo.
Ora avete in mano tutti gli strumenti necessari per sistemare il vostro problema.
(Un ringraziamento ad Alessandro Scardova per lo screenshot)
Ho sistemato il problema: come carico la nuova versione?
L’App Hub non prevede un comando diretto per fare questa cosa: la best practise sarebbe quella di scegliere Delete submission dal menu a tendina Action e procedere con un nuovo submit. Il problema è che questo sistema vi fa perdere parecchio tempo, dato che dovrete reinserire da capo tutte le informazioni. Il trucco per evitare questo fastidio è quello di selezionare dal menu a tendina la voce Edit application: in questo modo verrà ripetuto l’intero processo di submission da capo, con la differenza però che tutte le informazioni saranno già valorizzate. Le operazioni indispensabili da fare sono:
- Caricare il nuovo XAP nello step 1.
- Apportare una modifica qualsiasi nello step 2 (basta anche solamente inserire uno spazio nella descrizione).
A questo punto se avete fatto tutto correttamente, arrivati al penultimo step (la definizione del prezzo) dovreste trovare il pulsante Submit for testing, che vi porterà dritti all’ultimo step. Una volta completato anche questo passaggio, tornerete all’App Hub e vedrete lo stato della vostra applicazione cambiare in Ready for testing, per diventare infine dopo qualche minuto Testing in progress.
Se nello step 4 non trovate il pulsante Submit for testing ma solo Save & Quit, attenzione: vuol dire che l’App Hub non ha rilevato alcuna modifica e non vi da la possibilità di fare il submit. In questo assicuratevi di aver completato entrambi gli step indicati prima e riprovate.
In generale, quando state caricando una nuova versione assicuratevi sempre che al termine della procedura lo stato sia Ready for testing o Testing in progress: se trovate lo stato Submission in progress vuol dire che qualcosa è andato storto, ovvero che l’applicazione non è stata inviata per la certificazione ma è “congelata” in attesa che voi completiate la procedura.
Ho preparato un update per la mia applicazione: come lo carico?
Nel momento in cui avete un’applicazione pubblicata sul Marketplace, avete la possibilità di caricare un nuovo update: per farlo, vi basta accedere alla pagina di dettaglio della vostra applicazione nell’App Hub e, dal menu a tendina Action, scegliere la voce Submit application update. A questo punto il procedimento sarà lo stesso di submit di una nuova applicazione: vi verranno richieste le informazioni e, purtroppo, dovrete reinserirle tutte, anche se non avete intenzione di cambiarle rispetto alla versione precedente. Il mio consiglio, perciò, è quello di creare una cartella sul vostro computer dove tenere a portata di mano tutto il materiale necessario per l’update: testi, keywords, icone e screenshot.
Voglio modificare alcune delle informazioni pubblicate sul Marketplace: come faccio?
Non potete: l’unico momento in cui potete modificare la maggior parte delle informazioni visualizzate sul Marketplace è quando fate il submit della vostra applicazione (indipendentemente dal fatto che sia la prima release o un update). Nello specifico, le informazioni che non potete modificare sono quelle richieste agli step 1, 2 e 3: descrizione, categoria, nome, keywords, icone e screenshots.
L’unica informazione che è modificabile in qualsiasi momento è il prezzo della vostra applicazione: selezionando infatti dal menu a tendina Action l’opzione Edit pricing verrete portati direttamente allo step 4, dove potrete modificare il costo, la disponibilità negli store internazioni e il supporto alla trial.
Il processo di submit di un’app nel Marketplace: la pubblicazione
Posted by qmatteoq in Windows Phone , Tutorials Marketplace on Wednesday 15 December 2010 at 10:00 AM
Ora che, seguendo le indicazioni del post precedente, abbiamo un account attivo e valido per l’App Hub, siamo pronti per procedere con il submit vero e proprio. Entriamo nella dashboard di Windows Phone e scegliamo Submit new application per iniziare la procedura.
Step 1: upload e informazioni tecniche
Nel primo step andremo a caricare lo XAP (il pacchetto prodotto da Visual Studio quando compiliamo un’applicazione Windows Phone) e a definire alcune informazioni tecniche sulla nostra applicazione.
- Application Name: si tratta di un nome identificativo della nostra applicazione, che verrà visualizzato nella nostra Dashboard. Attenzione, questo nome non coincide con il titolo dell’applicazione che verrà visualizzato sul Marketplace: questa informazione verrà inserita nello step successivo.
-
Application Platform: la piattaforma su cui gira la nostra applicazione (noi andremo a scegliere Windows Phone 7, ma vien
- Default language: la lingua in cui è localizzata la vostra applicazione. Se supporta più lingue, in questo campo dovrete scegliere quella principale.
- Version: il numero di versione della nostra applicazione. Tale informazione viene visualizzata sul Marketplace, è perciò buona regola incrementare il numero di release ad ogni update, utilizzando magari il numero decimale per le release minori (ad esempio, 1.2) e il numero intero per le major releases (ad esempio, 2.0).
- Application package: cliccando sul pulsante + avrete modo di cercare sul vostro computer il file XAP della vostra applicazione, che viene creato da Visual Studio nella cartella bin/release del vostro progetto. Attenzione: ricordatevi di compilare il progetto in modalità release e di non caricare XAP compilati in modalità debug, dato che non verranno accettati.
- Developer notes: si tratta di un campo opzionale, in cui possiamo inserire delle informazioni utili per noi (ad esempio, delle note tecniche sulla release che stiamo inviando che ci potrebbero servire in futuro).
- Tester notes: anche in questo caso si tratta di un campo opzionale, ma è molto importante perchè ci permette di inserire informazioni che le persone che testeranno la nostra applicazione leggeranno. Possiamo perciò ad esempio specificare delle credenziali di accesso (nel caso la nostra applicazione si colleghi a qualche servizio) o delle istruzioni su come configurarla.
- Requires technical exception: in casi speciali è possibile richiedere una deroga rispetto a quanto indicato nelle guidelines che devono rispettare le applicazione Windows Phone. La procedura è piuttosto burocratica (giustamente, dato che le motivazioni devono essere più che valide) e richiedono la compilazione di un modulo specifico (scaricabile all’indirizzo http://go.microsoft.com/fwlink/?LinkID=201159) che deve essere inviato assieme alla submission. Attenzione: questa procedura incrementa di diversi giorni il tempo necessario per l’approvazione.
Nel secondo step andremo a inserire una serie di informazioni molto importanti, che verranno visualizzate sul Marketplace da parte degli utenti: descrizione, categoria, ecc.
Questo step viene ripetuto per ognuna delle lingue che è supportata dalla nostra applicazione.
In questa sezione andremo a caricare tutte le informazioni visuali che verranno mostrare nel Marketplace: icone, screenshots, ecc.
Questo step viene ripetuto per ognuna delle lingue che è supportata dalla nostra applicazione, anche se di default avete la possibilità di utilizzare sempre lo stesso set di immagini.
In questo e penultimo step andremo a specificare come vogliamo distribuire la nostra applicazione.
Ce l’abbiamo fatta! Ora la nostra applicazione è pronta per essere inviata ai tester, che si occuperanno di valutare la nostra applicazione sia per i contenuti che dal punto di vista tecnico. L’unica opzione che abbiamo a disposizione in questo step è un checkbox, che ci da la possibilità di sceglire se pubblicare l’applicazione in automatico una volta superato il processo di certificazione oppure attendere un intervento manuale da parte nostra.
In entrambi i casi, riceveremo una mail al termine del processo di validazione, che vi avviserà dell’esito positivo o negativo dei test.
Nel prossimo post vedremo la gestione del ciclo di vita di un’applicazione nell’App Hub: come fare il submit di un aggiornamento, cosa fare nel caso in cui la nostra applicazione sia stata rifiutata e così via.
Step 2: le informazioni per il Marketplace
Step 3: le immagini
Step 4: la distribuzione

Step 5: ci siamo!
Il processo di submit di un’app nel Marketplace: i prerequisiti
Posted by qmatteoq in Windows Phone Tutorials on Monday 13 December 2010 at 10:00 AM
Dal 3 Novembre il Marketplace ha aperto le porte a tutti gli sviluppatori: prima di tale data solo alcuni sviluppatori selezionati avevano la possibilità di effettuare il submit di applicazioni per Windows Phone 7. Ora che questa possibilità è data a tutti, in tanti saranno sicuramente interessati a conoscere meglio l’App Hub, il portale creato appositamente da Microsoft per la gestione e il caricamento delle nostre applicazioni sul Marketplace.
In questo primo post vedremo i requisiti necessari per poter procedere con il submit.
La registrazione
Il primo passo da fare è ovviamente registrarvi sul portale App Hub: l’indirizzo è http://create.msdn.com/en-US/ e da lì, accedendo alla sezione Membership, vi verrà mostrato un riepilogo informativo e il pulsante per procedere con la registrazione vera e propria. Prima nota importante: come per tutti i portali Microsoft, la registrazione richiede un account Live. Fate ben attenzione ad usare un account Live di tipo italiano e non americano, altrimenti potreste andare incontro a una serie di problemi molto difficili da risolvere. Se non siete sicuri, il mio consiglio è quello di creare un account Live apposta da utilizzare con il Marketplace.
Step 1: il tipo di account
In questo primo step sono due le informazioni richieste:
- La nazione in cui vivete.
- Il tipo di account, a scelta tra aziendale, personale e studenti (vi ricordo che se siete studenti iscritti al programma DreamSpark avete la possibilità di iscrivervi all’App Hub senza pagare la quota di iscrizione).

Step 2: i dati personali
Questo step richiede una serie di dati personali, che non commenterò uno ad uno dato che sono autoesplicativi (nome, cognome, indirizzo, ecc.). Sappiate solo che, in caso vi stiate registrando come company, la schermata sarà leggermente diversa, dato che chiederà anche le informazioni relative alla vostra azienda.

Step 3: informazioni sul profilo
Premessa: l’App Hub ha un suo forum specifico per la discussione sui temi e sulle problematiche relative al submit di applicazioni. Tale forum non fa parte del gruppo dei forum MSDN, perciò non utilizza le impostazioni del vostro profilo, nel caso ne abbiate già uno. In questo step quello che andrete a fare perciò sarà specificare le informazioni necessarie per partecipare al forum, quindi il vostro nome e il vostro avatar.
Tipicamente il Display Name coincide con il Publisher Name specificato in fase di registrazione: vi verrà data la possibilità di specificarne uno alternativo nel caso quello da voi impostato sia già in uso. Attenzione che la validità del Display Name verrà verificato insieme alla vostra identità (vedi paragrafo successivo), per evitare che un utente possa utilizzare marchi o nomi registrati senza averne l’autorizzazione.
Infine vi verrà chiesto il Gamertag, che è il vostro nickname per il mondo XBox Live: tale informazione viene richiesta dato che l’App Hub può essere utilizzato anche per il submit di giochi XBox per la sezione Live Arcade.

Step 4: il pagamento
Come ho già ricordato, l’iscrizione all'App Hub ha un costo di 79€ annuali: ecco perciò che in questo step vi verranno richieste le informazioni della carta di credito con cui effettuerete il pagamento.
Step 5: conclusione
Il processo di registrazione è concluso, ma in realtà non siamo ancora pronti per utilizzare il nostro account. Gli altri due step necessari sono:
- Verifica della validità dell’indirizzo mail, tramite un link che ricevermo nella casella che abbiamo specificato in fase di registrazione.
- Verifica della nostra identità da parte di GeoTrust

La verifica della nostra identità
Una volta completata la fase di registrazione, il vostro account non sarà immediatamente attivo: l’attivazione di un account richiede infatti una verifica della vostra identità, necessaria dato che ci sono delle transizioni economiche in ballo. Per questa verifica riceverete una mail da GeoTrust, partner di Microsoft a cui è delegata tutta la procedura di identificazione: tale mail conterrà un documento, che dovrete compilare in tutte le sue parti, allegando una copia di un vostro documento d’identità (la mail parla di passaporto o patente di guida, ma anche la semplice carta d’identità va bene).
Il documento va necessariamente stampato, dato che dovrete firmarlo: dopodichè potete scegliere di inviarlo via fax, oppure scansirlo e mandarlo via mail.
Se avete compilato tutto correttamente, nel giro di qualche giorno riceverete una mail di conferma da GeoTrust, i quali si incaricheranno di portare avanti la vostra pratica girando i documenti necessari a Microsoft. Per sapere se la pratica si è conclusa correttamente vi basterà accedere all’App Hub: se qualcuno degli step obbligatori non è stato ancora completato (verifica dell’indirizzo mail, verifica dell’identità, ecc.) troverete un avviso nella pagina dedicata al submit di applicazioni Windows Phone.
Attenzione che se vi state registrando come azienda, la procedura di verifica sarà più complessa, dato che richiederà una serie di documenti che certifica l’esistenza legale della vostra azienda e che voi siate legalmente abilitati a operare per conto dell’azienda.
La documentazione W-7 e W-8 BEN
Questo step è obbligatorio solamente nel caso in cui abbiate intenzione di pubblicare applicazioni a pagamento: fintanto che inviate applicazioni gratuite continuerà a comparire una notifica nell’App Hub, ma ciò non vi impedirà di fare il submit.
Tra Italia e USA esiste un accordo commerciale che garantisce che sui guadagni provenienti dagli Stati Uniti non venga applicata una doppia tassazione da entrambi gli stati: per ottenere questo beneficio è però necessario compilare una serie di documenti, nello specifico i moduli chiamati W-7 (necessario per ottenere l’ITIN, una sorta di codice fiscale che ci identifica univocamente) e W-8 BEN.
Si tratta di due documenti piuttosto complessi da compilare, soprattutto se siete a digiuno di burocrazia: fortunatamente Alessandro Del Sole, MVP italiano, ha deciso di condividere la sua esperienza scrivendo sul forum MSDN dedicato a Windows Phone 7 una guida molto approfondita che vi spiegherà passo per passo cosa fare e che vi darà una esauriente panoramica dei risvolti legali di questo documento. Un grosso grazie per il lavoro che ha fatto!
What’s next?
Ora che abbiamo soddisfatto tutti i requisiti necessari e abbiamo attivato il nostro account, siamo pronti per vedere nel prossimo post il processo vero e proprio di pubblicazione di un’applicazione Windows Phone 7.
Come mantenere un’applicazione attiva anche quando il device è bloccato – Parte 2: un esempio più avanzato
Posted by qmatteoq in Windows Phone Tutorials on Friday 10 December 2010 at 10:00 AM
Dopo aver introdotto nel post precedente la possibilità per le applicazioni Windows Phone di rimanere attive anche a device bloccato, vediamo in questo post un esempio più concreto: un timer che continua a rimanere attivo anche quando blocchiamo lo schermo. Per implementarlo, però, non useremo lo stesso approccio adottato nel post precedente ma faremo uso di un helper realizzato da Jaime Rodriguez, evangelist di Microsoft molto attivo sullo sviluppo Windows Phone, e descritto in questo post sul suo blog.
Qual è il vantaggio di usare questo helper? Principalmente uno, ovvero una gestione più intelligente di uno dei limiti di questa feature: l’impossibilità di cambiare la modalità di funzionamento dell’applicazione a runtime, ovvero mentre l’applicazione è in esecuzione. Cosa significa? Che se noi nel nostro programma impostiamo la proprietà PhoneApplicationService.Current.ApplicationIdleMode a IdleDetectionMode.Disabled (disabilitando perciò la sospensione) e poi cerchiamo di riabilitarla, questa modifica non avrà effetto se non dopo aver riavviato l’applicazione.
Come vedremo, l’helper ci mette a disposizione una serie di proprietà e metodi che possiamo sfruttare per far scegliere all’utente se abilitare o meno questa feature e gestire tutte le casistiche collegate.
La classe ApplicationIdleModeHelper
Questa classe è un singleton: questo significa che non deve essere istanziata ogni volta, ma che avremo una e un’unica istanza (tramite la proprietà Current) che verrà condivisa da tutte le classi e le pagine della nostra applicazione. Tale classe espone le seguenti proprietà:
- RunsUnderLock: è una proprietà di tipo booleano che, quando viene impostata a true, disabilita la sospensione dell’applicazione, per poi riabilitarla quando la impostiamo a false. Equivale a impostare la proprietà PhoneApplicationService.Current.ApplicationIdleMode a IdleDetectionMode.Disabled (true) o IdleDetectionMode.Enabled (false), come nell’esempio del post precedente. La differenza è che l’helper implementa un meccanismo tale per cui se impostiamo a false questa proprietà viene scatenato un evento che ci notifica della necessità di riavviare l’applicazione.
- HasUserAgreedToRunUnderLock: anche questa è una proprietà di tipo booleano, che ci può essere utile se vogliamo gestire all’interno della nostra applicazione un messaggio di warning che chieda all’utente conferma se vuole sospendere o meno l’applicazione al lock. Il valore di questa proprietà viene persistito nell’Isolated Storage: può essere perciò utilizzato in qualsiasi punto del nostro programma.
- IsRestartRequired: questa proprietà viene valorizzata automaticamente a true nel momento in cui riattiviamo la sospensione dell’applicazione. Essa non viene persistita, dato che viene automaticamente resettata ad ogni avvio.
- IsRunningUnderLock: anch’essa è una proprietà di tipo booleana, che possiamo utilizzare nella nostra applicazione per determinare se in quel momento è in esecuzione a device bloccato oppure no.
In più, vengono esposti i seguenti eventi:
- Obscure e Unonscured: sono gli stessi eventi che abbiamo visto nel post precedente e che vengono esposti dalla classe PhoneApplicationFrame. L’helper, in questo caso, funge da wrapper.
- RestartRequired: questo evento viene scatenato nel momento in cui la proprietà RunsUnderLock passa da True a False ed è perciò necessario un riavvio dell’applicazione perchè la modifica venga eseguita.
Un esempio concreto: un timer
Andremo ora a realizzare un semplice timer, che continuerà a funzionare anche nel momento in cui bloccheremo il device: per farlo useremo proprio l’helper di cui abbiamo appena parlato. In più, daremo all’utente la possibilità di scegliere se abilitare o meno la possibilità di mantenere attivo il timer anche a device bloccato. Infine, nel momento in cui l’utente cercherà di attivare l’opzione, comparirà un messaggio che richiederà un’ulteriore conferma.
Partiamo dal semplice XAML del ContentPanel della nostra pagina:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<CheckBox x:Name="cbStatus" Unchecked="cbStatus_Unchecked" Checked="cbStatus_Checked" Content="Runs under lock?"></CheckBox>
<Button Content="Apply settings" Click="Button_Click"></Button>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20,0,0">
<TextBlock Text="Timer: " FontSize="24"></TextBlock>
<TextBlock x:Name="tbTimer" FontSize="24"></TextBlock>
</StackPanel>
</StackPanel>
</Grid>
Abbiamo inserito i seguenti elementi:
- Un checkbox, con etichetta Runs under lock?, a cui abbiamo associato due diversi eventi: Checked, che viene scatenato quando il controllo viene selezionato, e Unchecked, che viene scatenato quando il controllo viene deselezionato
- Un pulsante, che verrà utilizzato per salvare le impostazioni che abbiamo scelto tramite il checkbox.
- Uno StackPanel, con all’interno due TextBox che visualizzano il timer vero e proprio.
Ora siamo pronti a inserire il codice vero e proprio: prima però abbiamo bisogno di importare nel nostro progetto l’helper di Jaime Rodriguez. Scarichiamo il progetto di esempio da lui realizzato da qui, scompattiamolo da qualche parte e includiamo il file ApplicationIdleModeHelper.cs nel nostro progetto: per farlo, ci basta fare clic con il tasto destro sul progetto in Visual Studio e scegliere Add, Existing item e andare a cercare il file sul nostro computer.
Ora posizioniamoci nel code behind della nostra view (nel nostro caso, il file MainPage.xaml.cs) e importiamo il namespace LearningWindowsPhone.RunUnderLock; a questo punto siamo pronti per utilizzare l’helper.
Vediamo ora il codice completo della nostra applicazione:
public partial class MainPage : PhoneApplicationPage
{
private DispatcherTimer timer;
private int cont = 0;
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ApplicationIdleModeHelper.Current.RestartRequired += new EventHandler(Current_RestartRequired);
timer = new DispatcherTimer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval=new TimeSpan(0,0,0,1);
timer.Start();
}
void Current_RestartRequired(object sender, EventArgs e)
{
MessageBox.Show("Restart required");
}
void timer_Tick(object sender, EventArgs e)
{
cont++;
tbTimer.Text = cont.ToString();
}
private void cbStatus_Unchecked(object sender, RoutedEventArgs e)
{
ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock = false;
}
private void cbStatus_Checked(object sender, RoutedEventArgs e)
{
MessageBoxResult result = MessageBox.Show("Are you sure you want to disable suspend when the device is locked?", "Obscure demo", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock = true;
else
{
cbStatus.IsChecked = false;
ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock = false;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ApplicationIdleModeHelper.Current.RunsUnderLock =
ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock;
}
}
In questa semplice applicazione utilizziamo l’helper per:
- gestire l’attivazione o la disattivazione della sospensione dell’applicazione tramite la proprietà RunsUnderLock.
- sottoscriverci all’evento RestartRequired: ogni qualvolta la proprietà RunsUnderLock passa da true a false, in automatico verrà eseguito il metodo Current_RestartRequired, che mostra un semplice messaggio di avviso all’utente.
- chiedere all’utente una conferma e valorizzare la proprietà HasUserAgreedToRunUnderLock in base alla sua scelta.
Proviamo a lanciare l’applicazione e vediamo cosa succede:
- Il timer viene attivato: vedremo il contatore incrementarsi ad ogni secondo.
- Se ora proviamo a bloccare il device, aspettiamo qualche secondo e poi lo sblocchiamo, vedremo comparire il messaggio Resuming e il timer ripartire da zero: questo perchè l’applicazione è stata sospesa e, dato che non abbiamo gestito il tombstoning, al ripristino sarà come se fosse stata aperta per la prima volta.
- Facciamo ora tap sul checkbox: comparirà un messaggio che ci chiederà conferma se vogliamo procedere. Solo se premiamo Ok, il checkbox verrà selezionato. Quello che succede dietro le quinte è che andiamo a valorizzare la proprietà HasUserAgreedToRunUnderLock a true solo se l’utente ha scelto Ok.
- Premiamo il pulsante Apply settings: la proprietà RunsUnderLock verrà valorizzata con lo stesso valore della proprietà HasUserAgreedToRunUnderLock (nel nostro caso, true). Ora proviamo a bloccare nuovamente il device e a risbloccarlo dopo qualche secondo. Questa volta l’applicazione sarà disponibile istantaneamente e potremo notare che il timer ha continuato a incrementarsi anche mentre il device era bloccato.
- Ora facciamo l’ultimo esperimento: rifacciamo tap sul checkbox, così da deselezionarlo, e premiamo Apply settings. Apparirà un messaggio che ci comunicherà che è necessario un riavvio dell’applicazione: questo perché abbiamo cambiato il valore della proprietà RunsUnderLock da true a false. L’helper ha perciò scatenato l’evento RestartRequired, al quale abbiamo associato il metodo Current_RestartRequired che, per l’appunto, mostra il messaggio a video.
In conclusione
In questo post abbiamo visto un’applicazione in grado di rimanere in esecuzione anche a device bloccato: per realizzarla, abbiamo sfruttato un helper realizzato da Jaime Rodriguez, che ci ha permesso di gestire con maggiore facilità alcuni casi particolari nella gestione di questa feature (uno su tutti, la necessità di dover riavviare l’applicazione quando si verificano determinate condizioni). Se volete approfondire l’argomento, vi consiglio di leggervi (in inglese) il post di Jaime Rodriguez e di scaricare il progetto di esempio da lui realizzato: un’applicazione in grado di riprodurre un file audio anche a device bloccato. Come sempre, di seguito trovate il link per scaricare il progetto di esempio utilizzato in questo post.
Come mantenere un’applicazione attiva anche quando il device è bloccato – Parte 1: le basi
Posted by qmatteoq in Windows Phone Tutorials on Thursday 09 December 2010 at 10:00 AM
Si è parlato molto di questa feature con la presentazione delle nuova revisione delle guidelines per la pubblicazione di applicazioni sul Marketplace: molte persone infatti l’avevano scambiata per una novità, quando in realtà è sempre esistita sin dalla versione RTM dei tools. Quello che le nuove guidelines hanno introdotto è una minor ristrettezza nei requisiti da rispettare: prima era obbligatorio avvisare sempre l’utente se si faceva uso di questa caratteristica, ora invece non è più necessario, a patto che si rispettino tutti i requisiti.
Ma facciamo un passo indietro: di cosa stiamo parlando? Il comportamento di default di un’applicazione Windows Phone quando il device viene bloccato è la sospensione, esattamente come se avessimo premuto il pulsante Start del device. Ecco perciò che entra in gioco il tombstoning e viene scatenato l’evento Application_Suspended.
Questo scenario però può stare stare stretto ad alcune tipologie di applicazioni: pensiamo ad esempio ad un programma per tenere traccia dei nostri spostamenti o per ascoltare una radio tramite Internet. E’ uno scenario più che probabile che l'utente voglia continuare ad usarla anche una volta messo in tasca il device e, per compiere questa operazione, deve ovviamente bloccare il telefono.
Ecco perciò che i tool di sviluppo per Windows Phone ci danno la possibilità di cambiare il comportamento di default delle applicazioni e di far si che queste non vengano più sospese nel momento in cui il device viene bloccato.
Ricordate la classe PhoneApplicationService, che espone il dictionary State che viene utilizzato per gestire il tombstoning e mantenere in memoria dati quando la nostra applicazione viene sospesa? Una delle proprietà esposte da questa classe si chiama ApplicationIdleDetectMode e può assumere due valori:
- IdleDetectionMode.Enabled: è il comportamento standard, l’applicazione viene sospesa quando il device viene bloccato.
- IdleDetectioMode.Disabled: viene impostato quando vogliamo che la nostra applicazione continui a rimanere attiva anche a device bloccato.
Una volta che abbiamo impostato questa proprietà nel modo corretto, siamo pronti per intercettare due eventi esposti dalla classe PhoneApplicationFrame, che rappresenta la “finestra” all’interno della quale vengono caricate le pagine della nostra applicazione. I due eventi sono:
- Obscure: l’evento viene scatenato quando il device viene bloccato. Tipicamente, viene utilizzato per “liberare” tutte le risorse non necessarie così da ridurre il consumo di batteria al minimo mentre l’applicazione è in esecuzione a schermo bloccato.
- Unobscure: l’evento viene scatenato quando il device viene sbloccato. Tipicamente, viene utilizzato per riportare l’applicazione allo stato originale.
Un esempio concreto
Vediamo un esempio pratico: una semplice applicazione in cui una TextBox viene valorizzata nel momento in cui il device viene bloccato.
Ecco il semplice codice XAML che inseriremo nella ContentGrid della nostra view (nel mio caso, il file MainPage.xaml).
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock x:Name="tbStatus"></TextBlock>
</StackPanel>
</Grid>
Ora vediamo invece il codice della view (che inseriremo nel file MainPage.xaml.cs):
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
PhoneApplicationFrame appFrame = App.Current.RootVisual as PhoneApplicationFrame;
appFrame.Obscured += new EventHandler<ObscuredEventArgs>(appFrame_Obscured);
}
void appFrame_Obscured(object sender, ObscuredEventArgs e)
{
tbStatus.Text = "Obscured";
}
}
Le operazioni essenziali che andiamo a fare sono due:
- Al caricamento della pagina, andiamo a disabilitare l’Idle Detection Mode, ovvero la sospensione dell’applicazione al blocco dello schermo. Inoltre, andiamo a recuperare l’istanza corrente della nostra applicazione della classe PhoneApplicationFrame e la utilizziamo per sottoscrivere l’evento Obscured.
- Nel metodo appFrame_Obscured (che poche righe sopra abbiamo associato all’evento Obscured) andiamo a scrivere un testo nella nostra TextBox.
Ora possiamo testare la nostra applicazione: attenzione che, per testare questa feature, abbiamo bisogno di un device reale; l’emulatore infatti non consente di simulare il lock del device. Facciamo il deploy in Visual Studio e, ad applicazione in esecuzione, blocchiamo il telefono. Ora sblocchiamolo e noteremo due cose:
- La prima è che l’applicazione si è comportata correttamente: la nostra TextBlock conterrà il testo Obscured.
- Tutte le volte che un’applicazione passa dallo stato Suspended allo stato Active appare per qualche secondo la scritta Resuming: maggiore è il numero di operazioni da fare al ripristino (il caricamento dei dati dal tombstone, ad esempio) maggiore sarà il tempo necessario perchè l’applicazione ritorni attiva. Nel nostro caso invece la scritta non apparirà, ma vedremo subito la nostra pagina: questo perchè l’applicazione non è stata sospesa, ma è rimasta in esecuzione.
Nella prossima puntata 
Nel prossimo post vedremo un esempio più concreto di applicazione che sfrutta la feature che abbiamo visto oggi: inoltre vedremo in dettaglio alcune importanti considerazioni tecniche e infine useremo un approccio alternativo per realizzare quanto abbiamo fatto oggi, sfruttando un helper di terze parti che ci mette a disposizione una serie di utilità proprietà. Come sempre, è a disposizione il codice sorgente dell’esempio utilizzato in questo post.
Say hello to Silverlight 5!
Posted by qmatteoq in Silverlight on Monday 06 December 2010 at 10:00 AM
Uno degli obiettivi di Silverlight Firestarter (l’evento tenuto in quel di Redmond Giovedì 2 Dicembre) era quello di rilanciare Silverlight, dopo tutte le “polemiche” nate in seguito alle dichiarazioni fatte durante la PDC che erano state interpretate come un segno da parte di Microsoft di voler abbandonare la piattaforma.
Bene, diciamo che l’obiettivo è stato centrato in pieno, dato che Scott Guthrie ha presentato durante il keynote Silverlight 5, la nuova versione della piattaforma. Due premesse: la prima è che non si tratta di una rivoluzione, bensì di una evoluzione. Supporto alla grafica 3D a parte, tutte le altre feature che vedremo in dettaglio non sono delle novità in senso assoluto, ma dei miglioramenti che hanno come obiettivo quello di semplificare la vita agli sviluppatori (ad esempio, il debug del binding) e di rendere sempre più convergenti WPF e Silverlight (l’introduzione delle custom markup extensions ne è un esempio).
L’altra premessa è di non trattenere il respiro nell’attesa di poter iniziare a lavorare con Silverlight 5: la prima beta è prevista in Primavera, mentre la release finale è data in uscita per la seconda metà del 2011.
Vediamo ora quali sono queste novità e miglioramenti, raggruppate per categoria.
La riproduzione video
Uno degli ambiti in cui Silverlight eccelle da sempre è la riproduzione video: grazie alle enormi potenzialità della piattaforma, è possibile gestire la riproduzione di flussi video sfruttando feature quali smooth streaming, full screen, supporto all’HD,ecc.
Silverlight 5 introdurrà il supporto all’accelerazione hardware per la riproduzione dei flussi: in questo modo la decodifica dei video potrà essere fatta sfruttando la GPU (il processore della scheda video), scaricando di fatto notevolmente il lavoro della CPU. In questo modo sarà possibile riprodurre filmati ad alta qualità anche su computer poco potenti, con un minor utilizzo di risorse e un minor consumo di batteria (nel caso di netbook e notebook).
Un’altra novità si chiama TrickPlay e introduce il supporto alle funzionalità tipiche di un videoregistratore all’interno di un player video: Rewind, Fast Forward nonchè la possibilità di cambiare la velocità di riproduzione.
Infine, sono state introdotte una serie di funzionalità che consentiranno di realizzare player video che si comportano in tutto e per tutto come delle vere e proprie applicazioni desktop: gestione intelligente dello screen saver (che viene disabilitato quando si sta guardando un video), supporto a remote controller, miglior performance e minor consumo di risorse, ecc.
WCF & RIA Services
Silverlight 4 offre già un ottimo supporto ai servizi WCF e ai più recenti RIA services, ma manca di alcune feature importanti, come una gestione integrata dell’autenticazione per garantire una comunicazione sicura tra l’applicazione e i servizi.
Silverlight 5 colma questa lacuna, aggiungendo il supporto a WS-Trust, un protocollo per lo scambio di messaggi SOAP sicuri tramite l’utilizzo di token criptati.
In più, è stato aggiunto il supporto ai tipi complessi, a Microsoft Azure nonchè sono state introdotte delle migliore per l’utilizzo del pattern MVVM. Un’ultima novità interessante è la possibilità di utilizzare un thread separato (che lavora in background) per recuperare informazioni da servizi WCF, così da garantire un tempo di risposta molto basso (utile per scenari in cui è richiesta uno scambio continuo di dati).
Data Binding
Il data binding, come sappiamo, è una delle feature più potenti di Silverlight e WPF e consente di collegare i controlli visuali presenti nello XAML ad altri controlli o a oggetti ed eventi dichiarati nel nostro codice. In questo modo è possibile creare un “flusso continuo” tra la UI e i dati, in modo che i cambiamenti da una parte si riflettano automaticamente sull’altra e viceversa.
L’implementazione del pattern MVVM (Model-View-View Model) nelle applicazioni Silverlight è fortemente basata sul data binding: Silverlight 5 introduce una serie di feature proprio in ottica di rendere il binding ancora più potente e flessibile e di rendere ancora più agevole l’utilizzo del pattern MVVM.
Ecco alcune di queste feature:
- Debug del binding: sarà possibile inserire dei breakpoint anche nello XAML, così da debuggare step by step eventuali problemi nel binding.
- Implicit DataTemplate: questa feature permette di creare template per la visualizzazione de dati che vengono applicati automaticamente a tutti gli oggetti di un tipo specifico presenti all’interno dell’applicazione.
- Ancestor RelativeSource: questa feature permette ad un controllo di essere messo in binding con una proprietà del controllo padre che lo contiene.
- Binding in style setters: in Silverlight è possibile definire degli stili, da utilizzare all’interno dei controlli della nostra applicazione (pensate ai CSS del mondo web). Con Silverlight 5 questi stili, invece che essere associati direttamente ad un valore, possono essere valorizzati tramite il Data Binding, dandoci la possibilità di cambiare in maniera semplice a runtime il valore dello stile. Durante il keynote John Papa ha sfruttato questa feature per cambiare al volo con un click del mouse il tema dell’applicazione da lui realizzata per la demo.
- DataContextChanged: questo nuovo evento viene scatenato nel momento in cui il DataContext di un controllo cambia durante l’esecuzione dell’applicazione.
- Custom Markup Extensions: tutti i controlli Silverlight hanno una serie di attributi, che permettono di definire direttamente da XAML i valori delle proprietà (ad esempio, Text e FontSize sono due delle tante proprietà disponibili per i controllidi tipo TextBox). Questi attributi tipicamente contengono dei valori “semplici” (come strighe o numeri): Silverlight però nativamente supporta la possibilità di definire dei valori che sono il risultato di elaborazioni più complesse. Binding e StaticResource sono due esempi di Markup Extensions native, caratterizzate dal fatto che il valore viene racchiusa tra parentesi graffe (ad esempio, Text={Biding Path=Testo}). Le Custom Markup Extensions sono una feature già presente nel mondo WPF e permettono di realizzare delle Markup Extensions ad hoc, in cui definiamo noi la logica di comportamento e di visualizzazione dell’elemento.
Grafica 3D avanzata
Silverlight 5 introduce un set di API dedicate alla manipolazione della grafica 3D, sfruttando l’accelerazione hardware della scheda video. In questo modo è possibile realizzare animazioni 3D complesse, garantendo allo stesso tempo delle ottime performance. Su questa nuova feature non c’è molto da dire per ora: durante il keynote non sono stati dati dettagli implementativi, ma sono state mostrate delle demo del risultato finale che si può ottenere con le nuove API. Vi consiglio di guardarvi la demo mostrata durante il keynote: il risultato è veramente notevole e apre le porte a molti scenari decisamente interessanti, anche in ambito business.
Convergenza con le applicazioni desktop
Molte delle novità introdotte hanno l’obiettivo di rendere Silverlight sempre più adatto allo sviluppo non solo di applicazioni web ma anche desktop: ora, sfruttando la funzionalità Out Of Browser, è possibile aprire e gestire più finestre all’interno della stessa applicazione. In più, è stato aggiunto il supporto alle chiamate P/Invoke, ovvero un sistema nativo del framework .NET per lanciare processi esterni e gestire chiamate a codice unmanaged (come le librerie di Windows). Questa funzionalità facilita, ad esempio, l’integrazione con dispositivi esterni: durante il keynote è stata presentata un’applicazione medica capace di interfacciarsi con un dispositivo USB di analisi del glucosio nel sangue.
Anche le nuove funzionalità per la stampa e per il rendering dei testi possono essere lette in quest’ottica: oltre a diverse migliorie nella resa visiva dei font su schermo, è stata introdotta una nuova API (chiamata Postscript Vector Printing API) che offre una maggiore versatilità nella creazione di versioni stampabili dei nostri documenti.
Infine, verrà integrato nativamente il controllo Pivot, che permette di gestire in maniera visuale grandi collezioni di dati (potete vederne un esempio qui
Performance
Silverlight 5 punta ad offrire un’esperienza utente più fluida e meno esosa di risorse di sistema: minor tempo di startup delle applicazioni, supporto ai 64 bit e supporto all’accelerazione hardware di IE9 sono alcune delle migliorie che verranno introdotte.
Testing
Infine, è stato aggiunto il supporto per le creazione di unit test automatici per il testing della UI della nostra applicazione: sarà possibile direttamente in Visual Studio 2010 “registrare” le nostre interazioni con l’applicazione e tradurle in codice, che ci permetterà di verificare che il risultato dell’interazione sia sempre lo stesso. Anche in questo caso John Papa ha dato un’interessante dimostrazione di questa feature, realizzando un test che verificasse che la ricerca di una determinata parola nella sua applicazione desse sempre lo stesso risultato.
E per quanto riguarda gli altri mondi?
Le applicazioni Silverlight, come sappiamo, sono compatibili anche con Mac OS X, grazie ad una versione dedicata del runtime: già Silverlight 4 aveva creato un divario tra il mondo Windows e il mondo Mac, introducendo il supporto alle COM per la sola piattaforma Microsoft. E’ probabile che Silverlight 5 aumenti questo divario: alcune feature quasi sicuramente non saranno disponibili per il sistema operativo Apple, come il supporto ai 64 bit, alle chiamate P/Invoke e (ovviamente) all’accelerazione hardware di IE9.
E per quanto riguarda noi sviluppatori Windows Phone? Come Silverlight 5 influenzerà il mondo Windows Phone? Purtroppo è ancora troppo presto per dare una risposta: durante il keynote non sono stati svelati i piani per la piattaforma mobile, perciò al momento non è possibile dare una risposta a questa domanda. D’altronde, come anticipavo all’inizio del post, è ancora troppo presto: la prima beta di Silverlight 5 non vedrà la luce prima della Primavera e probabilmente alcune delle feature che verranno incluse nella versione finale non sono ancora state svelate.
La speranza è che, nel lungo periodo, si possa arrivare ad una convergenza tra le due piattaforme: per forza di cose la versione tradizionale e la versione mobile continueranno a viaggiare su due binari separati (non avrebbe senso introdurre ad esempio il supporto alle chiamate P/Invoke o alle nuove API per la stampa su Windows Phone); sarebbe bello però che questi binari diventassero paralleli, in modo da avere un allineamento delle feature principali (il supporto alle custom markup extensions o al debug nel binding sono solo due delle novità che sarebbero le benvenute anche su Windows Phone).
Direi che ho scritto abbastanza, perciò vi lascio con tre link molto interessanti:
- La pagina ufficiale dell’evento, in cui è possibile rivedere il keynote nonchè tutte le sessioni successive. Unica nota “negativa”: il filmato non è ancora stato reso disponibile per il download, ma viene trasmesso in streaming. Ciò significa che, in caso di intenso traffico sul sito, la qualità del video viene automaticamente diminuita, rendendo in alcuni casi praticamente illeggibili gli esempi di codice che vengono mostrati.
- La pagina ufficiale del sito di Silverlight in cui vengono presentate le novità di Silverlight.
- Il post del blog di Scott Guthrie, dedicato anch’esso alle novità presentate durante il keynote.
Salvare in un tombstone il valore dei controlli DatePicker e TimePicker del Silverlight Toolkit for Windows Phone
Posted by qmatteoq in Windows Phone Tutorials on Friday 03 December 2010 at 10:00 AM
In questo post vi ho parlato del Silverlight Toolkit per Windows Phone, che include una serie di controlli aggiuntivi molto utili nello sviluppo di applicazioni. Ci sono però due di questi controlli, DatePicker e TimePicker, che possono darvi qualche grattacapo quando la vostra applicazione viene sospesa.
Ma partiamo dall’inizio: questi due controlli servono semplicemente a selezionare una data e un’ora, tramite una sorta di dropdown, il quale viene visualizzato in una schermata differente da quella in cui avete inserito il controllo. Utilizzare il controllo è molto semplice, vi basta refernziare il namespace del toolkit nel vostro XAML e poi inserire del codice di questo tipo:
<toolkit:datepicker x:Name="picker"></toolkit:datepicker>
Con questo codice, vi portate a casa in automatico:
- L’inserimento di una textbox nella pagina.
- Il passaggio alla schermata di selezione della data o dell’ora quando si fa tap sulla textbox.
- La visualizzazione nella textbox della data o dell’ora scelta.
Andando a spulciare il codice sorgente del toolkit (disponibile sul sito ufficiale) scopriremo che la schermata di selezione della data o dell’ora è una vera e propria pagina (DatePickerPage.xaml e TimePickerPage.xaml). Questo, in ottica di gestione del tombstoning della nostra applicazione, può causare qualche problema. Vediamo perchè: se ricordiamo i tutorial sul tombstoning il salvataggio dello stato della pagina (valori dei textbox, focus, ecc.) viene tipicamente gestito negli eventi OnNavigatedFrom e OnNavigatedTo, che si scatenano quando ci muoviamo da e verso la pagina corrente. Dato che, come abbiamo detto, la selezione di una data o di un’ora avvengono in una vera e propria pagina, ecco che tutte le volte che utilizziamo il controllo si scatenano i due eventi: OnNavigatedFrom quando andiamo alla pagina di selezione e OnNavigatedTo quando ci torniamo.
Ipotizziamo di gestire il tombstoning nella maniera consueta, ovvero salvando lo stato della pagina nell’evento OnNavigatedFrom e ripristinandolo nell’evento OnNavigatedTo.
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
if (State.ContainsKey("Date"))
State.Remove("Date");
State.Add("Date", Convert.ToDateTime(picker.Value.Value));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (State.ContainsKey("Date"))
picker.Value = (DateTime?) State["Date"];
}
Piccola nota: nell’evento OnNavigatedTo il valore al picker non viene recuperato direttamente dal tombstone, ma viene prima castato in (DateTime?). Il punto interrogativo sta ad indicare che si tratta di un Nullable DateTime, ovvero un DateTime che può avere valore nullo. Il tipo DateTime standard, infatti, non supporta il valore null, ma deve sempre essere valorizzato. Il cast è necessario perchè la proprietà Value esposta dal controlloDatePicker (che contiene, per l’appunto, la data selezionata) è di tipo Nullable DateTime.
Ma torniamo al nostro esempio: se proviamo ad eseguire il codice ci accorgeremo che qualcosa non va. La pagina con il controllo riporterebbe sempre la stessa data, indipendentemente da quella che selezioniamo. Non è difficile capire perchè: ogni volta che noi tocchiamo il controllo e veniamo portati alla pagina di selezione della data si scatena l’evento OnNavigatedFrom; la data correntemente impostata viene perciò salvata nel tombstone. Quando invece abbiamo scelto la data e dato Ok, veniamo riportati nella pagina con il nostro controllo, scatenando l’evento OnNavigatedTo. Ecco perciò che, invece di essere utilizzata la data appena scelta, viene caricato il valore dal tombstone e visualizzato al suo posto.
Dobbiamo perciò trovare un modo per distinguere se gli eventi sono stati scatenati perchè ci stiamo spostando da e verso la pagina di selezione della data (quindi non dobbiamo salvare lo stato) oppure se perchè l’applicazione è stata sospesa o ci stiamo spostando verso un’altra pagina della nostra app (e in questo caso dobbiamo salvare lo stato).
Ecco la soluzione!
Entrambi gli eventi legati alla navigazione espongono, tra gli argomenti di ritorno, un oggetto di tipo NavigationEventArgs, che contiene l’informazione su qual è la pagina verso cui ci stiamo spostando, più precisamente nella proprietà Content. Se debuggiamo l’applicazione nel momento in cui ci stiamo spostando verso la pagina di selezione della data e analizziamo questa proprietà, scorpriremo che tale pagina si chiama DatePickerPage nel caso del DatePicker e TimePickerpage nel caso del TimePicker. E’ semplice perciò capire che possiamo sfruttare questa informazione per il nostro scopo: andremo a salvare la data o l’ora in un tombstone solo nel caso in cui la proprietà Content contiene un valore nullo (si verifica quando l’applicazione viene sospesa) o il cui tipo è diverso da DatePickerPage o TimePickerPage.
C’è un’altra considerazione da fare però: l’oggetto di tipo NavigationEventArgs esponse solo l’informazione sulla pagina verso cui ci stiamo spostando e non anche quella da cui proveniamo. Non possiamo perciò sfruttare lo stesso stratagemma nell’evento OnNavigatedTo per capire se dobbiamo recuperare l’informazione dal tombstone oppure no.
Il trucco che possiamo utilizzare è quello di memorizzare in una variabile booleana, durante l’evento OnNavigatedFrom, se l’evento si è scatenato perchè ci stiamo spostando verso la pagina di selezione della data (isFromDatePicker = true) oppure no (isFromDatePicker = false). Tale variabile verrà salvata anch’essa in un tombstone: solo se questa è a true, nell’evento OnNavigatedTo andiamo a recuperare dal tombstone la data e la visualizziamo nel controllo DatePicker o TimePicker.
Ecco il codice:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
bool isFromDatePicker;
if (e.Content==null || e.Content.GetType().Name != "DatePickerPage")
{
if (PhoneApplicationService.Current.State.ContainsKey("Date"))
PhoneApplicationService.Current.State.Remove("Date");
PhoneApplicationService.Current.State.Add("Date", Convert.ToDateTime(picker.Value));
isFromDatePicker = false;
}
else
isFromDatePicker = true;
if (PhoneApplicationService.Current.State.ContainsKey("isFromDatePicker"))
PhoneApplicationService.Current.State.Remove("isFromDatePicker");
PhoneApplicationService.Current.State.Add("isFromDatePicker", isFromDatePicker);
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (PhoneApplicationService.Current.State.ContainsKey("Date") && (bool)PhoneApplicationService.Current.State["isFromDatePicker"] == false)
picker.Value = (DateTime?) PhoneApplicationService.Current.State["Date"];
base.OnNavigatedTo(e);
}
Conclusione
Abbiamo visto come salvare in un tombstone la data e l’ora che recuperiamo utilizzando i controlli DatePicker e TimePicker: come sempre, qui sotto trovate il link per scaricare il codice sorgente del progetto d’esempio utilizzato nel post.

Recent Comments