Windows Phone 8.1 でピクチャーハブから写真を選択する #wpdev_jp
Windows Phone 8.1ではメモリが少ないデバイス用にいくつかのAPIで、アプリがサスペンドして、ユーザー操作後に復帰するようになっています。開発者的には気を遣うことが増えたわけですが、ユーザーフレンドリー。
そして、Windows ストアアプリとコードを共有するユニバーサル アプリでは、それらのAPIに対してWindows ストアアプリ用のHogeAsync
とWindows Phone用のHogeAndContinue
が提供されています。HogeAndContinue
を呼ぶとサスペンドするので、アプリの復帰処理を適切に行う必要があります。
ピクチャーハブから写真を選択する
従来のWindows Phoneアプリ(ここではWindows Phone 8以前)ではPhotoChooserTask
を使用しますが、ここではWindows ストアアプリと同様にFileOpenPicker
を使用します。
ピクチャーハブの呼び出し
まず、拡張子や参照場所などの準備をします。
var picker = new FileOpenPicker { .ViewMode = viewMode, .SuggestedStartLocation = PickerLocationId.PicturesLibrary }; foreach (var extension in SupportedExtensions) { // .jpgとか.pngとか picker.FileTypeFilter.Add(extension); }
次に、対象とするプロジェクトに合わせた#ifディレクティブでAPIを呼びます。
#if WINDOWS_APP await picker.PickSingleFileAsync(); #else picker.PickSingleFileAndContinue(); #endif
サスペンドからの復帰
App.xaml.cs
のOnActivated
で引数がIContinuationActivatedEventArgs
か調べて処理します。
protected override void OnActivated(IActivatedEventArgs args) { // 中略: ページの復帰処理 var e = args as IContinuationActivatedEventArgs; if (e != null) { // 記事末の補助ライブラリのクラス new ContinuationManager().Continue(e); } }
ライブラリのContinue
内では、復帰したページがどのAPIからの復帰に対応しているか判別しています。
var fileOpenPickerPage = rootFrame.Content as IFileOpenPickerContinuable; if (fileOpenPickerPage != null) { fileOpenPickerPage.ContinueFileOpenPicker(args as FileOpenPickerContinuationEventArgs); }
これでPage
に引数として選んだファイルが渡されるのでアプリの用途で処理できます。
サンプル
サンプルは下記で公開しています。
- Citrus.Interactions/Citrus.Interactions/Sample/Sample.Shared at develop · KatsuYuzu/Citrus.Interactions · GitHub
- Views/PickPhotoPage.xaml
- ピクチャーハブの呼び出し
- App.xaml.cs, Views/PickPhotoPage.xaml.cs
- サスペンドからの復帰
- ViewModels/PickPhotoPageViewModel.cs
- ファイルの処理
- Views/PickPhotoPage.xaml
サンプルアプリはPrismベースで、@okazukiさんのPrismAdapterを使用しています。
補助ライブラリ
サンプルの一部は開発中のライブラリ(Citrus.Interactions)を使用したものです。
ライブラリを使用すると、ピクチャーハブの呼び出しはPickPhotoAction
というトリガーアクションを配置するだけでいいです。
<Button Content="PickPhotoAction"> <Interactivity:Interaction.Behaviors> <Core:EventTriggerBehavior EventName="Click"> <Interactions:PickPhotoAction CallbackCommand="{Binding PickPhotoCommand}" /> </Core:EventTriggerBehavior> </Interactivity:Interaction.Behaviors> </Button>