I am having this strange issue. I am trying to create a music player app for Windows Phone 8.1
. I need the music player to play the music in background, even if the application is in background/closed state. So I am using the BackgroundMediaPlayer class for playing the music. Following is the code for the same:
private void SendMessageToBackground(string Path, string Name, bool IsRadio)
{
if (!string.IsNullOrEmpty(Path))
{
var message = new ValueSet();
message.Add(Constants.TrackURI, Path);
message.Add(Constants.TrackName, Name);
message.Add(Constants.IsRadio, IsRadio);
BackgroundMediaPlayer.MessageReceivedFromBackground += BackgroundMediaPlayer_MessageReceivedFromBackground;
BackgroundMediaPlayer.Current.MediaFailed += Current_MediaFailed;
BackgroundMediaPlayer.SendMessageToBackground(message);
}
}
The code works all fine, the music is playing smoothly. But now I am facing an issue. I am fetching the music files in the application by looping through all folders. Hence it displays all music files, wherever they are in the folder hierarchy. But when I am trying to play a file outside the Music
folder created by the windows phone(refer screenshot), the background music player simply doesn't play the file.
As seen in the code I am listening to events from the BackgroundMediaPlayer
and its MediaPlayer
to check for any possible failure reasons, but both these events are not getting triggered in case of a failed playback. But the BackgroundMediaPlayer
's MessageReceivedFromBackground
event is getting triggered correctly in case of successful playbacks(from Music folder). I checked the file path being passed, and it was all correct, and I tried playing these music files using the inbuilt Music app of the phone, and that too played successfully. What can be the possible problem here? How can I solve it?
EDIT
I debugged further and figured out that it is actually an permission issue. The path passed from the above code, I was using in another function, to pass the Uri
/StorageFile
to the BackgroundMediaPlayer.Current
. Code:
public async void StartTrackAt(string TrackURI, string Name)
{
try
{
BackgroundMediaPlayer.Current.SetUriSource(new Uri(TrackURI)); // This works fine in debug mode. Throws Exception in release mode
/* Tried this also, but this doesn't even work in debug mode
StorageFile storageFile = await StorageFile.GetFileFromPathAsync(TrackURI);
mediaPlayer.SetFileSource(s);
*/
}
catch (Exception ex)
{
//Control comes here when trying to play files outside Music folder.
}
}
I have set the required capabilities in the app's manifest file. But I got the following Exception
when I tried to run this application:
{System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at BackgroundMusicPlayer.MyPlayListManager.<StartTrackAt>d__0.MoveNext()}
[System.UnauthorizedAccessException]: {System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at BackgroundMusicPlayer.MyPlayListManager.<StartTrackAt>d__0.MoveNext()}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2147024891
InnerException: null
Message: "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
Source: "mscorlib"
StackTrace: " at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at BackgroundMusicPlayer.MyPlayListManager.<StartTrackAt>d__0.MoveNext()"
Strangely enough, when passing the Uri
directly without fetching the StorageFile
, it works well in debug mode.
Here are the capabilities I have set for the application: