博主开发的UWP应用China Daily中,支持将生词本、收藏夹等数据同步到OneDrive,现在我们来看看这个功能具体是如何实现的。
1. 在项目中安装OneDriveSDK
特别注意:请安装Microsoft.OneDriveSDK的1.x.x版本!(2.x.x版本和1.x.x版本差异比较大,前者不兼容后者。博主在这篇博客中以
1.2.0版本的OneDriveSDK
进行讲解,如果你确实希望使用最新版本SDK,本篇博客可能对你的参考价值极其有限)
额外说明:你也可以通过包管理控制台安装OneDriveSDK。安装语法为:PM> Install-Package Microsoft.OneDriveSDK -Version 1.2.0
2. 将当前项目与应用商店关联起来
3. SDK的使用
Microsoft.OneDriveSDK使用OAuth 2.0进行用户授权管理,一旦用户授予相关权限后,我们就可以进行相关操作了(我的China Daily向用户申请了三个OneDrive操作权限:登录、读写、离线使用权)。详细的权限管理信息请参见微软相关文档,而下方的图片则展示了文档中的关键信息供你参考
3.1 调用登录接口获取授权
// 全局的Client
private static IOneDriveClient _client;
// 所请求的权限
private static string[] scopes = new string[] { "onedrive.readwrite", "wl.offline_access", "wl.signin" };
/// <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;
}
}
说明:我创建了一个OneDriveUtil的静态类,并在类里面实现身份验证、上传、下载的方法。所以下述(方法调用部分除外)的字段、方法都使用了static关键字进行限制。(值得一提的是:OneDriveSDK十分的人性化,因为我们不需要主动管理Session,一个全局的Client就足够了)
3.2 上传文件到OneDrive
/// <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;
}
3.3 从OneDrive下载文件
/// <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;
}
3.4 综合调用
// 数据备份功能的实现
if (await OneDriveUtil.LogInAsync())
{
var succeed = await OneDriveUtil.UploadFileAsync();
}
// 同步功能的实现
if (await OneDriveUtil.LogInAsync())
{
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);
// TODO: Notify task succeed
}
catch
{
// TODO: Notify task failed
}
}
else
{
// TODO: Notify task failed
}
}
3.5 初次运行
初次运行,系统会弹框告知用户应用正在申请授权(如下图)。若成功授权,则以后一般不会再弹出提示,除非身份验证过期。
4. Demo
5. 参考
Win10开发:OneDrive SDK 的使用 http://blog.csdn.net/zmq570235977/article/details/50520247