上一篇提到为了给用户打造一个完全无缝衔接的最佳体验,UWP开发者最好也要实现App设置和数据的跨平台
分析了数据漫游和OneDrive的优缺点,结合自己App实际需要,我选择了OneDrive。
毕竟数据漫游100KB不够用啊。。。
这一次给大家我千辛万苦找来的、非常简单的使用OneDrive 2.x api使用方法。
那就是隐藏在官方UWP Community Toolkit Sample App中的OneDrive Service中
我觉得平时我看这个App已经够多了,以前也瞄过一眼这个OneDrive Service,但是在真真使用它的时候,偏偏想不起来了。
我用过这里面的Grid Splitter、Markdown Textbox、RadialProgressBar、等等太多了
这是一个非常好的例子,商店有下载,gayhub也有源代码
不得不说,微软开发这个App的人员非常伟大了。。。哈哈哈😂
下面就结合我自己的【微识别/WeRecognition】代码来和大家说一下。
1. 授权
要访问OneDrive,首先需要授权。
授权有三种方式:
OnlineId,最简单,我就用这个,也是推荐UWP开发者使用的
Microsoft account with client id
Work or school account with client id
private OneDriveStorageFolder _appFolder = null;这个用来获取OneDrive下面的应用文件夹
private async Task SigninAsync(int indexProvider = 0, string appClientId = null){if (!IsInternetAvailable())return;ShowBusy(true);try{// OnlineIdif (indexProvider == 0){OneDriveService.Instance.Initialize();}//Microsoft account with client idelse if (indexProvider == 1){OneDriveService.Instance.Initialize(appClientId, AccountProviderType.Msa, OneDriveScopes.AppFolder | OneDriveScopes.ReadWrite);}//Work or school account with client idelse if (indexProvider == 2){OneDriveService.Instance.Initialize(appClientId, AccountProviderType.Adal);}if (await OneDriveService.Instance.LoginAsync()){_appFolder = await OneDriveService.Instance.AppRootFolderAsync();ShowBusy(false);}else{ShowBusy(false);throw new Exception("Unable to sign in");}}catch (ServiceException serviceEx){var dialog = new MessageDialog(serviceEx.Message, "Error!");await dialog.ShowAsync();ShowBusy(false);}catch (Exception ex){var dialog = new MessageDialog(ex.Message, "Error!");await dialog.ShowAsync();ShowBusy(false);}finally{ShowBusy(false);}}
注意:用的时候,最好加上上面捕捉的那些异常,以防万一。
接下来无非就是,上传下载文件咯。【我没有做别的一些操作,比如在OneDrive上新建文件(夹),或者缩略图等,你可以自行看那个App说明】
我不想把简单的事情搞得复杂,这个团队做的也是这样,能简单就简单。不信你上传的代码
上传
var size = await file.GetBasicPropertiesAsync();if (size.Size >= 4 * 1024 * 1024)await OneDriveServiceHelper.UploadLargeFileAsync(file, strBackupName, CreationCollisionOption.ReplaceExisting, _appFolder);elseawait OneDriveServiceHelper.UploadSimpleFileAsync(file, strBackupName, CreationCollisionOption.ReplaceExisting, _appFolder);
不过这要区分一下是不是超过4M,两种上传方式,用我的代码判断一下即可。
具体为啥区分,请去看官方gayhub上面的Issues讨论。
两个函数的原型
UploadSimpleFileAsync
public static async Task UploadSimpleFileAsync(OneDriveStorageFolder folder){try{if (folder != null){var selectedFile = await OpenLocalFileAsync();if (selectedFile != null){using (var localStream = await selectedFile.OpenReadAsync()){var fileCreated = await folder.CreateFileAsync(selectedFile.Name, CreationCollisionOption.GenerateUniqueName, localStream);}}}}catch (OperationCanceledException ex){await OneDriveServiceHelper.DisplayMessageAsync(ex.Message);}catch (ServiceException graphEx){await OneDriveServiceHelper.DisplayMessageAsync(graphEx.Error.Message);}catch (Exception ex){await OneDriveServiceHelper.DisplayMessageAsync(ex.Message);}finally{}}
UploadLargeFileAsync
public static async Task UploadLargeFileAsync(OneDriveStorageFolder folder){try{if (folder != null){var selectedFile = await OpenLocalFileAsync();if (selectedFile != null){using (var localStream = await selectedFile.OpenReadAsync()){// If the file exceed the Maximum size (ie 4MB)var largeFileCreated = await folder.UploadFileAsync(selectedFile.Name, localStream, CreationCollisionOption.GenerateUniqueName, 320 * 1024);}}}}catch (OperationCanceledException ex){await OneDriveServiceHelper.DisplayMessageAsync(ex.Message);}catch (ServiceException graphEx){await OneDriveServiceHelper.DisplayMessageAsync(graphEx.Error.Message);}catch (Exception ex){await OneDriveServiceHelper.DisplayMessageAsync(ex.Message);}finally{}}
你可能注意到了,官方的函数参数和我用的不一样,是的。我重新封装了。
官方的是var selectedFile = await OpenLocalFileAsync();,需要手动选择文件。在我的场景里面,是自动选择数据库文件上传的,让用户选择,就不合适了
下载
var remoteFile = await _appFolder.GetFileAsync(strBackupName);using (var remoteStream = await remoteFile.OpenAsync()){byte[] buffer = new byte[remoteStream.Size];var localBuffer = await remoteStream.ReadAsync(buffer.AsBuffer(), (uint)remoteStream.Size, InputStreamOptions.ReadAhead);var localFolder = ApplicationData.Current.LocalFolder;var myLocalFile = await localFolder.CreateFileAsync(SQLiteHelper.FaceDbName, CreationCollisionOption.ReplaceExisting); using (var localStream = await myLocalFile.OpenAsync(FileAccessMode.ReadWrite)){await localStream.WriteAsync(localBuffer);await localStream.FlushAsync();TipServices.TipDataDownloadFromCloudComplete();}
下载不区分什么大小文件,很简单的
=================================================================================
总结
UWP本来就是小众,资料少之又少,我走过了坑,记录下来,对以后用到OneDrive 开发的有所帮助。
使用OneDrive Api 2.x流程如下
- 注册应用以获取应用 ID。
- 使用令牌流或代码流通过指定的作用域让用户登录。就是上面的 SigninAsync函数
- 上传下载操作
- 注销用户(可选)。
以上就是在我的【微识别/WeRecognition】场景里面使用的实际代码分享,如有不足之处,敬请指正。谢谢。