天天看点

Win10开发:OneDrive SDK 的使用

在我的“焕屏”应用中用到了OneDrive同步功能,因此准备写一下OneDrive SDK的简单使用。OneDrive 开发者中心:开发中心

使用SDK需要做一些准备工作

一、在开发者中心注册应用

1、用开发者账号登陆开发者中心,不过这里的开发者中心不是平时常去的dev.windows.com,而是这里 https://account.live.com/developers/applications/index 

2、在页面上点击“创建应用程序”,输入应用程序名称并选择语言。然后“我接受”(怎么不是我愿意

Win10开发:OneDrive SDK 的使用

3、在API设置页面中将“移动或桌面客户端应用”选择成“是”。如果你要在原有的应用中使用SDK,更改对应应用的API设置即可

Win10开发:OneDrive SDK 的使用

二、项目准备

1、新建一个UWP工程,这里命名为OneDriveDemo

2、在工程中安装SDK对应的NuGet包,搜索“Microsoft.OneDriveSDK”

Win10开发:OneDrive SDK 的使用

3、将项目工程与应用程序关联

右键项目名,选择“应用商店”->“将应用程序与应用商店关联”

Win10开发:OneDrive SDK 的使用

在登陆应用商店之后,在选择应用程序名称页面下面填入新应用名称,或者在应用列表中选择对应应用名

Win10开发:OneDrive SDK 的使用

以上,我们完成了SDK使用的准备工作。

要操作OneDrive中的应用,就要让用户登录,也就是身份认证。

三、身份认证

在UWP中,有三种方法可以调用用于身份认证(其实大同小异

• GetUniversalClient

var oneDriveClient = OneDriveClientExtensions.GetUniversalClient(scopes);
var accountSession = await oneDriveClient.AuthenticateAsync();
           

• GetClientUsingOnlineIdAuthenticator

var oneDriveClient =await OneDriveClientExtensions.GetAuthenticatedClientUsingOnlineIdAuthenticator(scopes);
var accountSession = await oneDriveClient.AuthenticateAsync();
           

• GetClientUsingWebAuthenticationBroker

var oneDriveClient = OneDriveClientExtensions.GetClientUsingWebAuthenticationBroker(appId,scopes);
await oneDriveClient.AuthenticateAsync();
           

前两种方法接受一个string 数组做为参数scopes,第三者方法多一个string 参数appId。返回一个IOneDriveClient对象

scopes数组的定义是这样:

private readonly string[] scopes = new string[] { "onedrive.readwrite", "wl.offline_access", "wl.signin" };
           

其中具体的选择可以查看这 https://dev.onedrive.com/auth/msa_oauth.htm

Win10开发:OneDrive SDK 的使用

appId可以在注册应用的时候在应用设置中查看。我偏向于使用第一种方法,也不需要appId了。

调用oneDriveClient的AuthenticateAsync方法,如果没问题,第一次就会弹出下面的对话框

Win10开发:OneDrive SDK 的使用

之后一般都不会再弹,除非身份验证过期。

四、SDK主要方法

OneDrive中的每一个项都是Item,因此操作的对象都是Item

1、通过Id获取Item

var item = await oneDriveClient
                     .Items[itemId]
                     .Request()
                     .GetAsync();
           

2、通过路径获取Item

var item = await oneDriveClient
                     .Drive
                     .Root
                     .ItemWithPath(itemPath)
                     .Request()
                     .GetAsync();
           

3、删除Item

await oneDriveClient
          .Drive
          .Items[itemId]
          .Request()
          .DeleteAsync();
           

4、获取Item的子项目列表

var items=await oneDriveClient
                    .Drive
                    .Items[rootItem.Id]
                    .Children
                    .Request()
                    .GetAsync();
 var itemList= items.CurrentPage;
           

5、上传Item

using (stream)
{
    var uploadedItem = await oneDriveClient
                               .Drive                                     
                               .Root
                               .ItemWithPath(itemPath)
                               .Content
                               .Request()
                               .PutAsync<Item>(stream);
}
           

6、下载Item

var stream = await oneDriveClient
                              .Drive
                              .Items[itemId]
                              .Content
                              .Request()
                              .GetAsync();
           

五、Demo

1、XAML界面设计

<Page.Resources>
        <local:ItemTypeToImageConverter x:Key="ItemType2ImageConverter" />
</Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Grid.Row="0">
            <Button Content="登陆" Click="btnLogin_Click" Margin="5"/>
            <Button Content="上传" Click="btnUpload_Click" Margin="5"/>
            <Button Content="下载" Click="btnDownload_Click" Margin="5"/>
            <Button Content="返回" Click="btnBack_Click" Margin="5"/>
            <TextBlock x:Name="txtMsg"/>
        </StackPanel>
        <GridView Grid.Row="1" x:Name="gridView" SelectionChanged="gridView_SelectionChanged">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Image Source="{Binding File,Converter={StaticResource ItemType2ImageConverter}}" Width="150" Height="150"/>
                        <TextBlock Text="{Binding Name}"/>
                    </StackPanel>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
    </Grid>
           

2、XAML中的Convert类

作用:如果是文件显示文件的图片,否则显示文件夹的图片。判断方式是Item的File属性是否为null

public class ItemTypeToImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (value==null)
                return "Assets/folder.png";
            else
                return "Assets/file.png";
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
           

3、登陆并显示所有文件/文件夹

private async void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                oneDriveClient = OneDriveClientExtensions.GetUniversalClient(scopes);
                var accountSession = await oneDriveClient.AuthenticateAsync();

                if (accountSession!=null)
                {
                    var rootItem = await oneDriveClient
                                        .Drive
                                        .Root
                                        .Request()
                                        .GetAsync();

                   var items=await oneDriveClient
                                          .Drive
                                          .Items[rootItem.Id]
                                          .Children
                                          .Request()
                                          .GetAsync();
                    gridView.ItemsSource = items.CurrentPage;
                }
            }
            catch (OneDriveException oe)
            {
                txtMsg.Text="登陆失败";
            }
        }
           

