次の方法で共有


結果を得るためのアプリを起動する

重要な API

別のアプリからアプリを起動し、2 つのアプリ間でデータを交換する方法について説明します。 これを、結果を得るためにアプリを起動すること と呼びます。 次の例では、 LaunchUriForResultsAsync を使用して結果のアプリを起動する方法を示します。

Windows 10 の新しいアプリ間通信 API により、Windows アプリ (および Windows Web アプリ) がアプリを起動し、データとファイルを交換できるようになります。 これにより、複数のアプリからマッシュアップ ソリューションを構築できます。 これらの新しい API を使用すると、ユーザーが複数のアプリを使用する必要がある複雑なタスクをシームレスに処理できるようになりました。 たとえば、アプリでソーシャル ネットワーキング アプリを起動して連絡先を選択したり、チェックアウト アプリを起動して支払いプロセスを完了したりできます。

結果のために起動するアプリは、起動されたアプリと呼ばれます。 アプリを起動するアプリは、呼び出し元アプリと呼ばれます。 この例では、呼び出し元のアプリと起動されたアプリの両方を記述します。

手順 1: 結果のために起動するアプリで処理するプロトコルを登録する

起動したアプリの Package.appxmanifest ファイルで、プロトコル拡張機能を <Application> セクションに追加します。 この例では、 test-app2app という名前の架空のプロトコルを使用しています。

プロトコル拡張機能の ReturnResults 属性は、次のいずれかの値を受け入れます。

  • 省略可能なLaunchUriForResultsAsync メソッドを使用して結果を得るようにアプリを起動することができるか、LaunchUriAsyncメソッドを使用して結果を得ずにアプリを起動することができます。 オプションを使用する場合は、起動されたアプリが結果のために起動されたかどうかを判断する必要があります。 これを行うには、 OnActivated イベント引数を確認します。 引数の IActivatedEventArgs.Kind プロパティが ActivationKind.ProtocolForResults を返す場合、またはイベント引数の型が ProtocolActivatedEventArgs の場合、アプリは LaunchUriForResultsAsync を介して起動されました。
  • always - アプリは結果のためだけに起動できます。つまり、 LaunchUriForResultsAsync にのみ応答できます。
  • none - 結果のためにアプリを起動できません。 LaunchUriAsync にのみ応答できます。

このプロトコル拡張の例では、結果のためだけにアプリを起動できます。 これにより、以下で説明する OnActivated メソッド内のロジックが簡略化されます。これは、アプリをアクティブ化できるその他の方法ではなく、"launched for results" ケースのみを処理する必要があるためです。

<Applications>
   <Application ...>

     <Extensions>
       <uap:Extension Category="windows.protocol">
         <uap:Protocol Name="test-app2app" ReturnResults="always">
           <uap:DisplayName>Test app-2-app</uap:DisplayName>
         </uap:Protocol>
       </uap:Extension>
     </Extensions>

   </Application>
</Applications>

手順 2: 結果のために起動するアプリで Application.OnActivated をオーバーライドする

起動したアプリにこのメソッドがまだ存在しない場合は、App.xaml.csで定義されている App クラス内に作成します。

ソーシャル ネットワークでフレンドを選択できるアプリでは、この関数はユーザー選択ページを開く場所である可能性があります。 次の例では、結果に対してアプリがアクティブ化されると 、LaunchedForResultsPage という名前のページが表示されます。 ステートメントを使用した がファイルの先頭に含まれていることを確認します。

using Windows.ApplicationModel.Activation;
...
protected override void OnActivated(IActivatedEventArgs args)
{
    // Window management
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame == null)
    {
        rootFrame = new Frame();
        Window.Current.Content = rootFrame;
    }

    // Code specific to launch for results
    var protocolForResultsArgs = (ProtocolForResultsActivatedEventArgs)args;
    // Open the page that we created to handle activation for results.
    rootFrame.Navigate(typeof(LaunchedForResultsPage), protocolForResultsArgs);

    // Ensure the current window is active.
    Window.Current.Activate();
}
using namespace winrt::Windows::ApplicationModel::Activation;
...
protected override void OnActivated(IActivatedEventArgs args)
{
    // Window management
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }
    
    if (rootFrame == null)
    {
        rootFrame = Frame();
        Window::Current().Content(rootFrame);
    }

    // Code specific to launch for results
    auto protocolForResultsEventArgs{ args.as<ProtocolForResultsActivatedEventArgs>() };
    // Open the page that we created to handle activation for results.
    rootFrame.Navigate(xaml_typename<LaunchedForResultsPage>(), protocolForResultsArgs);

    // Ensure the current window is active.
    Window::Current().Activate();
}

Package.appxmanifest ファイルのプロトコル拡張機能では、常にとして ReturnResults 指定されているため、示されているコードは を直接 Protocol にキャストできますForResultsActivatedEventArgsProtocolForResultsActivatedEventArgs のみが、このアプリの OnActivated に送信されます。 結果の起動以外の方法でアプリをアクティブ化できる場合は、 IActivatedEventArgs.Kind プロパティが ActivationKind.ProtocolForResults を返して、アプリが結果のために起動されたかどうかを確認できます。

手順 3: 結果を得るために起動するアプリに ProtocolForResultsOperation フィールドを追加する

private Windows.System.ProtocolForResultsOperation _operation = null;
Windows::System::ProtocolForResultsOperation _operation = nullptr;

