Fork me on GitHub

UWP 使用OneDrive云存储2.x api(二)【全网首发】

接上一篇 http://www.cnblogs.com/hupo376787/p/8032146.html

上一篇提到为了给用户打造一个完全无缝衔接的最佳体验,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
            {
                // OnlineId
                if (indexProvider == 0)
                {
                    OneDriveService.Instance.Initialize();
                }
                //Microsoft account with client id
                else if (indexProvider == 1)
                {
                    OneDriveService.Instance.Initialize(appClientId, AccountProviderType.Msa, OneDriveScopes.AppFolder | OneDriveScopes.ReadWrite);
                }
                //Work or school account with client id
                else 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);
                else
                    await 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流程如下 

  1. 注册应用以获取应用 ID。
  2. 使用令牌流或代码流通过指定的作用域让用户登录。就是上面的 SigninAsync函数
  3. 上传下载操作
  4. 注销用户(可选)。

 

 

 

以上就是在我的【微识别/WeRecognition】场景里面使用的实际代码分享,如有不足之处,敬请指正。谢谢。

posted @ 2017-12-13 12:16  猫叔Vincent  阅读(1013)  评论(4编辑  收藏  举报