2626using Windows . Foundation ;
2727using BackgroundAudioShared . Messages ;
2828using Windows . Storage . Streams ;
29+ using Windows . Foundation . Diagnostics ;
30+ using System . Runtime . Serialization ;
31+ using System . IO ;
2932
3033/* This background task will start running the first time the
3134 * MediaPlayer singleton instance is accessed from foreground. When a new audio
@@ -53,6 +56,7 @@ public sealed class MyBackgroundAudioTask : IBackgroundTask
5356 private const string TrackIdKey = "trackid" ;
5457 private const string TitleKey = "title" ;
5558 private const string AlbumArtKey = "albumart" ;
59+ private const string PlaylistFileName = "MyPlaylist.txt" ;
5660 private SystemMediaTransportControls smtc ;
5761 private MediaPlaybackList playbackList = new MediaPlaybackList ( ) ;
5862 private BackgroundTaskDeferral deferral ; // Used to keep task alive
@@ -150,6 +154,7 @@ private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellati
150154 {
151155 // You get some time here to save your state before process and resources are reclaimed
152156 Debug . WriteLine ( "MyBackgroundAudioTask " + sender . Task . TaskId + " Cancel Requested..." ) ;
157+
153158 try
154159 {
155160 // immediately set not running
@@ -242,7 +247,7 @@ private void smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMedia
242247 bool result = backgroundTaskStarted . WaitOne ( 5000 ) ;
243248 if ( ! result )
244249 throw new Exception ( "Background Task didnt initialize in time" ) ;
245-
250+
246251 StartPlayback ( ) ;
247252 break ;
248253 case SystemMediaTransportControlsButton . Pause :
@@ -275,7 +280,7 @@ private void smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMedia
275280 /// <summary>
276281 /// Start playlist and change UVC state
277282 /// </summary>
278- private void StartPlayback ( )
283+ async private void StartPlayback ( )
279284 {
280285 try
281286 {
@@ -287,8 +292,21 @@ private void StartPlayback()
287292 // If the task was cancelled we would have saved the current track and its position. We will try playback from there.
288293 var currentTrackId = ApplicationSettingsHelper . ReadResetSettingsValue ( ApplicationSettingsConstants . TrackId ) ;
289294 var currentTrackPosition = ApplicationSettingsHelper . ReadResetSettingsValue ( ApplicationSettingsConstants . Position ) ;
295+
290296 if ( currentTrackId != null )
291297 {
298+ if ( playbackList . Items . Count == 0 )
299+ {
300+ // We're being re-launched via the Universal Volume Control (UVC),
301+ // so we need to read in the last saved playlist.
302+ UpdatePlaylistMessage playlistMessage = await ReadPlaylist ( ) ;
303+
304+ if ( null != playlistMessage )
305+ {
306+ CreatePlaybackList ( playlistMessage . Songs ) ;
307+ }
308+ }
309+
292310 // Find the index of the item by name
293311 var index = playbackList . Items . ToList ( ) . FindIndex ( item =>
294312 GetTrackId ( item ) . ToString ( ) == ( string ) currentTrackId ) ;
@@ -307,7 +325,7 @@ private void StartPlayback()
307325 // Play from exact position otherwise
308326 TypedEventHandler < MediaPlaybackList , CurrentMediaPlaybackItemChangedEventArgs > handler = null ;
309327 handler = ( MediaPlaybackList list , CurrentMediaPlaybackItemChangedEventArgs args ) =>
310- {
328+ {
311329 if ( args . NewItem == playbackList . Items [ index ] )
312330 {
313331 // Unsubscribe because this only had to run once for this item
@@ -326,6 +344,7 @@ private void StartPlayback()
326344
327345 // Switch to the track which will trigger an item changed event
328346 Debug . WriteLine ( "StartPlayback: Switching to track " + index ) ;
347+
329348 playbackList . MoveTo ( ( uint ) index ) ;
330349 }
331350 }
@@ -475,6 +494,7 @@ void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPla
475494 if ( MessageService . TryParseMessage ( e . Data , out updatePlaylistMessage ) )
476495 {
477496 CreatePlaybackList ( updatePlaylistMessage . Songs ) ;
497+ SavePlaylist ( updatePlaylistMessage ) ;
478498 return ;
479499 }
480500 }
@@ -508,6 +528,68 @@ void CreatePlaybackList(IEnumerable<SongModel> songs)
508528 // Add handler for future playlist item changes
509529 playbackList . CurrentItemChanged += PlaybackList_CurrentItemChanged ;
510530 }
531+
532+ /// <summary>
533+ /// Saves the given UpdatePlaylistMessage to Application Storage
534+ /// </summary>
535+ async void SavePlaylist ( UpdatePlaylistMessage message )
536+ {
537+ Windows . Storage . StorageFolder localFolder = Windows . Storage . ApplicationData . Current . LocalFolder ;
538+ var builder = new System . Text . StringBuilder ( ) ;
539+
540+ try
541+ {
542+ var writer = System . Xml . XmlWriter . Create ( builder ) ;
543+
544+ DataContractSerializer ser = new DataContractSerializer ( typeof ( UpdatePlaylistMessage ) ) ;
545+
546+ ser . WriteObject ( writer , message ) ;
547+ writer . Flush ( ) ;
548+
549+ // For the sake of this sample, simply write to a local file with a fixed name
550+ StorageFile playlist = await localFolder . CreateFileAsync ( PlaylistFileName , CreationCollisionOption . ReplaceExisting ) ;
551+
552+ await FileIO . WriteTextAsync ( playlist , builder . ToString ( ) ) ;
553+ }
554+ catch ( Exception ex )
555+ {
556+ Debug . WriteLine ( ex . ToString ( ) ) ;
557+ }
558+ }
559+
560+ /// <summary>
561+ /// Reads in a previously stored playlist
562+ /// </summary>
563+ async System . Threading . Tasks . Task < UpdatePlaylistMessage > ReadPlaylist ( )
564+ {
565+ UpdatePlaylistMessage message = null ;
566+
567+ Windows . Storage . StorageFolder localFolder = Windows . Storage . ApplicationData . Current . LocalFolder ;
568+ DataContractSerializer ser = new DataContractSerializer ( typeof ( UpdatePlaylistMessage ) ) ;
569+
570+ try
571+ {
572+ var playlist = await localFolder . TryGetItemAsync ( PlaylistFileName ) ;
573+
574+ if ( ( null != playlist ) && ( playlist . IsOfType ( StorageItemTypes . File ) ) )
575+ {
576+ // re-create the message
577+ StorageFile playlistFile = ( StorageFile ) playlist ;
578+
579+ string playlistXml = await FileIO . ReadTextAsync ( playlistFile ) ;
580+
581+ System . Xml . XmlReader reader = System . Xml . XmlReader . Create ( new StringReader ( playlistXml ) ) ;
582+
583+ message = ( UpdatePlaylistMessage ) ser . ReadObject ( reader ) ;
584+ }
585+ }
586+ catch ( Exception ex )
587+ {
588+ Debug . WriteLine ( ex . ToString ( ) ) ;
589+ }
590+
591+ return message ;
592+ }
511593 #endregion
512594 }
513595}
0 commit comments