啟動應用程式以取得結果
重要 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 語句包含在檔案頂端。
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,因此剛剛顯示的程式碼可以 args
直接轉換為 ProtocolForResultsActivatedEventArgs,並且確信只有 ProtocolForResultsActivatedEventArgs 會傳送到此應用程式的 OnActivated。 如果您的 app 可以啟動結果以外的方式來啟動,您可以檢查 IActivatedEventArgs.Kind 屬性是否傳回 ActivationKind.ProtocolForResults,以判斷應用程式是否已針對結果啟動。
步驟 3:將 ProtocolForResultsOperation 欄位新增至您針對結果啟動的應用程式
private Windows.System.ProtocolForResultsOperation _operation = null;
Windows::System::ProtocolForResultsOperation _operation = nullptr;
您將使用 ProtocolForResultsOperation 欄位,在啟動的應用程式準備好將結果傳回給呼叫的應用程式時發出訊號。 在此範例中,欄位會新增至 LaunchedForResultsPage 類別,因為您將從該頁面完成 launch-for-results 作業,而且需要存取它。
步驟 4:在您啟動以取得結果的應用程式中覆寫 OnNavigatedTo()
覆寫頁面上的 OnNavigatedTo 方法,以在應用程式啟動時顯示結果。 如果這個方法還不存在,請在 <pagename> 中定義的頁面類別內建立它.xaml.cs。 確保文件頂部包含以下 using 語句:
using Windows.ApplicationModel.Activation
using namespace winrt::Windows::ApplicationModel::Activation;
OnNavigatedTo 方法中的 NavigationEventArgs 物件包含從呼叫應用程式傳遞的資料。 數據可能不超過 100KB,並儲存在 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;
}
在此範例中,包含金鑰 TestData 的 ValueSet 被傳遞到啟動的應用程式。 啟動的應用程式會建立一個 ValueSet,其中包含名為 ReturnedData 的鍵,其中包含傳回給呼叫者的結果。
您必須先建置並部署要啟動以取得結果的應用程式,再執行呼叫的應用程式。 否則,LaunchUriResult.Status 會報告 LaunchUriStatus.AppUnavailable。
當您設定 TargetApplicationPackageFamilyName 時,將需要已啟動應用程式的系列名稱。 取得系列名稱的其中一個方法是從啟動的應用程式內進行下列呼叫:
string familyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
備註
本操作說明中的範例提供啟動應用程式以取得結果的 「hello world」 簡介。 需要注意的關鍵事項是,新的 LaunchUriForResultsAsync API 可讓您非同步啟動應用程式並透過 ValueSet 類別進行通訊。 透過 ValueSet 傳遞資料的限制為 100KB。 如果您需要傳遞較大的數據量,您可以使用 SharedStorageAccessManager 類別來共用檔案,以建立可在應用程式之間傳遞的檔案令牌。 例如,假設有名為 inputData
的 ValueSet,您可以將令牌儲存至您想要與啟動的應用程式共用的檔案:
inputData["ImageFileToken"] = SharedStorageAccessManager.AddFile(myFile);
然後,透過 LaunchUriForResultsAsync 將它傳遞給啟動的應用程式。
相關主題