ProtocolForResultsOperation フィールドを使用して、起動したアプリが呼び出し元アプリに結果を返す準備ができたら通知します。 この例では、そのページから結果の起動操作を完了し、それにアクセスする必要があるため、このフィールドは LaunchedForResultsPage クラスに追加されます。

手順 4: 起動したアプリで OnNavigatedTo() をオーバーライドして結果を取得する

結果を得るためのアプリの起動時に表示されるページの OnNavigatedTo メソッドをオーバーライドします。 このメソッドがまだ存在しない場合は、<ページ名>.xaml.cs で定義されているページのクラス内に作成します。 を用いたステートメントが、ファイルの先頭にとして含まれていることを確認してください。

using Windows.ApplicationModel.Activation
using namespace winrt::Windows::ApplicationModel::Activation;

OnNavigatedTo メソッドの NavigationEventArgs オブジェクトには、呼び出し元アプリから渡されたデータが含まれています。 データは 100 KB を超えず、 ValueSet オブジェクトに格納されます。

このコード例では、起動されたアプリは、呼び出し元アプリから送信されたデータが、TestData という名前のキーの下の ValueSet に含まれると想定しています。これは、この例の呼び出し元アプリが送信するようにコーディングされているためです。

using Windows.ApplicationModel.Activation;
...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var protocolForResultsArgs = e.Parameter as ProtocolForResultsActivatedEventArgs;
    // Set the ProtocolForResultsOperation field.
    _operation = protocolForResultsArgs.ProtocolForResultsOperation;

    if (protocolForResultsArgs.Data.ContainsKey("TestData"))
    {
        string dataFromCaller = protocolForResultsArgs.Data["TestData"] as string;
    }
}
...
private Windows.System.ProtocolForResultsOperation _operation = null;
using namespace winrt::Windows::ApplicationModel::Activation;
...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    auto protocolForResultsArgs = e.Parameter().try_as<ProtocolForResultsActivatedEventArgs>();
    // Set the ProtocolForResultsOperation field.
    _operation = protocolForResultsArgs.ProtocolForResultsOperation();

    if (protocolForResultsArgs.Data().HasKey("TestData"))
    {
        string dataFromCaller{ unbox_value<hstring>(protocolForResultsArgs.Data().Lookup("TestData")) };
    }
}
...
Windows::System::ProtocolForResultsOperation _operation = nullptr;

手順 5: 呼び出し元アプリにデータを返すコードを記述する

起動したアプリで、 ProtocolForResultsOperation を使用して、呼び出し元のアプリにデータを返します。 このコード例では、呼び出し元アプリに返す値を含む ValueSet オブジェクトが作成されます。 その後、ProtocolForResultsOperation フィールドを使用して、呼び出し元アプリに値を送信します。

    ValueSet result = new ValueSet();
    result["ReturnedData"] = "The returned result";
    _operation.ReportCompleted(result);
    ValueSet result;
    result.Insert("ReturnedData", "The returned result");
    _operation.ReportCompleted(result);

手順 6: 結果のためにアプリを起動し、返されたデータを取得するコードを記述する

このコード例に示すように、呼び出し元アプリの非同期メソッド内からアプリを起動します。 コードをコンパイルするために必要な using ステートメントに注意してください。

using System.Threading.Tasks;
using Windows.System;
...

async Task<string> LaunchAppForResults()
{
    var testAppUri = new Uri("test-app2app:"); // The protocol handled by the launched app
    var options = new LauncherOptions();
    options.TargetApplicationPackageFamilyName = "67d987e1-e842-4229-9f7c-98cf13b5da45_yd7nk54bq29ra";

    var inputData = new ValueSet();
    inputData["TestData"] = "Test data";

    string theResult = "";
    LaunchUriResult result = await Windows.System.Launcher.LaunchUriForResultsAsync(testAppUri, options, inputData);
    if (result.Status == LaunchUriStatus.Success &&
        result.Result != null &&
        result.Result.ContainsKey("ReturnedData"))
    {
        ValueSet theValues = result.Result;
        theResult = theValues["ReturnedData"] as string;
    }
    return theResult;
}

この例では、ValueSet に TestData キーを含むものが起動されたアプリに渡されます。 起動されたアプリは、呼び出し元に返された結果を含む ReturnedData という名前のキーを持つ ValueSet を作成します。

呼び出し元アプリを実行する前に、結果のために起動するアプリをビルドしてデプロイする必要があります。 それ以外の場合、 LaunchUriResult.StatusLaunchUriStatus.AppUnavailable を報告します。

TargetApplicationPackageFamilyName を設定するときに、起動したアプリのファミリ名が必要になります。 ファミリ名を取得する方法の 1 つは、起動したアプリ内から次の呼び出しを行う方法です。

string familyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;

注釈

このハウツーの例では、結果を得るためにアプリを起動するための "hello world" の概要を示します。 重要な点は、新しい LaunchUriForResultsAsync API を使用すると、アプリを非同期的に起動し、 ValueSet クラスを介して通信できることです。 ValueSet を介したデータの受け渡しは 100 KB に制限されています。 大量のデータを渡す必要がある場合は、 SharedStorageAccessManager クラスを使用してファイルを共有し、アプリ間で渡すことができるファイル トークンを作成できます。 たとえば、という名前の inputData を指定すると、起動したアプリと共有するファイルにトークンを格納できます。

inputData["ImageFileToken"] = SharedStorageAccessManager.AddFile(myFile);

次に、LaunchUriForResultsAsyncを使って、アプリを起動し、そのアプリにデータを渡します。