UWP中,微软为Windows.System.Launcher启动器新增了很多的功能,以前只能启动App,打开指定扩展名文件,对uri协议的解析,以及当启动的应用没有安装时则会提示前往商店下载等。

如今,微软丰富了Launcher的功能,使用新的Launcher我们可以在App中实现调用文件资源管理器、App-To-App Server(应用对应用服务),Background Task Server App(后台任务处理服务App)还有设置页面调用。

一:Launcher.LaunchFolderAsync

该方法可以打开指定的文件夹,有两个方法重载:

1 public static IAsyncOperation<System.Boolean> LaunchFolderAsync(IStorageFolder folder);
2 public static IAsyncOperation<System.Boolean> LaunchFolderAsync(IStorageFolder folder, FolderLauncherOptions options);

比如我们可以在App中打开设备的图片文件夹

var picturesLibrary = await Launcher.LaunchFolderAsync(KnownFolders.PicturesLibrary);

KnownFolders给我们提供了很多可访问的文件夹位置

在尝试访问这些文件夹的时候,我们还需要在Package.appxmanifest中声明相应的权限

1 <uap:CapabilityName="picturesLibrary"/>
View Code

二:Launcher.LaunchUriForResultsAsync

我个人习惯称之为:AppToApp 应用于应用之间的通讯

通过新增的LaunchUriForResultsAsync API,Windows应用程序(以及Windows Web App)可以相互启动并交换数据和文件。利用这个新的API,使得以前需要多个App才能完成的复杂任务现在可以无缝的进行处理,使用户根本无法感觉到应用之间的切换。比如我们可以启动社交App来选择联系人,或者应用在支付的场景。

如果要使用AppToApp,首先我们需要在被启动的App中声明Protocol服务:

 1   <Applications>
 2     <Application Id="App"
 3       
 4     ……
 5  
 6       <!--  在能够提供外部调用服务的App中注册处理的协议 
 7       在协议中,ReturnResults有三种可能的值
 8        
 9         ● optional  应用可以通过使用LaunchUriForResultsAsync针对处理结果进行启动,而不是LaunchUriAsync。
10                      当使用optional时,调用的应用必须明确认定它是可以针对结果而调用的App(确认是AppToApp模式),我们还可以检查
11                      OnActivated()事件参数进行确定。如果事件参数的IactivatedEventArgs.Kind属性值是ProtocolForResults,或
12                      事件参数类型是ProtocolActivatedEventArgs,则可以确定应用是通过LaunchUriForResultsAsync启动的。
13                       
14         ● always    应用只能通过AppToApp模式调用,即它只能通过LaunchUriForResultsAsync调用
15          
16         ● none      应用不能通过AppToApp进行调用,即它只能通过LaunchUriAsync调用-->
17       <Extensions>
18         <uap:Extension Category="windows.protocol">
19           <uap:Protocol Name="app2app-sample" ReturnResults="optional">
20             <uap:DisplayName>App2App Sample</uap:DisplayName>
21           </uap:Protocol>
22         </uap:Extension>
23       </Extensions>
24     </Application>
25 </Applications>

然后在App.xaml.cs中重写OnActivated方法

 1 protected override void OnActivated(IActivatedEventArgs args)
 2 {
 3     if (args.Kind == ActivationKind.ProtocolForResults)
 4     {
 5         Frame rootFrame = Window.Current.Content as Frame;
 6         if (rootFrame == null)
 7         {
 8             rootFrame = new Frame();
 9             Window.Current.Content = rootFrame;
10         }
11         var protocolArgs = (ProtocolForResultsActivatedEventArgs)args;
12         rootFrame.Navigate(typeof(App2AppPage), protocolArgs);
13         Window.Current.Activate();
14     }
15 }

上面代码中我们需要检查下IActivatedEventArgs.Kind的值是否是ProtocolForResults来确定应用是否是使用AppToApp方式被启动起来的。如果是,则跳转到提供服务的页面App2AppPage,并传递数据参数。

在App2AppPage页面中我们重写OnNavigatedTo方法来接收数据,OnNavigationTo方法中NavigationEventArgs包含从调用方应用传来的数据。

Ok,开始重写OnNavigatedTo方法

 1 protected override void OnNavigatedTo(NavigationEventArgs e)
 2 {
 3     var protocolForResultsArgs = e.Parameter as ProtocolForResultsActivatedEventArgs;
 4     _operation = protocolForResultsArgs.ProtocolForResultsOperation;
 5     if (protocolForResultsArgs.Data.ContainsKey("TestData"))
 6     {
 7         var dataFromCaller = protocolForResultsArgs.Data["TestData"] as string;
 8         //页面显示得到的数据
 9         testData.Text = dataFromCaller;
10     }
11 }

当应用处理完数据后,可以调用ProtocolForResultsOperation. ReportCompleted方法将一个ValueSet对象返回到调用方App

1 private void Button_Click(object sender, RoutedEventArgs e)
2 {
3     var result = new ValueSet();
4     result["ReturnData"] = string.Format("他给了你{0}", money.Text);
5     _operation.ReportCompleted(result);
6 }

至此,被调用方App逻辑已完成

返回我们的调用方,使用Launcher.LaunchUriForResultsAsync方法调用App2并让App2帮助处理逻辑。

 1 private async Task<string> GetLaunchAppForResults()
 2    {
 3        string resultTxt = string.Empty;
 4        //被调用方的 Protocol Name
 5        var testAppUri = new Uri("app2app-sample:");
 6  
 7        var options = new LauncherOptions
 8        {
 9            //这个东东是被调用方的TargetApplicationPackageFamilyName  
10            //可以在被调用方里使用 Windows.ApplicationModel.Package.Current.Id.FamilyName 方法来拿到
11            //当然被调用方也可以将这个值存储到共享文件夹中 方便其他App获取
12            //要使用共享文件夹 则可以使用 ShareStorageAccessManager 类来处理
13            //ShareStorageAccessManager 以后会讲解到
14            TargetApplicationPackageFamilyName = "0de26e7d-8c3d-4040-8275-93a92570666d_md3s7cn435nw2"
15        };
16  
17        //要传递的数据 ValueSet最大不能超过100k
18        var inputData = new ValueSet();
19        inputData["TestData"] = "一百块都不给我,打我还要叫人来……一百一百一百块";
20  
21        //启动App2 要去提供服务
22        LaunchUriResult result = await Windows.System.Launcher.LaunchUriForResultsAsync(testAppUri, options, inputData);
23  
24        //结果的处理
25        if (result.Status == LaunchUriStatus.Success &&
26            result.Result != null &&
27            result.Result.ContainsKey("ReturnData"))
28        {
29            var theValues = result.Result;
30            resultTxt = theValues["ReturnData"] as string;
31        }
32        return resultTxt;
33 }

我们模仿小红帽(App1)向大叔要钱,QAQ来看效果:

 

推荐一个UWP开发群:53078485 大家可以进来一起学习~~