天天看點

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

繼續閱讀