4、选择事件

判断当前选择的是否是文件夹,如果是文件夹则进入,并重新绑定数据源

private async void gridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (gridView.SelectedItem!=null)
            {
                var selectedItem = gridView.SelectedItem as Item;
                if (selectedItem.Folder!=null)
                {
                    var items = await oneDriveClient
                                          .Drive
                                          .Items[selectedItem.Id]
                                          .Children
                                          .Request()
                                          .GetAsync();
                    gridView.ItemsSource = items.CurrentPage;

                    pathStack.Push(selectedItem.ParentReference.Path);
                }
            }
        }
           

这里用到了一个栈用来保存路径。Item的ParentReference属性是其父节点的数据

5、返回事件

如果存储路径的栈非空,说明存在上一级

private async void btnBack_Click(object sender, RoutedEventArgs e)
        {
            if (pathStack.Count >0)
            {
                var parentItem = await oneDriveClient
                   .Drive
                   .Root
                   .ItemWithPath(pathStack.Pop().Substring(12))
                   .Request()
                   .GetAsync();
                var items = await oneDriveClient
                                 .Drive
                                 .Items[parentItem.Id]
                                 .Children
                                 .Request()
                                 .GetAsync();

                gridView.ItemsSource = items.CurrentPage;
            }
        }
           

6、上传事件

private async void btnUpload_Click(object sender, RoutedEventArgs e)
        {
            var picker = new FileOpenPicker();
            picker.ViewMode = PickerViewMode.Thumbnail;
            picker.FileTypeFilter.Add(".txt");

            var file = await picker.PickSingleFileAsync();
             if (file != null)
            {
                Stream stream = await file.OpenStreamForReadAsync();
                var uploadedItem = await oneDriveClient
                                             .Drive
                                             .Root
                                             .ItemWithPath(file.Name)
                                             .Content
                                             .Request()
                                             .PutAsync<Item>(stream);

                txtMsg.Text = "上传成功";
            }
        }
           

7、下载事件

毕竟是个Demo,所以只下载了跟目录下的文件

private async void btnDownload_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var picker = new FolderPicker();
                picker.FileTypeFilter.Add(".txt");
                var folder = await picker.PickSingleFolderAsync();
                
                var rootItem = await oneDriveClient
                     .Drive
                     .Root
                     //.ItemWithPath("焕屏")
                     .Request()
                     .GetAsync();
                var items = await oneDriveClient
                                 .Drive
                                 .Items[rootItem.Id]
                                 .Children
                                 .Request()
                                 .GetAsync();
               var queryItem = items.Where(item => item.File != null);//筛选文件
                foreach (var item in queryItem)
                {
                    var file = await folder.CreateFileAsync(item.Name, CreationCollisionOption.GenerateUniqueName);
                    var stream = await oneDriveClient
                              .Drive
                              .Items[item.Id]
                              .Content
                              .Request()
                              .GetAsync();
                    byte[] buffer = new byte[stream.Length];
                    await stream.ReadAsync(buffer, 0, buffer.Length);  //将流的内容读到缓冲区

                    var fs = await file.OpenStreamForWriteAsync();
                    fs.Write(buffer, 0, buffer.Length);
                }
                txtMsg.Text = "下载成功";
            }
            catch (Exception ex)
            {
                txtMsg.Text = "下载失败";
            }
        }
           

关于上传和下载的代码,之前遇到了个大坑,可以查看这里  http://blog.csdn.net/zmq570235977/article/details/50520185

8、运行程序,效果图

Win10开发:OneDrive SDK 的使用

源码下载:https://github.com/hebecherish/OneDriveDemo

继续阅读