在我的“煥屏”應用中用到了OneDrive同步功能,是以準備寫一下OneDrive SDK的簡單使用。OneDrive 開發者中心:開發中心
使用SDK需要做一些準備工作
一、在開發者中心注冊應用
1、用開發者賬号登陸開發者中心,不過這裡的開發者中心不是平時常去的dev.windows.com,而是這裡 https://account.live.com/developers/applications/index
2、在頁面上點選“建立應用程式”,輸入應用程式名稱并選擇語言。然後“我接受”(怎麼不是我願意

3、在API設定頁面中将“移動或桌面用戶端應用”選擇成“是”。如果你要在原有的應用中使用SDK,更改對應應用的API設定即可
二、項目準備
1、建立一個UWP工程,這裡命名為OneDriveDemo
2、在工程中安裝SDK對應的NuGet包,搜尋“Microsoft.OneDriveSDK”
3、将項目工程與應用程式關聯
右鍵項目名,選擇“應用商店”->“将應用程式與應用商店關聯”
在登陸應用商店之後,在選擇應用程式名稱頁面下面填入新應用名稱,或者在應用清單中選擇對應應用名
以上,我們完成了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
appId可以在注冊應用的時候在應用設定中檢視。我偏向于使用第一種方法,也不需要appId了。
調用oneDriveClient的AuthenticateAsync方法,如果沒問題,第一次就會彈出下面的對話框
之後一般都不會再彈,除非身份驗證過期。
四、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、運作程式,效果圖
源碼下載下傳:https://github.com/hebecherish/OneDriveDemo