La piattaforma di sviluppo per Windows Phone mette a disposizione una serie di API per l'interazione con il Pictures Hub, che è poi il posto in cui vengono memorizzate le foto.
Una richiesta molto frequente è quella di poter salvare nel device foto da Internet, dato il loro indirizzo Web. Posto che ci siamo accertati di avere il permesso di poterlo fare
, ricorriamo a una serie di strumenti. Innanzitutto usiamo la classe WebClient per eseguire il download asincrono della foto. Quindi spostiamo il suo contenuto fatto di byte in un file all'interno dell'isolated storage, per poi eseguire il salvataggio vero e proprio.
Per interagire in modo rapido con l'hub delle foto è conveniente utilizzare la classe MediaLibrary (che non fa solo questo), messa a disposizione dall'assembly Microsoft.Xna.Framework. Tale assembly, al quale dobbiamo necessariamente aggiungere un riferimento nel nostro progetto, è specifico per i giochi sviluppati con XNA ma si integra perfettamente con le app.
Il codice che ci permette di eseguire questa operazione non è affatto complicato, richiede solo un po' di dimestichezza con gli stream. Eccolo, con i commenti che facilitano la lettura:
'The following Imports directives are required
'Imports System.Windows.Resources
'Imports System.IO
'Imports Microsoft.Xna.Framework.Media
'Imports System.IO.IsolatedStorage
Private Sub SavePictureToHub(webAddress As Uri, pictureName As String)
Dim client As New WebClient()
AddHandler client.OpenReadCompleted, Sub(sender As Object, e As OpenReadCompletedEventArgs)
'Get the result of the download operation as a stream
Dim resInfo As New StreamResourceInfo(e.Result, Nothing)
Dim reader As New StreamReader(resInfo.Stream)
'Get a reference to the isolated storage
Dim store = IsolatedStorageFile.GetUserStoreForApplication
'Read the downloaded stream
Dim contents As Byte()
Using bReader As New BinaryReader(reader.BaseStream)
contents = bReader.ReadBytes(CInt(reader.BaseStream.Length))
End Using
'Move the downloaded stream to a temp file into the isolated storage
Using fStream As IsolatedStorage.IsolatedStorageFileStream = store.CreateFile(pictureName)
fStream.Write(contents, 0, contents.Length)
End Using
'Save the picture to the Pictures hub (Saved pictures)
Using rStream As New IsolatedStorageFileStream(pictureName, FileMode.Open, store)
Dim ml As New MediaLibrary
ml.SavePicture(pictureName, rStream)
End Using
reader.Close()
'Remove the temp file from the isolated storage
store.DeleteFile(pictureName)
End Sub
client.OpenReadAsync(webAddress)
End Sub
Per una comodità personale uso le statement lambda dove posso, chiaramente si poteva incapsulare il codice della sub 'nidificata' in un delegate separato. L'unica cosa di cui tener conto (oltre, come detto, ad avere il permesso di scaricare la foto) è che le immagini verranno salvate nell'album chiamato Foto Salvate.
Alessandro