共用方式為


音樂、圖片和影片媒體櫃中的檔案和資料夾

將現有的音樂、圖片或影片資料夾新增至對應的文件庫。 您也可以從文檔庫移除資料夾、取得文件庫中的資料夾清單,以及探索儲存的相片、音樂和影片。

資料庫是虛擬的資料夾集合,預設包含一個已知的資料夾,以及使用者透過您的應用程式或內建應用程式加入的其他資料夾。 例如,圖片庫預設會包含 [圖片] 已知資料夾。 使用者可以使用您的應用程式或內建的 Photos 應用程式,將資料夾新增至圖片庫,或將其從中移除。

先決條件

  • 瞭解通用 Windows 平臺 (UWP) app 的異步程式設計

    您可以瞭解如何在 C# 或 Visual Basic 撰寫異步應用程式,請參閱在 C# 或 Visual Basic 中呼叫異步 API 。 若要瞭解如何在 C++ 中撰寫異步應用程式,請參閱 C++中的 異步程序設計。

  • 對於位置的訪問權限

    在 Visual Studio 中,開啟指令清單設計工具中的應用程式指令清單檔案。 在 [功能] 頁面上,選取您的應用程式所管理的程式庫。

    • 音樂庫
    • 圖片庫
    • 影片庫

    若要深入瞭解,請參閱 檔案存取權限

取得程式庫的參考

備註

請記得宣告適當的功能。 如需詳細資訊,請參閱應用程式功能宣告 \(部分機器翻譯\)。  

若要取得使用者的 Music、Pictures 或 Video 文檔庫參考,請呼叫 StorageLibrary.GetLibraryAsync 方法。 從 KnownLibraryId 枚舉中取得相應的值。

var myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);

取得文件庫中的資料夾清單

若要取得文檔庫中的資料夾清單,請取得 StorageLibrary.Folders 屬性的值。

using Windows.Foundation.Collections;
IObservableVector<Windows.Storage.StorageFolder> myPictureFolders = myPictures.Folders;

取得預設儲存新檔案之文件庫中的資料夾

若要取得函式庫中預設儲存新檔案的資料夾,請取得 StorageLibrary.SaveFolder 屬性的值。

Windows.Storage.StorageFolder savePicturesFolder = myPictures.SaveFolder;

將現有的資料夾新增至文件庫

若要將資料夾新增至連結庫,您可以呼叫 StorageLibrary.RequestAddFolderAsync。 以圖片庫為例,使用這個方法會讓使用者看到資料夾選取器,其中包括一個將此資料夾新增至圖片庫 的按鈕。 如果使用者挑選資料夾,則資料夾會保留在磁碟的原始位置,而且它成為 StorageLibrary.Folders 屬性中的專案(以及內建的 Photos 應用程式中),但資料夾不會顯示為檔案總管中 [圖片] 資料夾的子系。

Windows.Storage.StorageFolder newFolder = await myPictures.RequestAddFolderAsync();

從文件庫移除資料夾

若要從連結庫移除資料夾,請呼叫 StorageLibrary.RequestRemoveFolderAsync 方法,並指定要移除的資料夾。 您可以使用 StorageLibrary.FoldersListView 控件 ,讓用戶選取要移除的資料夾。

當您呼叫 StorageLibrary.RequestRemoveFolderAsync 時,使用者會看到確認對話方塊,指出資料夾「不會再出現在圖片中,也不會刪除」。這表示資料夾會保留在磁碟的原始位置、從 StorageLibrary.Folders 屬性中移除,而且不再包含在內建的 Photos 應用程式中。

下列範例假設用戶已選取要從名為 lvPictureFolders的 ListView 控件中移除的資料夾。

bool result = await myPictures.RequestRemoveFolderAsync(folder);

您將收到圖書館中資料夾列表變更的通知

若要收到連結庫中資料夾清單變更的通知,請註冊連結庫 StorageLibrary.DefinitionChanged 事件的處理程式。

myPictures.DefinitionChanged += MyPictures_DefinitionChanged;

void HandleDefinitionChanged(Windows.Storage.StorageLibrary sender, object args)
{
    // ...
}

媒體資料庫檔案夾

裝置提供五個預先定義的位置,供使用者和應用程式儲存媒體檔案。 內建應用程式會將使用者建立的媒體和下載的媒體儲存在這些位置。

