zoukankan      html  css  js  c++  java
  • 【uwp】浅谈China Daily中数据同步到One Drive的实现

    新版China Daily与旧版相比新增了数据同步的功能,那这个功能具体是如何实现的呢,现在让我们来一起看看。

    1.注册应用

    开发者中心的应用注册就不用多说了(https://developer.microsoft.com/windows)。因为稍后的步骤会涉及到项目与应用关联,所以各位可以先行准备好。

    2.在应用中添加相应的Nuget包

    创建工程的部分就不用我赘述了,要是不会的……自个儿撞墙去吧(ˉ▽ˉ;)...

    特别说明:安装Microsoft.OneDriveSDK的1.x版本!!

    OneDriveSDK的2.x版本和1.x版本有较大程度的差异。很尴尬的是,对于2.x版本的正确使用方式,鄙人还未能掌握,所以本文皆是以1.x版本的API进行的讲解(个人使用的是1.2.0版本SDK)。

    (PS: 如果觉得这种安装方式太low了,可以通过View -> Other Windows -> Package Manager Console安装,PM> Install-Package Microsoft.OneDriveSDK -Version 1.2.0)

     3.应用关联

    将应用程序与应用商店相关联

    关联完成后,准备工作就算是做完了。

    4.SDK的具体使用

    OneDriveSDK在China Daily中的应用,总体来说分两步走:1.身份验证 2.通过上传、下载等方法实现数据同步的功能。

    说明:我创建了一个OneDriveUtil的静态类,并在类里面实现身份验证、上传、下载的方法。所以下述(方法调用部分除外)的字段、方法都使用了static关键字进行限制。

    1)部分全局变量

    // Client
    private static IOneDriveClient _client;
    
    // 所请求的权限
    private static string[] scopes = new string[] { "onedrive.readwrite", "wl.offline_access", "wl.signin" };

    至于权限的详细信息,请参见微软相关文档https://dev.onedrive.com/auth/msa_oauth.htm

    2)身份验证

    /// <summary>
    /// 身份验证
    /// </summary>
    /// <returns></returns>
    public static async Task<bool> LogInAsync()
    {
        try
        {
            _client = OneDriveClientExtensions.GetUniversalClient(scopes);
            var session = await _client.AuthenticateAsync();
    
            return session != null;
        }
        catch (OneDriveException ex)
        {
            Debug.WriteLine(ex.Message);
    
            return false;
        }
    }

    OneDriveSDK是十分人性化的,因为我们不需要主动管理Session,只需要一个全局的Client即可。 

    3)上传功能

    /// <summary>
    /// 上传文件到OneDrive
    /// </summary>
    /// <returns></returns>
    public static async Task<bool> UploadFileAsync()
    {
        var file = await StorageFile.GetFileFromPathAsync($"ms-appx:///Assets/Images/{fileName}");
    
        return await UploadFileAsync(file, OneDriveFilePath);
    }
    
    /// <summary>
    /// 上传文件到OneDrive
    /// </summary>
    /// <param name="file"></param>
    /// <param name="path"></param>
    /// <returns></returns>
    private static async Task<bool> UploadFileAsync(StorageFile file, string serverPath)
    {
        if (file != null)
        {
            var stream = await file.OpenStreamForReadAsync();
    
            var item = await _client
                                .Drive
                                .Root
                                .ItemWithPath(serverPath)
                                .Content
                                .Request()
                                .PutAsync<Item>(stream);
    
            return true;
        }
    
        return false;
    }

    4)下载功能

    /// <summary>
    /// 从OneDrive下载文件
    /// </summary>
    /// <returns></returns>
    public static async Task<Stream> DownloadFileAsync()
    {
        return await DownloadFileAsync(OneDriveFilePath);
    }
    
    /// <summary>
    /// 从OneDrive下载文件
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private static async Task<Stream> DownloadFileAsync(string serverPath)
    {
        var item = await _client
                            .Drive
                            .Root
                            .ItemWithPath(serverPath)
                            .Request()
                            .GetAsync();
    
        var stream = await _client
                              .Drive
                              .Items[item.Id]
                              .Content
                              .Request()
                              .GetAsync();
    
        return stream;
    }

    5)方法调用

    注:代码中的UpdateProgressRing方法(更新进度条显示状态)以及ToastService.SendToast方法(弹框提示),各位不必太在意。

    // 备份功能的实现
    if (await OneDriveUtil.LogInAsync())
    {
        UpdateProgressRing(true, "Uploading data...");
    
        var succeed = await OneDriveUtil.UploadFileAsync();
    
        ToastService.SendToast(succeed ? "Succeed (●'◡'●)" : "Fail (⊙︿⊙)");
    }
    // 同步功能的实现
    if (await OneDriveUtil.LogInAsync())
    {
        UpdateProgressRing(true, "Downloading data...");
    
        using (var stream = await OneDriveUtil.DownloadFileAsync())
        {
            await ImportDataAsync(stream);
        }
    }
    /// <summary>
    /// 通过文件流导入数据
    /// </summary>
    /// <param name="stream"></param>
    /// <returns></returns>
    public static async Task ImportDataAsync(Stream stream)
    {
        if (stream != null)
        {
            try
            {
                // 这个地方使用了图片库,一定要记得申请相关权限(见下图)
                var lib = KnownFolders.PicturesLibrary;
                var file = await lib.CreateFileAsync(OneDriveUtil.fileName, CreationCollisionOption.ReplaceExisting);
    
                byte[] buffer = new byte[stream.Length];
                await stream.ReadAsync(buffer, 0, buffer.Length);
    
                var fs = await file.OpenStreamForWriteAsync();
                fs.Write(buffer, 0, buffer.Length);
    
                ToastService.SendToast("Succeed (●'◡'●)");
            }
            catch
            {
                ToastService.SendToast("Fail (⊙︿⊙)");
            }
        }
        else
        {
            ToastService.SendToast("Fail (⊙︿⊙)");
        }
    }

    6)初次运行

    初次运行时,系统会弹框提示用户是否授权(如图)。如果授权成功,则以后一般都不会再弹出提示,除非身份验证过期。

    5.Demo

     https://files.cnblogs.com/files/lary/OneDriveDemo.rar

    6.参考

     Win10开发:OneDrive SDK 的使用 http://blog.csdn.net/zmq570235977/article/details/50520247

  • 相关阅读:
    栈 队列 递归 算法的GO语言实现
    数组与链表算法
    树算法的GO语言实现
    排序算法的GO语言实现
    如何抵抗记忆的衰退
    C程序运行的背后(2)
    C程序运行的背后(1)
    Shell脚本:“syntax error:unexpected end of file”
    电线的粗细与电流的大小怎么算?电流的大小与电器的功率有什么关系? 如何根据电流的大小选择铜质电线的粗细
    Word2019发布文章到博客园
  • 原文地址:https://www.cnblogs.com/lary/p/6752617.html
Copyright © 2011-2022 走看看