Windows Phone 8 Succinctly Multimediaprogram

I den här handledningen kommer vi att fokusera på hur man skapar ett multimediaprogram för Windows Phone genom att dra fördel av enhetens kamera, interagera med mediebiblioteket och utforska möjligheterna för Photos Hub.

Använda kameran

Kameran är en av de viktigaste funktionerna i Windows Phone-enheter, särskilt tack vare Nokia, som har skapat några av de bästa kameratelefonerna som finns tillgängliga på marknaden.

Som utvecklare kan vi integrera kamerans upplevelse i vår applikation så att användare kan ta bilder och redigera dem direkt i applikationen. Dessutom, med Lens App-funktionen diskuteras senare, det är ännu enklare att skapa program som kan ersätta den inbyggda kamerans upplevelse.

Obs! För att interagera med kameran måste du aktivera ID_CAP_IS_CAMERA kapacitet i manifestfilen.

Det första steget är att skapa ett område på sidan där vi kan visa bilden inspelad av kameran. Vi ska använda VideoBrush, vilket är en av de ursprungliga XAML borstarna som kan bädda in en video. Vi använder den som bakgrund av a Duk kontroll, som visas i följande prov:

        

Lägg märke till CompositeTransform som har tillämpats Dess syfte är att behålla videoens riktiga orientering, baserat på kameroriktningen.

Ta bilder

Nu när vi har en plats för att visa live kamera matningen, kan vi använda API: erna som ingår i Windows.Phone.Media.Capture namnutrymmet. Specifikt kallas klassen som är tillgänglig för att ta bilder PhotoCaptureDevice (senare ser vi en annan klass för inspelning av videoklipp).

Följande kod är en provinitiering:

skyddad överstyrning async void OnNavigatedTo (NavigationEventArgs e) Storlekupplösning = PhotoCaptureDevice.GetAvailableCaptureResolutions (CameraSensorLocationBack) .First (); PhotoCaptureDevice camera = väntar PhotoCaptureDevice.OpenAsync (CameraSensorLocationBack, resolution); video.SetSource (kamera); previewTransform.Rotation = camera.SensorRotationInDegrees; 

Innan vi initierar livematningen måste vi göra två val: vilken kamera som ska användas och vilken av de tillgängliga upplösningarna vi vill använda.

Vi uppnår detta genom att ringa GetAvailableCaptureResolutions () metod på PhotoCaptureDevice klass, passerar som parameter a CameraSensorLocation objekt som representerar kameran vi ska använda. Metoden kommer att returnera en samling av de stödda resolutioner som identifieras av Storlek klass.

Tips: Det är säkert att använda den tidigare koden eftersom varje Windows Phone-enhet har en bakkamera. Om vi ​​vill interagera med den främre kameran istället är det bättre att kontrollera om en är tillgänglig först eftersom inte alla Windows Phone-enheter har en. För att göra detta kan du använda AvailableSensorLocation egenskapen hos PhotoCaptureDevice klass, som är en samling av alla kameror som stöds.

När vi har bestämt vilken upplösning som ska användas, kan vi överföra den som en parameter (tillsammans igen med den valda kameran) till OpenAsync () metod för PhotoCaptureDevice klass. Det kommer att returnera a PhotoCaptureDevice objekt som innehåller live-matningen vi måste helt enkelt överföra det till SetSource () metod för VideoBrush

Som redan nämnts hanterar vi kamerans orientering med den transformation vi har tillämpat på VideoBrush: vi ställer in Rotation använda SensorRotationInDegrees egenskap som innehåller den aktuella vinkelns rotation.

Obs! Det kan hända att du får ett fel när du försöker skicka ett PhotoCaptureDevice objekt som en parameter för SetSource () metod för VideoBrush. Om så är fallet måste du lägga till Microsoft.Devices namnrymden till din klass, eftersom det innehåller en förlängningsmetod för SetSource () metod som stöder PhotoCaptureDevice klass.

Nu kommer applikationen bara att visa live-matningen på kameran på skärmen. Nästa steg är att ta bilden.

Tekniken som används av API: n är att skapa en sekvens av ramar och spara dem som en ström. Tyvärr finns det en begränsning i den aktuella SDK: du kan bara ta en bild i taget, så du kan bara använda sekvenser som gjorts av en ram.