位置如下:

  • 圖片 資料夾。 包含圖片。

    • Camera Roll 資料夾。 包含來自內建相機的相片和視訊。

    • 已儲存的圖片 資料夾。 包含使用者從其他應用程式儲存的圖片。

  • Music 資料夾。 包含歌曲、播客和有聲書。

  • Video 資料夾。 包含影片。

使用者或應用程式也可以將媒體檔案儲存在 SD 記憶卡上的媒體櫃資料夾之外。 若要可靠地在 SD 記憶卡上尋找媒體檔案,請掃描 SD 記憶卡的內容,或使用檔案選擇器要求使用者找出檔案。 如需詳細資訊,請參閱 存取 SD 記憶卡

查詢媒體資料庫

若要取得檔案的集合,請指定連結庫和您想要的文件類型。

using Windows.Storage;
using Windows.Storage.Search;

private async void getSongs()
{
    QueryOptions queryOption = new QueryOptions
        (CommonFileQuery.OrderByTitle, new string[] { ".mp3", ".mp4", ".wma" });

    queryOption.FolderDepth = FolderDepth.Deep;

    Queue<IStorageFolder> folders = new Queue<IStorageFolder>();

    var files = await KnownFolders.MusicLibrary.CreateFileQueryWithOptions
      (queryOption).GetFilesAsync();

    foreach (var file in files)
    {
        // do something with the music files
    }
}

查詢結果包括內部和卸除式記憶體

根據預設,用戶可以選擇將檔案儲存在選擇性 SD 記憶卡上。 不過,應用程式可以選擇不允許將檔案儲存在 SD 記憶卡上。 因此,媒體櫃可以分割至裝置的內部記憶體和 SD 記憶卡。

您不需要撰寫其他程式代碼來處理這種可能性。 Windows.Storage 命名空間中查詢已知資料夾的方法會透明地結合這兩個位置的查詢結果。 您不需要在應用程式指令清單檔案中指定 removableStorage 功能,即可取得這些合併的結果。

請考慮下圖所示裝置記憶體的狀態:

手機和 sd 記憶卡上的影像

如果您藉由呼叫 await KnownFolders.PicturesLibrary.GetFilesAsync()來查詢圖片庫的內容,結果會同時包含 internalPic.jpg 和 SDPic.jpg。

處理相片

在相機同時儲存低解析度影像和每張圖片高解析度影像的裝置上,深度查詢只會傳回低解析度影像。

相片膠卷和已儲存的圖片資料夾不支援深入查詢。

在擷取相片的應用程式中開啟相片

如果您想要讓使用者稍後在擷取相片的應用程式中再次開啟相片,您可以使用類似下列範例的程式代碼來儲存 CreatorAppId 與相片的元數據。 在這個範例中,testPhotoStorageFile

IDictionary<string, object> propertiesToSave = new Dictionary<string, object>();

propertiesToSave.Add("System.CreatorOpenWithUIOptions", 1);
propertiesToSave.Add("System.CreatorAppId", appId);

testPhoto.Properties.SavePropertiesAsync(propertiesToSave).AsyncWait();   

使用數據流方法將檔案新增至媒體櫃

當您使用 KnownFolders.PictureLibrary 等已知資料夾存取媒體媒體櫃時,並使用串流方法將檔案新增至媒體櫃時,您必須確定關閉程式代碼開啟的所有數據流。 否則,因為至少有一個資料流仍持有檔案的控制權,這些方法無法如預期般將檔案新增至媒體庫。

例如,當您執行下列程式代碼時,檔案不會新增至媒體庫。 在程式代碼行中,using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0))OpenAsync 方法和 GetOutputStreamAt 方法都會開啟數據流。 不過,使用 語句的結果是,只有由 GetOutputStreamAt 方法所開啟的資料流會被處置。 另一個數據流保持開啟狀態,並防止儲存文件。

StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(@"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");
using (var sourceStream = (await sourceFile.OpenReadAsync()).GetInputStreamAt(0))
{
    using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0))
    {
        await RandomAccessStream.CopyAndCloseAsync(sourceStream, destinationStream);
    }
}

若要成功使用數據流方法將檔案新增至媒體庫,請務必關閉程式代碼開啟的所有數據流,如下列範例所示。

StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(@"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");

using (var sourceStream = await sourceFile.OpenReadAsync())
{
    using (var sourceInputStream = sourceStream.GetInputStreamAt(0))
    {
        using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))
            {
                await RandomAccessStream.CopyAndCloseAsync(sourceInputStream, destinationStream);
            }
        }
    }
}