酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windowsストアアプリで共有コントラクトを使ってデータを共有する

Windowsストアアプリの前身でもあるWindows Phone OSですが、当時既に他のスマートフォンのフレームワークと比較して大きく劣る点がありました。アプリケーション間連携の機能が存在していませんでした。例外的にですが、「Microsoft.Phone.Tasks名前空間にあるLaunchers&Chooser API」を使うことで一部のOS標準アプリケーションとの連携をおこなうことができていました。

Windows 8から導入された強力な新機能の1つに「共有コントラクト」があります。Windowsストアアプリを開発する上で欠かせないものとなっています。他のサードベンダー製のアプリケーションとの連携ができるようになり、コントラクト対応のアプリケーションが増えれば増えるほど便利になっていきます。

共有コントラクトは、データを投げる側とデータを受け取る側のそれぞれの役割によって実装が異なります。本記事では共有コントラクトを使って、データを共有する(データを投げる)側の実装をおこないます。Windows.ApplicationModel.DataTransfer名前空間のDataTransferManagerクラスを使用しますので、usingディレクティブに以下の名前空間を宣言しておいてください。

using Windows.ApplicationModel.DataTransfer;

ここでは、ボタンのクリックをトリガーにして共有コントラクトUIを起動させていると仮定しましょう。

private void btnShare_Click(object sender, RoutedEventArgs e)
{
    // デフォルトのDataTransferManagerオブジェクトの取得
    var transferManager = DataTransferManager.GetForCurrentView();
    transferManager.DataRequested += transferManager_DataRequested;

    // 共有コントラクトUIの起動
    DataTransferManager.ShowShareUI();
}

共有コントラクトUIの起動すると、DataRequestedイベントが発生します。このイベントハンドラで共有したいものを設定します。データの種類別に共有の仕方をご紹介します。

テキストとして共有する

テキストとして共有する方法は過去に「Windowsストアアプリで共有コントラクトを使ってテキストデータを共有する - 酢ろぐ!」で詳細を書いたことがありますね。

// 共有処理が開始されると発生する。必要なデータはここで共有する
private void transferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
    DataRequest request = e.Request;

    // 共有コントラクトで表示されるタイトル
    request.Data.Properties.Title = "タイトル";
    
    // 共有するテキスト
    request.Data.SetText("ほげほげ");
}

Uriとして共有する

// 共有処理が開始されると発生する。必要なデータはここで共有する
private void transferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
    DataRequest request = e.Request;

    // 共有コントラクトで表示されるタイトル
    request.Data.Properties.Title = "タイトル";
    
    // 共有するリンク
    var url = "http://ch3cooh.jp/";
    request.Data.SetUri(new Uri(filePath));
}

画像として共有する

// 共有処理が開始されると発生する。必要なデータはここで共有する
private void transferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
    DataRequest request = e.Request;

    // 共有コントラクトで表示されるタイトル
    request.Data.Properties.Title = "タイトル";
    
    // 共有する画像
    var filePath = "ms-appdata:///local/images/logo.png";
    var strm = RandomAccessStreamReference.CreateFromUri(new Uri(filePath))
     request.Data.SetBitmap(strm);
}

共有コントラクトの受け側の実装によって、画像サイズやフォーマットによって共有が失敗するアプリケーションが存在しているようです。共通したいアプリが画像とファイル両方に対応している場合にあえて画像として共有する必要性は低いかもしれません。

ファイルとして共有する

// 共有処理が開始されると発生する。必要なデータはここで共有する
private async void transferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
    DataRequest request = e.Request;

    // 共有コントラクトで表示されるタイトル
    request.Data.Properties.Title = "タイトル";
    
    // 共有するファイル
    var filePath = "ms-appdata:///local/images/logo.png";
    var storage = await StorageFile.GetFileFromApplicationUriAsync(new Uri(filePath));
    request.Data.SetStorageItems(new[] { storage });
}

最近はどうか分かりませんが、ファイルとして共有しても受け取れるアプリが少ないかもしれません。