privat async ogiltig OnTakePhotoClicked (objekt avsändare, RoutedEventArgs e) CameraCaptureSequence cameraCaptureSequence = camera.CreateCaptureSequence (1); MemoryStream stream = nytt MemoryStream (); cameraCaptureSequence.Frames [0] .CaptureStream = stream.AsOutputStream (); väntar på kameran.PrepareCaptureSequenceAsync (CameraCaptureSequence); vänta på kameraCaptureSequence.StartCaptureAsync (); stream.Seek (0, SeekOrigin.Begin); MediaLibrary library = new MediaLibrary (); library.SavePictureToCameraRoll ("picture1.jpg", stream); 

Processen börjar med a CameraCaptureSequence objekt, vilket representerar capture-strömmen. På grund av den tidigare nämnda singular-picutre-begränsningen kan du ringa CreateCaptureSequence () metod för PhotoCaptureDevice klass endast genom att passera 1 som dess parameter.

Av samma anledning kommer vi bara att arbeta med den första ramen i den sekvens som lagras inuti ramar samling. De CaptureStream egenskapen till ramen måste ställas in med den ström som vi ska använda för att lagra den infångade bilden. I det föregående provet använder vi en Memory för att lagra fotot i minnet. På så sätt kan vi spara det senare i användarens Photos Hub (speciellt i Camera Roll-albumet).

Obs! Att interagera med Media bibliotek klass du behöver aktivera ID_CAP_MEDIALIB_PHOTO kapacitet i manifestfilen.

Du kan också anpassa många inställningar av kameran genom att ringa SetProperty () metod på PhotoCaptureDevice objekt som kräver två parametrar: egenskapen som ska ställas in och värdet som ska tilldelas. De tillgängliga egenskaperna definieras av två talare: KnownCameraGeneralProperties, som innehåller de allmänna kameregenskaperna, och KnownCameraPhotoProperties, som innehåller de fotospecifika egenskaperna.

Vissa egenskaper är skrivskyddade, så den enda operationen du kan utföra är att få sina värden genom att använda GetProperty () metod.

I följande prover använder vi SetProperty () Metod för att ställa in blixtläget och GetProperty () för att få informationen om den nuvarande regionen tvingar telefoner att spela ett ljud när de tar en bild.

privat tomt OnSetPropertiesClicked (objekt avsändare, RoutedEventArgs e) camera.SetProperty (KnownCameraPhotoProperties.FlashMode, FlashMode.RedEyeReduction); bool isShutterSoundRequired = (bool) camera.GetProperty (KnownCameraGeneralProperties.IsShutterSoundRequiredForRegion); 

Observera att GetProperty () Metoden returnerar alltid ett generiskt objekt, så du måste manuellt kasta den enligt de egenskaper du frågar.

Du kan se en lista över alla tillgängliga egenskaper i MSDN-dokumentationen.

Använda maskinvarukameratangenten

Vanligtvis har Windows Phone-enheter en dedikerad knapp för kameran, som kan användas både för att ställa in fokus genom att halvt trycka på den och för att ta bilden genom att helt trycka på den. Du kan också använda den här knappen i dina applikationer genom att prenumerera på tre händelser som exponeras av CameraButtons statisk klass:

  • ShutterKeyPressed utlöses när knappen trycks ned.
  • ShutterKeyReleased utlöses när knappen släpps.
  • ShutterKeyHalfPressed utlöses när knappen är halvpressad.

I följande prov abonnerar vi på ShutterKeyReleased händelse att ta en bild och ShutterKeyHalfPressed händelse för att använda autofokusfunktionen.

offentlig kamera () InitializeComponent (); CameraButtons.ShutterKeyReleased + = CameraButtons_ShutterKeyReleased; CameraButtons.ShutterKeyHalfPressed + = CameraButtons_ShutterKeyHalfPressed;  async void CameraButtons_ShutterKeyHalfPressed (objekt avsändare, EventArgs e) väntar camera.FocusAsync ();  void CameraButtons_ShutterKeyReleased (objekt avsändare, EventArgs e) // Ta bilden. 

Spela in en video

Processen att spela in en video liknar den som vi brukade ta en bild. I det här fallet ska vi använda AudioVideoCaptureDevice klass i stället för PhotoCaptureDevice klass. Som du kan se i följande exempel är initieringsförfarandet detsamma: Vi bestämmer vilken upplösning och kamera vi vill använda, och vi visar det returnerade live-flödet med hjälp av en VideoBrush.

