かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

UWPで共有コントラクト 受信側

送信側は簡単にできました。

blog.okazuki.jp

ということで、今度は受信側です。 受信側はPackage.appxmanifestでアプリが何を受信できるのか定義する必要があります。宣言タブで共有ターゲットを追加して、簡単な共有の説明と受け付けるデータ形式を入力します。この例ではファイルを受け取るようにしました。

f:id:okazuki:20160321152923p:plain

これで、配置をすると共有の選択肢に出てくるようになります。

f:id:okazuki:20160321153023p:plain

共有されたときの処理は、AppクラスのOnShareTargetActivatedメソッドをオーバーライドすることで記述できます。ここで、Window.Current.ContentにPageを突っ込むと、任意のページを表示することができます。

例えば、ShareTargetPageというページを作成して以下のようなXAMLを書きます。

<Page x:Class="App60.ShareTargetPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App60"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Image x:Name="Image" />
    </Grid>
</Page>

そして、以下のようなShareTargetActivatedEventArgsを受け取るメソッドを作ります。 ShareTargetActivatedEventArgsのShareOperationのDataからGetXXXメソッドで共有されたデータを取得することが出来ます。

ここでは、共有されたストレージアイテムが画像だという前提で表示するというコードを書いてます。(エラー処理とか省いてます)

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace App60
{
    public sealed partial class ShareTargetPage : Page
    {
        public ShareTargetPage()
        {
            this.InitializeComponent();
        }

        public async Task ActivateAsync(ShareTargetActivatedEventArgs args)
        {
            var item = (await args.ShareOperation.Data.GetStorageItemsAsync()).FirstOrDefault() as StorageFile;
            var bitmap = new BitmapImage();
            using (var s = await item.OpenReadAsync())
            {
                await bitmap.SetSourceAsync(s);
            }
            this.Image.Source = bitmap;

            Window.Current.Content = this;
            Window.Current.Activate();
        }
    }
}

そして、このメソッドをAppクラスのOnShareTargetActivatedから呼んでやります。

protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
    var page = new ShareTargetPage();
    await page.ActivateAsync(args);
}

こうすると、画像を共有すると以下のような感じに画像が表示されます。

f:id:okazuki:20160321154716p:plain

ここでは表示してるだけですが、本番コードではボタンなどを置いて、ボタンが押されたらツイッターにツイートするとか、アプリ固有の処理を行うといいと思います。

共有ターゲットのデバッグ方法

小ネタですが、共有ターゲットのように他から呼び出されるような処理をデバッグする方法があります。プロジェクトのプロパティのデバッグの開始操作に起動しないが、開始時にコードをデバッグにチェックを入れておきます。

f:id:okazuki:20160321154903p:plain

こうするとデバッグ実行を押してもVisual Studioがデバッグ状態になるだけでアプリは起動しません。その状態で、共有操作などをして、アプリをキックするとデバッグが開始されます。