重要的应用程序接口(API)
了解如何从另一个应用启动应用并在两者之间交换数据。 这称为 启动应用以获取结果。 此处的示例演示如何使用 LaunchUriForResultsAsync 启动应用以获取结果。
Windows 10 中的新应用到应用通信 API 使 Windows 应用(和 Windows Web 应用)能够启动应用并交换数据文件。 这样,便可以从多个应用生成混合解决方案。 使用这些新 API,现在可以无缝处理需要用户使用多个应用的复杂任务。 例如,你的应用可以启动社交网络应用以选择联系人,或启动结帐应用以完成付款过程。
将您启动以获取结果的应用称为已启动的应用。 启动应用的应用将称为调用应用。 在此示例中,你将同时编写调用应用和启动的应用。
步骤 1:在您将启动以获取结果的应用中注册要处理的协议。
在启动应用的 Package.appxmanifest 文件中,将协议扩展添加到 <应用程序> 部分。 此处的示例使用名为 test-app2app
协议扩展中的 ReturnResults 属性接受以下值之一:
- 可选— 可以通过使用 LaunchUriForResultsAsync 方法来启动应用以获取结果,或通过使用 LaunchUriAsync来启动应用而不获取结果。 使用 可选的时,启动的应用必须确定它是否是为了获取结果而启动的。 它可以通过检查 OnActivated 事件参数来执行此操作。 如果参数的 IActivatedEventArgs.Kind 属性返回 ActivationKind.ProtocolForResults,或者事件参数类型为 ProtocolActivatedEventArgs,应用是通过 LaunchUriForResultsAsync启动的。
- 始终—应用只能为了结果而启动,也就是说,它只能响应 LaunchUriForResultsAsync。
无 — 无法针对结果启动应用;它只能响应 launchUriAsync。
在此协议扩展示例中,应用只能为了获取结果而启动。 这简化了下面讨论的 OnActivated 方法内的逻辑结构,因为我们必须仅处理“针对结果启动”的情况,而不是应用可能被激活的其他方式。
<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 指定为始终
步骤 3:将 ProtocolForResultsOperation 字段添加到启动以获取结果的应用程序中
private Windows.System.ProtocolForResultsOperation _operation = null;
Windows::System::ProtocolForResultsOperation _operation = nullptr;
你将使用 ProtocolForResultsOperation 字段来指示启动的应用何时准备好将结果返回到调用应用。 在此示例中,字段被添加到 LaunchedForResultsPage 类中,因为你将在该页上完成启动以获取结果的操作,并且需要访问它。
步骤 4:在用于获取结果的应用中覆盖 OnNavigatedTo() 方法
重写在启动应用以获取结果时显示的页面上的 OnNavigatedTo 方法。 如果此方法尚不存在,请在 <pagename>.xaml.cs 中定义的页面的类中创建此方法。 确保在文件顶部包含以下具有 语句的
using Windows.ApplicationModel.Activation
using namespace winrt::Windows::ApplicationModel::Activation;
OnNavigatedTo 方法中的 NavigationEventArgs 对象包含从调用应用传递的数据。 数据可能不超过 100KB,并且存储在 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 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;
}
在此示例中,包含密钥 TestData 的 ValueSet 被传递给启动的应用。 启动的应用创建一个 ValueSet,其键名为 ReturnedData,其中包含返回给调用端的结果。
在运行呼叫应用程序之前,您必须构建并部署要启动以获得结果的应用程序。 否则,
当您设置 TargetApplicationPackageFamilyName时,您将需要已启动应用的家族名称。 获取姓氏的一种方法是在启动的应用程序中进行以下调用:
string familyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
注解
本教程示例提供了一个“你好,世界”简介,用于启动应用程序以获取结果。 需要注意的关键是,新的 LaunchUriForResultsAsync API 允许异步启动应用并通过 ValueSet 类进行通信。 通过 ValueSet 传递数据限制为 100KB。 如果需要传递大量数据,可以使用 SharedStorageAccessManager 类来共享文件,以创建可在应用之间传递的文件令牌。 例如,给定一个名为 的 inputData
,你可以将令牌存储在文件中,以便与已经启动的应用程序共享。
inputData["ImageFileToken"] = SharedStorageAccessManager.AddFile(myFile);
然后,通过 LaunchUriForResultsAsync将其传递给启动的应用。
相关主题