Obs! För att spela in videoklipp måste du också aktivera ID_CAP_MICROPHONE kapacitet i manifestfilen.

skyddad överstyrning async void OnNavigatedTo (NavigationEventArgs e) Storlek upplösning = AudioVideoCaptureDevice.GetAvailableCaptureResolutions (CameraSensorLocationBack) .First (); videoDevice = väntar AudioVideoCaptureDevice.OpenAsync (CameraSensorLocationBack, resolution); video.SetSource (videoDevice); previewTransform.Rotation = videoDevice.SensorRotationInDegrees; 

Inspelning av en video är ännu enklare sedan AudioVideoCaptureDevice klassen avslöjar StartRecordingToStreamAsync () metod, som helt enkelt kräver att du anger var du ska spara den inspelade dataen. Eftersom det är en video behöver du också ett sätt att stoppa inspelningen. Detta är syftet med StopRecordingAsync () metod.

I följande prov lagras inspelningen i en fil som skapats i lokal lagring:

privat AudioVideoCaptureDevice videoDevice; privat IRandomAccessStream-ström; privat StorageFile-fil; allmän videoinspelning () InitializeComponent ();  privat async void OnRecordVideoClicked (objekt avsändare, RoutedEventArgs e) file = väntar ApplicationData.Current.LocalFolder.CreateFileAsync ("video.wmv", CreationCollisionOption.ReplaceExisting); stream = vänta file.OpenAsync (FileAccessMode.ReadWrite); videoDevice.StartRecordingToStreamAsync (stream);  privat async ogiltig OnStopRecordingClicked (objekt avsändare, RoutedEventArgs e) väntar videoDevice.StopRecordingAsync (); väntar stream.FlushAsync (); 

Du kan enkelt testa resultatet av operationen med hjälp av MediaPlayerLauncher klass för att spela inspelningen:

privat tomt OnPlayVideoClicked (objekt avsändare, RoutedEventArgs e) MediaPlayerLauncher launcher = ny MediaPlayerLauncher Media = ny Uri (file.Path, UriKind.Relative); launcher.Show (); 

SDK erbjuder en specifik lista över anpassningsbara inställningar som är anslutna till videoinspelning. De finns tillgängliga i KnownCameraAudioVideoProperties enumerator.

Interagera med mediebiblioteket

Ramverket erbjuder en klass kallad Media bibliotek, som kan användas för att interagera med användarmedia biblioteket (foton, musik, etc.). Låt oss se hur du använder den för att hantera de vanligaste scenarierna.

Obs! I den nuvarande versionen kan du inte interagera med biblioteket för att spara nya videor i kamerarullen, eller att få tillgång till strömmen av befintliga videoklipp.

Bilder

De Media bibliotek klassen kan användas för att få tillgång till bilderna som är lagrade i Photos Hub, tack vare Bilder samling. Det är en samling av Bild objekt där var och en representerar en bild som är lagrad i Photos Hub.

Obs! Du måste aktivera ID_CAP_MEDIALIB_PHOTO kapacitet i manifestfilen för att få tillgång till bilderna som är lagrade i Photos Hub.

De Bilder samling ger tillgång till följande album:

  • Kamera rulle
  • Sparade bilder
  • Skärm

Alla andra album som visas i People Hub som kommer från fjärrtjänster som SkyDrive eller Facebook kan inte nås med Media bibliotek klass.

Tips: The Media bibliotek klassen avslöjar en samling som heter SavedPictures, som bara innehåller de bilder som lagras i albumet Sparade bilder.

Varje Bild Objektet erbjuder vissa egenskaper för att få tillgång till grundläggande information, som namn, Bredd, och Höjd. En mycket viktig egenskap är Album, som innehåller referensen för albumet där bilden är lagrad. Dessutom kan du få tillgång till olika strömmar om du vill manipulera bilden eller visa den i din ansökan:

  • De GetPicture () Metoden returnerar strömmen av originalbilden.
  • De GetThumbnail () Metoden returnerar strömmen av miniatyrbilden, vilken är en upplösning med låg upplösning av originalbilden.
  • Om du lägger till PhoneExtensions namnrymd till din klass kan du använda GetPreviewImage () metod som returnerar en förhandsgranskningsbild. Dess upplösning och storlek ligger mellan originalbilden och miniatyrbilden.

