首先先给你们推荐一个UWP/Win10开发者群:53078485 里面有不少大婶,还有不少学习资源,欢迎你们来一块儿讨论Win10开发!前端
在UWP开发中,微软提供了一个新的特性叫作SharedStorageAccessManager,它容许咱们的App根据指定的文件生成一个FileToken来共享此文件,其余App可使用SharedStorageAccessManager. RedeemTokenForFileAsync(fileToken);方法根据FileToken来获取到共享的文件。这样两个App之间就具有了共享文件的能力。app
咱们先看下SharedStorageAccessManager类中都具备哪些Api可供咱们使用:async
方法ide |
描述布局 |
AddFile学习 |
获取一个文件共享Token,使应用程序可以与另外一个应用程序共享指定的文件。ui |
RedeemTokenForFileAsyncthis |
另外一个应用程序经过一个文件共享Token来使用此文件。url |
RemoveFilespa |
撤销现有的共享Token。 |
SharedStorageAccessManager功能的使用步骤大体分为如下三个步骤:
能够看出使用SharedStorageAccessManager共享一个文件仍是挺方便的,可是须要注意的是,SharedStorageAccessManager的使用仍是有必定的限制的:
接下来咱们就作个简单的例子来看一下SharedStorageAccessManager具体的使用方法。
例子:咱们在一个App中共享一个Image文件到另外一个App中
首先建立分享者App,页面布局一个图片和一个分享按钮以下:
分享者前端XAML:
1 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 2 <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 3 <Image Source="Images/img.jpg"/> 4 <Button Click="{x:Bind ShareFileToOtherApp}" Content="分享这个图片到另外一个App" HorizontalAlignment="Right"/> 5 </StackPanel> 6 </Grid>
分享者分享Button Click方法的实现:
1 private async void ShareFileToOtherApp(object sender, RoutedEventArgs args) 2 { 3 var file = await Package.Current.InstalledLocation.GetFileAsync(@"Images\img.jpg"); 4 5 // 由于图片正在UI上使用中 因此咱们要另外建立一个该图片文件的副本进行分享 6 var localFolder = ApplicationData.Current.LocalFolder; 7 var filePath = $"{Guid.NewGuid().ToString("N")}.jpg"; 8 var sampleFile = await localFolder.CreateFileAsync(filePath, CreationCollisionOption.ReplaceExisting); 9 await file.CopyAndReplaceAsync(sampleFile); 10 11 // 获取要分享的文件的Token 12 var sharingToken = SharedStorageAccessManager.AddFile(sampleFile); 13 14 //设置要分享到的 App 的 Uri 15 var driveTo = new Uri("aran.sharetargetsample:?SharedImgToken=" + sharingToken); 16 var launch = await Launcher.LaunchUriAsync(driveTo); 17 }
分享者的代码至此完成,是否是很简单?接下来咱们去作接收者App,因为咱们是经过Launcher.LaunchUriAsync的方式将Token传递到接收者App中,因此咱们须要让接收者App支持Uri启动协议
首先建立一个新的项目做为接收者,而后双击打开Package.appxmanifest文件,选择"声明"选项卡,添加一个"协议"的声明,填写协议声明的"显示名称"和"名称",例以下图:
须要注意的是,"名称"的填写是不能使用大写字母的。
这个协议填写好后保存并运行下咱们的程序来检查下启动协议是否声明成功
咱们依次打开计算机的"控制面板 – 默认程序 – 设置默认程序",若是声明成功,在程序列表中能够找到咱们设置的ShareTargetSample程序,点击"选择此程序的默认值",就能够查看到咱们的启动协议了,以下:
从描述信息中咱们能够看出咱们的URL为:aran.sharetargetsample,咱们打开一个文件资源管理器,在文件路径中键入"aran.sharetargetsample:"后回车,这时系统就会经过URL协议激活并启动咱们的App
完成上面的操做仅仅是可以经过URL激活启动咱们的程序,那么怎么在激活程序时获取到外界传递过来的参数呢?咱们须要在接收者的App.cs里App类中重写OnActivated方法来判断是否由Url协议启动App,若是是则获取参数
OnActivated方法代码以下:
1 protected async override void OnActivated(IActivatedEventArgs args) 2 { 3 base.OnActivated(args); 4 //判断是否由LaunchUriAsync方式启动 5 if (args.Kind != ActivationKind.Protocol) return; 6 var protocolArgs = args as ProtocolActivatedEventArgs; 7 8 // 从uri中获取文件token 9 if (protocolArgs == null) return; 10 var queryStrings = new WwwFormUrlDecoder(protocolArgs.Uri.Query); 11 var sharedImgToken = queryStrings.GetFirstValueByName("SharedImgToken"); 12 13 // 根据该token读取文件 14 if (string.IsNullOrEmpty(sharedImgToken)) return; 15 var file = await SharedStorageAccessManager.RedeemTokenForFileAsync(sharedImgToken); 16 17 // 本地建立一个File用来接收该文件 18 var localFolder = ApplicationData.Current.LocalFolder; 19 var filePath = $"{Guid.NewGuid().ToString("N")}.jpg"; 20 var sampleFile = await localFolder.CreateFileAsync(filePath, CreationCollisionOption.ReplaceExisting); 21 await file.CopyAndReplaceAsync(sampleFile); 22 23 24 // 获取页面引用 25 var root = Window.Current.Content as Frame; 26 if (root == null) 27 { 28 root = new Frame(); 29 Window.Current.Content = root; 30 } 31 // 导航到指定的页面并传递文件路径 32 root.Navigate(typeof(MainPage), Path.Combine(localFolder.Path, filePath)); 33 // 确保当前窗口处于活动状态 34 Window.Current.Activate(); 35 }
由于程序有可能被多种方式激活,因此上面的方法中咱们首先要判断接收者App被激活的类型是否为ActivationKind.Protocol,而后咱们再根据url中的参数获取到共享文件的Token值并经过SharedStorageAccessManager.RedeemTokenForFileAsync方法获得共享的文件(这里咱们忽略掉App是否已是正在运行中以及忽略跳转到MainPage页面是否合理,项目中可根据需求跳转到其余页面)
拿到共享文件后,咱们先保存文件到本身的App根目录中,而后将文件路径传递到显示共享文件的页面并跳转到该页面
共享文件显示页面的逻辑很简单,获取共享文件存放的文件路径,而后展现该文件,代码以下:
1 public sealed partial class MainPage : Page, INotifyPropertyChanged 2 { 3 private ImageSource _imgUri; 4 public ImageSource ImgUri 5 { 6 get { return _imgUri; } 7 set 8 { 9 _imgUri = value; 10 SendPropertyChanged(); 11 } 12 } 13 14 public event PropertyChangedEventHandler PropertyChanged; 15 public void SendPropertyChanged([CallerMemberName] string propertyName = null) 16 { 17 var handler = PropertyChanged; 18 handler?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 19 } 20 21 22 public MainPage() 23 { 24 this.InitializeComponent(); 25 } 26 27 protected override void OnNavigatedTo(NavigationEventArgs e) 28 { 29 if (e.Parameter != null && !(string.IsNullOrEmpty(e.Parameter.ToString()) && e.Parameter is string)) 30 { 31 ImgUri = new BitmapImage(new Uri(e.Parameter.ToString(), UriKind.RelativeOrAbsolute)); 32 } 33 base.OnNavigatedTo(e); 34 } 35 }
前台页面XAML中放置一个Image元素,绑定Image的Source到后台ImgUri属性上便可
最终效果: