/// <summary> /// Fires when playlist changes to a new track /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void playList_TrackChanged(object sender, object args) { UpdateUVCOnNewTrack(); UpdateLastFmOnNewTrack(); ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.CurrentTrack, Playlist.CurrentTrackIndex); if (foregroundAppState == ForegroundAppStatus.Active) { //Message channel that can be used to send messages to foreground ValueSet message = new ValueSet(); message.Add(BackgroundAudioConstants.Trackchanged, Playlist.CurrentTrack); BackgroundMediaPlayer.SendMessageToForeground(message); } }
/// <summary> /// Handles background task cancellation. Task cancellation happens due to : /// 1. Another Media app comes into foreground and starts playing music /// 2. Resource pressure. Your task is consuming more CPU and memory than allowed. /// In either case, save state so that if foreground app resumes it can know where to start. /// </summary> private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { // You get some time here to save your state before process and resources are reclaimed Debug.WriteLine("MyBackgroundAudioTask " + sender.Task.TaskId + " Cancel Requested..."); try { //save state ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.CurrentTrack, Playlist.CurrentTrackIndex); ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.Position, BackgroundMediaPlayer.Current.Position.ToString()); ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.Time, BackgroundMediaPlayer.Current.NaturalDuration.ToString()); ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.BackgroundTaskState, BackgroundAudioConstants.BackgroundTaskCancelled); ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.AppState, Enum.GetName(typeof(ForegroundAppStatus), foregroundAppState)); backgroundtaskrunning = false; //unsubscribe event handlers systemmediatransportcontrol.ButtonPressed -= systemmediatransportcontrol_ButtonPressed; systemmediatransportcontrol.PropertyChanged -= systemmediatransportcontrol_PropertyChanged; Playlist.TrackChanged -= playList_TrackChanged; //clear objects task cancellation can happen uninterrupted playlistManager.ResetCollection((int)ResetType.NormalReset); playlistManager = null; // Send message to foreground task (if it's around) that this task was cancelled :( ValueSet message = new ValueSet { { BackgroundAudioConstants.BackgroundTaskCancelled, "" } }; BackgroundMediaPlayer.SendMessageToForeground(message); BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } deferral?.Complete(); // signals task completion. Debug.WriteLine("MyBackgroundAudioTask Cancel complete..."); }
/// <summary> /// The Run method is the entry point of a background task. /// </summary> /// <param name="taskInstance"></param> public void Run(IBackgroundTaskInstance taskInstance) { try { Debug.WriteLine("Background Audio Task " + taskInstance.Task.Name + " starting..."); // Initialize SMTC object to talk with UVC. //Note that, this is intended to run after app is paused and //hence all the logic must be written to run in background process systemmediatransportcontrol = SystemMediaTransportControls.GetForCurrentView(); systemmediatransportcontrol.ButtonPressed += systemmediatransportcontrol_ButtonPressed; systemmediatransportcontrol.PropertyChanged += systemmediatransportcontrol_PropertyChanged; systemmediatransportcontrol.IsEnabled = true; systemmediatransportcontrol.IsPauseEnabled = true; systemmediatransportcontrol.IsPlayEnabled = true; systemmediatransportcontrol.IsNextEnabled = true; systemmediatransportcontrol.IsPreviousEnabled = true; // Associate a cancellation and completed handlers with the background task. taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled); taskInstance.Task.Completed += Taskcompleted; var value = ApplicationSettingsHelper.ReadResetSettingsValue(BackgroundAudioConstants.AppState); if (value == null) { foregroundAppState = ForegroundAppStatus.Unknown; } else { foregroundAppState = (ForegroundAppStatus)Enum.Parse(typeof(ForegroundAppStatus), value.ToString()); } //Add handlers for MediaPlayer BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged; //Add handlers for playlist trackchanged Playlist.TrackChanged += playList_TrackChanged; //Initialize message channel BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground; //Send information to foreground that background task has been started if app is active if (foregroundAppState != ForegroundAppStatus.Suspended) { ValueSet message = new ValueSet(); message.Add(BackgroundAudioConstants.BackgroundTaskStarted, ""); BackgroundMediaPlayer.SendMessageToForeground(message); } BackgroundTaskStarted.Set(); backgroundtaskrunning = true; Playlist.PopulatePlaylist(); var currentTrackIndex = ApplicationSettingsHelper.ReadSettingsValue(BackgroundAudioConstants.CurrentTrack); if (currentTrackIndex != null) { Playlist.CurrentTrack = (int)currentTrackIndex; } ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.BackgroundTaskState, BackgroundAudioConstants.BackgroundTaskRunning); deferral = taskInstance.GetDeferral(); } catch { } }
/// <summary> /// Fires when a message is recieved from the foreground app /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e) { foreach (string key in e.Data.Keys) { switch (key.ToLower()) { case BackgroundAudioConstants.PingBackground: Debug.WriteLine("Received Ping from foreground"); // App is suspended, you can save your task state at this point ValueSet message = new ValueSet(); message.Add(BackgroundAudioConstants.PingBackground, DateTime.Now.ToString()); BackgroundMediaPlayer.SendMessageToForeground(message); break; case BackgroundAudioConstants.AppSuspended: Debug.WriteLine("App suspending"); // App is suspended, you can save your task state at this point foregroundAppState = ForegroundAppStatus.Suspended; ApplicationSettingsHelper.SaveSettingsValue(BackgroundAudioConstants.CurrentTrack, Playlist.CurrentTrackIndex); break; case BackgroundAudioConstants.AppResumed: Debug.WriteLine("App resuming"); // App is resumed, now subscribe to message channel foregroundAppState = ForegroundAppStatus.Active; break; case BackgroundAudioConstants.StartPlayback: //Foreground App process has signalled that it is ready for playback Debug.WriteLine("Starting Playback"); StartPlayback(); break; case BackgroundAudioConstants.UpdatePlaylist: Debug.WriteLine("Updating playlist..."); Playlist.UpdatePlaylist(); break; case BackgroundAudioConstants.ResetPlaylist: var arg = new object(); if (e.Data.TryGetValue(BackgroundAudioConstants.ResetPlaylist, out arg)) { Playlist.ResetCollection((int)arg); } break; case BackgroundAudioConstants.AddTrack: object track = new object(); if (e.Data.TryGetValue(BackgroundAudioConstants.AddTrack, out track)) { // We should have the newest playlist with the new track already. If so, just repopulate the playlist. Playlist.AddTracks(AudioBackgroundInterface.DeserializeAudioTracks(track.ToString()) as List <BackgroundTrackItem>); } break; case BackgroundAudioConstants.PlayTrack: //Foreground App process has signalled that it is ready for playback Debug.WriteLine("Starting Playback"); Object obj = new Object(); if (e.Data.TryGetValue(BackgroundAudioConstants.PlayTrack, out obj)) { string s = obj as string; if (!string.IsNullOrEmpty(s)) { int t = Convert.ToInt32(s); Playlist.PlayTrack(t); } } break; case BackgroundAudioConstants.RestorePlaylist: //Foreground App process updated List Track Debug.WriteLine("Restoring ListTrack"); Playlist.PopulatePlaylist(); var currentTrack = ApplicationSettingsHelper.ReadSettingsValue(BackgroundAudioConstants.CurrentTrack); if (currentTrack == null) { break; } Playlist.CurrentTrack = (int)currentTrack; break; case BackgroundAudioConstants.SkipNext: // User has chosen to skip track from app context. Debug.WriteLine("Skipping to next"); SkipToNext(); break; case BackgroundAudioConstants.SkipPrevious: // User has chosen to skip track from app context. Debug.WriteLine("Skipping to previous"); SkipToPrevious(); break; } } }