I följande prov genererar vi miniatyren för den första tillgängliga bilden i kamerarullen och visar den med en Bild kontrollera:

privat tomt OnSetPhotoClicked (objekt avsändare, RoutedEventArgs e) MediaLibrary library = new MediaLibrary (); Picture picture = library.Pictures.FirstOrDefault (x => x.Album.Name == "Camera Roll"); om (bild! = null) BitmapImage image = new BitmapImage (); image.SetSource (picture.GetThumbnail ()); Thumbnail.Source = image; 

Tips: Att interagera med Media bibliotek klass med hjälp av emulatorn måste du öppna Photos Hub minst en gång; annars får du en tom samling bilder när du frågar Bilder fast egendom.

Med Media bibliotek klass kan du också göra det motsatta: Ta en bild i din ansökan och spara den i People Hub. Vi har redan sett ett prov när vi pratade om att integrera kameran i vår applikation; vi kan spara bilden i kamerarullen (med hjälp av SavePictureToCameraRoll () metod) eller i albumet Sparade bilder (med hjälp av Spara bild() metod). I båda fallen är de önskade parametrarna namnet på bilden och dess ström.

I följande prov laddar vi ner en bild från Internet och sparar den i albumet Sparade bilder:

privat async ogiltig OnDownloadPhotoClicked (objekt avsändare, RoutedEventArgs e) HttpClient client = new HttpClient (); Stream stream = väntar client.GetStreamAsync ("http://www.syncfusion.com/Content/en-US/Home/Images/syncfusion-logo.png"); MediaLibrary library = new MediaLibrary (); library.SavePicture ("logo.jpg", stream); 

musik

De Media bibliotek klassen erbjuder många alternativ för att få tillgång till musik, men det finns några begränsningar som inte är närvarande när man arbetar med bilder. 

Obs! Du måste aktivera ID_CAP_MEDIALIB_AUDIO kapacitet i manifestfilen för att få tillgång till bilderna som är lagrade i Photos Hub. 

Följande samlingar exponeras av Media bibliotek klass för att komma åt musik:

  • album för att få tillgång till musikalbum.
  • Songs för att få tillgång till alla tillgängliga låtar.
  • genrer för att få tillgång till sångerna grupperade efter genre.
  • spellistor för att få tillgång till spellistor.

Varje låt identifieras av Låt klass, som innehåller all den gemensamma informationen om ett musikspår som tagits direkt från ID3-taggen: Album, Konstnär, Titel, Spårnummer, och så vidare.

Tyvärr finns det ingen åtkomst till en låts ström, så det enda sättet att spela spår är att använda Mediaspelare klass, som är en del av Microsoft.XNA.Framework.Media namnutrymmet. Den här klassen visar många metoder för att interagera med spår. De Spela() Metoden accepteras som en parameter a Låt objekt, hämtat från Media bibliotek.

I följande exempel reproducerar vi den första sång som är tillgänglig i biblioteket:

privat tomt OnPlaySong (objekt avsändare, RoutedEventArgs e) MediaLibrary library = new MediaLibrary (); Song song = library.Songs.FirstOrDefault (); MediaPlayer.Play (låt); 

En av de nya funktionerna som introduceras i Windows Phone 8 låter dig spara en låt som lagras i programmets lokala lagring i mediebiblioteket så att det kan spelas av den inbyggda Music + Videos Hub. Detta kräver Microsoft.Xna.Framework.Media.PhoneExtensions namnrymd som ska läggas till i din klass.

privat async void OnDownloadMusicClicked (objekt avsändare, RoutedEventArgs e) MediaLibrary library = new MediaLibrary (); SongMetadata metadata = ny SongMetadata AlbumName = "En rush of blood to the head", ArtistName = "Coldplay", Name = "Klockor"; library.SaveSong (ny Uri ("song.mp3", UriKind.RelativeOrAbsolute), metadata, SaveSongOperation.CopyToLibrary); 

De SaveSong () Metoden kräver tre parametrar, som visas i föregående prov:

  • Låten för låten att spara. Det är en relativ sökväg som pekar på lokal lagring.
  • Sångmetadata, som identifieras av SongMetadata klass. Det är en valfri parameter; om du passerar null, Windows Phone tar automatiskt ut ID3-informationen från filen.
  • en SaveSongOperation objekt, som berättar om mediefältet om filen ska kopieras (CopyToLibrary) eller flyttat (MoveToLibrary) så att den raderas från lagringen.

