If you try to use
file picker in Windows Phone App in the same way you did in Windows Store App,
you would likely meet with some difficulties.
When you are done with your code for picking up a photo to
display the photo as following:
var openPicker = new FileOpenPicker()
{
SuggestedStartLocation = PickerLocationId.PicturesLibrary,ViewMode = PickerViewMode.Thumbnail
};
openPicker.FileTypeFilter.Clear();
openPicker.FileTypeFilter.Add(".bmp");
openPicker.FileTypeFilter.Add(".png");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".jpg");
var photo = await openPicker.PickSingleFileAsync();
if (photo != null)
{
var fileStream = await photo.OpenAsync(Windows.Storage.FileAccessMode.Read);
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(fileStream);
displayImage.Source = bitmapImage;
}
The code builds, but when the code executed to await openPicker.PickSingleFileAsync() you will get
an exception with following message:
{System.Exception: The request is not supported. (Exception
from HRESULT: 0x80070032)
at
Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync()
you would have no idea on what is going on here, Maybe
Microsoft could do better job in vetting its Hello Word App for Windows Phone 8.1.
In this article, it said
in Windows Store App, you use PickSingleFileAsync, PickSaveFileAsync and
PickSiingleFolderAsync. However for Windows Phone app, you should use
PickSingleFileAndContinue, PickSaveFileAndContinue and PickFolderAndContinue
Bingo, it ends up that we should use PickSingleFileAndContinue
instead of PickSingleFileAsync.
Now let’s see how PickSingleFileAndContinue works. One thing
I want to get you be prepared, it is much complicated PickSingleFileAsync.
First of all, I would
like to refresh you on Windows Phone (Windows Store)Application life cycle as
following:
When PickSingleFileAndContinue is called, you app is
suspended into Suspended mode and then terminated to NotRunning state, when the
user is done with his or her file picking operation, the app will be reactivated to running state.
When the app is activated, the app’s OnActivated event is fired. You need
to add the event handler in your Application class. Most likely it is part of the code behind file
for App.XAML
protected async override void OnActivated(IActivatedEventArgs args)
{base.OnActivated(args);
var rootFrame = CreateRootFrame();
await RestoreStatusAsync(args.PreviousExecutionState);
if (rootFrame.Content == null)
{rootFrame.Navigate(typeof(MainPage));
}
if (rootFrame.Content is PhotoPage)
{var photoPage = rootFrame.Content as PhotoPage;
if (args is FileOpenPickerContinuationEventArgs)
{photoPage.ContinueFileOpenPicker(args as FileOpenPickerContinuationEventArgs);
}
}
}
Here CreateRootFrame and RestoreStatusAsync are 2
private methods. I will show the code for them at the bottom of this post.
What it does is get the previous page when the app is suspended. And
then check to see if the argument is FileOpenPickerContinuationEventArgs. If so call a method
in the page’s code behind class.
Now let’s see how it is handled in the page level and how to
access the file that the user picked.
public async void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{if (args.Files != null)
{
var file = args.Files.FirstOrDefault();
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
// Set the image source to the selected bitmap.
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(fileStream);
displayImage.Source = bitmapImage;}
}
The file the user picked is in the Argrment.Files collection. In this
case, as I used PickSingleFileAndContinue,so
there should be only one file, if you use PickMultipleFilesAndContinue, you will have multiple
files in this collection.
All you need to do is to open the file and steam and create a
bitmapImage with the stream file then use it as the source for the Image
element in your XAML.
The following are the rest of the code needed for the app to work:
private Frame CreateRootFrame()
{var rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame {Language = Windows.Globalization.ApplicationLanguages.Languages[0]};
// Set the default language
rootFrame.NavigationFailed += OnNavigationFailed;
// Place the frame in the current Window
Window.Current.Content =
rootFrame;}
return rootFrame;
}
private async Task RestoreStatusAsync(ApplicationExecutionState
previousExecutionState)
{// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (previousExecutionState == ApplicationExecutionState.Terminated)
{
// Restore the saved session state only when appropriate
try
{
await SuspensionManager.RestoreAsync();
}
catch (SuspensionManagerException)
{
//Something went wrong restoring state.
//Assume there is no state and continue
}
}
}
private void OnNavigationFailed(object sender, NavigationFailedEventArgs
e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
Thanks, that's really helpful. I will try to split the logic for my windows phone application.
ReplyDeleteWow. your post is helpful indeed. Such things about windows app development should be shared frequently.
ReplyDelete