Lins Apps

Windows Phone 8 har introducerat nya funktioner specifika för fotografiska applikationer. Några av de mest intressanta kallas linsapplikationer, vilka tillämpar olika filter och effekter på bilder. Windows Phone erbjuder ett sätt att enkelt byta mellan olika kameraprogram för att tillämpa filter på flyg.

Objektivlinser är vanliga Windows Phone-program som interagerar med kamerap APIerna vi använde i början av den här artikeln. Skillnaden är att en objektivapp visas i linser avsnittet av den inbyggda kameraprogrammet; När användare trycker på kameraknappen visas en speciell vy med alla tillgängliga objektivapps. På så sätt kan de enkelt byta till en annan applikation för att ta bilden.

Integration med linsens vy börjar från manifestfilen, som måste redigeras manuellt genom att välja Visa kod alternativet i snabbmenyn. Följande kod måste läggas till i Förlängning sektion:

  

Varje objektivapp behöver en särskild ikon som visas i objektivet. Ikoner hämtar automatiskt från Tillgångar mapp baserat på en namngivningskonvention. En ikon måste läggas till för varje stödd upplösning med hjälp av konventionerna i följande tabell:

Upplösning

Ikonstorlek

Filnamn

480 × 800

173 × 173

Lens.Screen-WVGA.png

768 × 1280

277 × 277

Lens.Screen-WXGA.png

720 × 1280

259 × 259

Lens.Screen-720p.png

De UriMapper klass krävs för att arbeta med linsapplikationer. Faktum är att linsapplikationer öppnas med en speciell URI som måste avlyssnas och hanteras. Följande kod är ett prov Uri:

/MainPage.xaml?Action=ViewfinderLaunch

När det här Uri Avlyssnar, användarna bör omdirigeras till den applikationssida som tar bilden. I följande exempel kan du se en UriMapper implementering som omdirigerar användare till en sida som heter Camera.xaml när applikationen öppnas från objektivet.

offentlig klass MyUriMapper: UriMapperBase offentligt åsidosätt Uri MapUri (Uri uri) string tempUri = uri.ToString (); om (tempUri.Contains ("ViewfinderLaunch")) returnera nytt Uri ("/ Camera.xaml", UriKind.Relative);  annars return uri; 

Stöddelning

Om du har utvecklat en applikation som stöder bilddelning, t.ex. en social nätverksklient, kan du integrera den i Dela med sig menyn i Photos Hub. Användare kan hitta det här alternativet i programfältet på sidan med fotoinformation.

När användare väljer det här alternativet visar Windows Phone en lista över program som är registrerade för att stödja delningen. Vi kan lägga till vår applikation på listan helt enkelt genom att lägga till en ny tillägg i manifestfilen, som vi gjorde för att lägga till linsstöd.

Vi måste manuellt lägga till följande deklaration i Extensions sektion:

  

När användare väljer vår ansökan från listan öppnas den med följande URI:

/MainPage.xaml?Action=ShareContent&FileId=%7B1ECC86A2-CDD7-494B-A9A8-DBD9B4C4AAC7%7D

Återigen kan vi använda a UriMapper implementering för att omdirigera användare till vår applikations sida som erbjuder delningsfunktionen. Det är också viktigt att bära FiledId parameter på denna sida; Vi behöver det för att veta vilket foto som har valts av användaren.

Följande prov visar a UriMapper genomförande som helt enkelt ersätter namnet på den ursprungliga sidan (MainPage.xaml) med namnet på destinationssidan (SharePage.xaml):

offentlig klass MyUriMapper: UriMapperBase offentligt åsidosätt Uri MapUri (Uri uri) string tempUri = uri.ToString (); sträng mappedUri; om ((tempUri.Contains ("SharePhotoContent")) && (tempUri.Contains ("FileId"))) // Vidarekoppla till PhotoShare.xaml. mappedUri = tempUri.Replace ("MainPage", "SharePage"); returnera ny Uri (mappedUri, UriKind.Relative);  returnera uri; 

Efter omdirigering av användaren till delningssidan kan vi använda en metod som heter GetPictureFromToken () utsätts av Media bibliotek klass. Den accepterar det unika bild-ID som en parameter och returnerar en referens till Bild objekt som representerar bilden vald av användaren.

Bild-id är parametern som heter FileId som vi fick i URI när ansökan öppnades. I följande exempel kan du se hur vi hämtar parametern genom att använda OnNavigatedTo händelse som utlöses när användaren omdirigeras till delningssidan och använder den för att visa den valda bilden med en Bild kontrollera.

skyddad åsidosättningsfel OnNavigatedTo (NavigationEventArgs e) if (NavigationContext.QueryString.ContainsKey ("FileId")) string fileId = NavigationContext.QueryString ["FileId"]; MediaLibrary library = new MediaLibrary (); Picture picture = library.GetPictureFromToken (fileId); BitmapImage image = nytt BitmapImage (); image.SetSource (picture.GetImage ()); ShareImage.Source = image; 

Andra integrationsfunktioner

Det finns andra sätt att integrera vår applikation med Photos Hub. De arbetar alla på samma sätt:

  • En deklaration måste läggas till manifestfilen.
  • Ansökan öppnas med en speciell Uri att du måste avlyssna med en UriMapper klass.
  • Användaren omdirigeras till en dedikerad sida där du kan hämta den valda bilden med hjälp av FileId parameter.

Lista applikationen som en fotografisk app

Det här är den enklaste integrationen eftersom det bara visar applikationen i Apps-sektionen i Photos Hub. För att stödja det måste du helt enkelt lägga till följande deklaration i manifestfilen:

  

Inget annat krävs eftersom denna typ av integration helt enkelt kommer att innehålla en snabb länk i Photos Hub. Applikationen öppnas normalt, som om den öppnades med huvudappikonen.

Integrerar med redigeringsalternativet

Ett annat alternativ som finns tillgängligt i programfältet på sidan med fotoinformation heter redigera. När användaren knackar på den visar Windows Phone en lista över program som stödjer fotoredigering. Efter att ha valt en, förväntar sig användaren att omdirigeras till en applikationssida där den valda bilden kan redigeras.

Följande deklaration ska läggas till i manifestfilen:

  

När den här funktionen är aktiverad öppnas din ansökan med följande URI:

/MainPage.xaml?Action=EditPhotoContent&FileId=%7B1ECC86A2-CDD7-494B-A9A8-DBD9B4C4AAC7%7D

Det här är Uri att avlyssna om att omdirigera användare till rätt sida där du kan hämta den valda bilden med hjälp av FileId parameter, som vi gjorde för funktionen för bilddelning.

Rich Media Apps

Rich media apps är program som kan ta bilder och spara dem i användarens bibliotek. När användare öppnar ett av dessa bilder ser de:

  • text under fotot med meddelandet "fångat av" följt av appens namn
  • ett nytt alternativ i programfältet "open in" följt av appens namn

Detta tillvägagångssätt liknar delnings- och redigeringsfunktionerna. Skillnaden är att integrering av rich media apps endast är tillgänglig för bilder som tagits i programmet, medan redigerings- och delningsfunktioner är tillgängliga för varje foto oavsett hur de togs.

Följande deklaration bör läggas till i manifestet för att möjliggöra integrering av integrerade medier:

  

I detta scenario öppnas applikationen med följande URI:

/MainPage.xaml?Action=RichMediaEdit&FileId=%7B1ECC86A2-CDD7-494B-A9A8-DBD9B4C4AAC7%7D

Som du kan se är URI alltid densamma. vilka förändringar är värdet av Verkan parameter-i det här fallet, RichMediaEdit.

Detta är URI du behöver avlyssna med din UriMapper genomförande. Du måste omdirigera användare till en sida i din ansökan som kan hantera den valda bilden.

Slutsats

I den här handledningen har vi lärt oss många sätt att skapa en bra multimediaapplikation för Windows Phone genom att:

  • integrera kamerafunktioner för att ta foton och spela in videoklipp
  • interagera med mediebiblioteket för att få tillgång till bilder och ljud
  • integrera med den inbyggda kamerans upplevelse för att ge användarna tillgång till avancerade funktioner direkt i Photos Hub

Denna handledning representerar ett kapitel från Windows Phone 8 Succinctly, en gratis eBook från laget vid Syncfusion.