Файлы и папки в библиотеках музыки, изображений и видеоFiles and folders in the Music, Pictures, and Videos libraries

Добавьте существующие папки музыки, изображений или видео в соответствующие библиотеки.Add existing folders of music, pictures, or videos to the corresponding libraries. Можно также удалить папки из библиотек, получить список папок в библиотеке и найти сохраненные фотографии, музыку и видео.You can also remove folders from libraries, get the list of folders in a library, and discover stored photos, music, and videos.

Библиотека — это виртуальная коллекция папок, которая содержит известную папку по умолчанию и все другие папки, добавленные пользователем в библиотеку с помощью вашего приложения или одного из встроенных приложений.A library is a virtual collection of folders, which includes a known folder by default plus any other folders the user has added to the library by using your app or one of the built-in apps. Например, библиотека изображений содержит известную папку изображений по умолчанию.For example, the Pictures library includes the Pictures known folder by default. Пользователь может добавлять папки в библиотеку изображений или удалить их из нее с помощью вашего приложения или встроенного приложения "Фотографии".The user can add folders to, or remove them from, the Pictures library by using your app or the built-in Photos app.

Необходимые компонентыPrerequisites

  • Общее представление об асинхронном программировании для приложений универсальной платформы Windows (UWP) .Understand async programming for Universal Windows Platform (UWP) apps

    Описание процесса написания асинхронных приложений на C# или Visual Basic см. в статье Вызов асинхронных API в C# и Visual Basic.You can learn how to write asynchronous apps in C# or Visual Basic, see Call asynchronous APIs in C# or Visual Basic. Сведения о создании асинхронных приложений на C++ см. в статье Асинхронное программирование на языке C++.To learn how to write asynchronous apps in C++, see Asynchronous programming in C++.

  • Права доступа к расположениюAccess permissions to the location

    В Visual Studio откройте файл манифеста приложения в Конструкторе манифестов.In Visual Studio, open the app manifest file in Manifest Designer. На странице Возможности выберите библиотеки, которыми управляет приложение.On the Capabilities page, select the libraries that your app manages.

    • Библиотека музыкиMusic Library
    • Библиотека изображенийPictures Library
    • Библиотека видеоVideos Library

    Дополнительную информацию см. в разделе Разрешения на доступ к файлам.To learn more, see File access permissions.

Получение ссылок на библиотекуGet a reference to a library

Примечание

Обязательно объявите соответствующую возможность.Remember to declare the appropriate capability. Дополнительные сведения см. в статье Объявление возможностей приложения.See App capability declarations for more information.  

Чтобы получить ссылку на библиотеку музыки, изображений или видео, вызовите метод StorageLibrary.GetLibraryAsync.To get a reference to the user's Music, Pictures, or Video library, call the StorageLibrary.GetLibraryAsync method. Предоставьте соответствующее значение из перечисления KnownLibraryId.Provide the corresponding value from the KnownLibraryId enumeration.

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

Получение списка папок в библиотекеGet the list of folders in a library

Чтобы получить список папок, получите значение свойства StorageLibrary.Folders.To get the list of folders in a library, get the value of the StorageLibrary.Folders property.

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

Получение папки в библиотеке, в котором новые файлы сохраняются по умолчаниюGet the folder in a library where new files are saved by default

Чтобы получить папку в библиотеке, в которую по умолчанию сохраняются новые файлы, получите значение свойства StorageLibrary.SaveFolder.To get the folder in a library where new files are saved by default, get the value of the StorageLibrary.SaveFolder property.

Windows.Storage.StorageFolder savePicturesFolder = myPictures.SaveFolder;

Добавление существующей папки в библиотекуAdd an existing folder to a library

Чтобы добавить папку в библиотеку, вызовите StorageLibrary.RequestAddFolderAsync.To add a folder to a library, you call the StorageLibrary.RequestAddFolderAsync. Рассмотрим в качестве примера библиотеку изображений. Вызов этого метода отображает для пользователя средство выбора папок с кнопкой Добавить эту папку в библиотеку изображений.Taking the Pictures Library as an example, calling this method causes a folder picker to be shown to the user with an Add this folder to Pictures button. Если пользователь выбирает папку, то она остается в исходном расположении на диске и становится элементом в свойстве StorageLibrary.Folders (и во встроенном приложении «Фотографии»), но папка не отображается как дочерний элемент папки «Изображения» в проводнике.If the user picks a folder then the folder remains in its original location on disk and it becomes an item in the StorageLibrary.Folders property (and in the built-in Photos app), but the folder does not appear as a child of the Pictures folder in File Explorer.

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

Удаление папки из библиотекиRemove a folder from a library

Чтобы удалить папку из библиотеки, вызовите метод StorageLibrary.RequestRemoveFolderAsync и укажите папку, которую нужно удалить.To remove a folder from a library, call the StorageLibrary.RequestRemoveFolderAsync method and specify the folder to be removed. Можно использовать элемент управления StorageLibrary.Folders и ListView (или подобный ему), чтобы пользователь мог выбрать папку для удаления.You could use StorageLibrary.Folders and a ListView control (or similar) for the user to select a folder to remove.

При вызове StorageLibrary.RequestRemoveFolderAsync пользователь увидит диалоговое окно подтверждения, указывающее, что эта папка «больше не будет отображаться в библиотеке изображений, но не будет удалена».When you call StorageLibrary.RequestRemoveFolderAsync, the user sees a confirmation dialog saying that the folder "won't appear in Pictures anymore, but won't be deleted." Это означает, что папка остается в исходном расположении на диске, удаляется из свойства StorageLibrary.Folders и больше не будет включена во встроенное приложение «Фотографии».What this means is that the folder remains in its original location on disk, is removed from the StorageLibrary.Folders property, and will no longer included in the built-in Photos app.

В следующем примере предполагается, что пользователь выбрал папку для удаления из элемента управления ListView с именем lvPictureFolders.The following example assumes that the user has selected the folder to remove from a ListView control named lvPictureFolders.

bool result = await myPictures.RequestRemoveFolderAsync(folder);

Получение уведомлений об изменениях списка папок в библиотекеGet notified of changes to the list of folders in a library

Для получения уведомлений об изменениях в списке папок в библиотеке зарегистрируйте обработчик для события StorageLibrary.DefinitionChanged библиотеки.To get notified about changes to the list of folders in a library, register a handler for the StorageLibrary.DefinitionChanged event of the library.

myPictures.DefinitionChanged += MyPictures_DefinitionChanged;

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

Папки библиотеки мультимедиаMedia library folders

В устройстве предусмотрено пять стандартных расположений для хранения файлов мультимедиа пользователей и приложений.A device provides five predefined locations for users and apps to store media files. Встроенные приложения хранят в этих расположениях как созданные пользователями, так и загруженные файлы мультимедиа.Built-in apps store both user-created media and downloaded media in these locations.

Используются следующие расположения.The locations are:

  • Папка ИзображенияPictures folder. Содержит изображения.Contains pictures.

    • Папка ПленкаCamera Roll folder. Содержит фотографии и видео со встроенной камеры.Contains photos and video from the built-in camera.

    • Папка Сохраненные изображения.Saved Pictures folder. Содержит изображения, сохраненные пользователем из других приложений.Contains pictures that the user has saved from other apps.

  • Папка Музыка.Music folder. Содержит композиции, подкасты и аудиокниги.Contains songs, podcasts, and audio books.

  • Папка Видео.Video folder. Содержит видео.Contains videos.

Пользователи или приложения также могут хранить файлы мультимедиа за пределами папок библиотек на SD-карте.Users or apps may also store media files outside the media library folders on the SD card. Чтобы наверняка найти файл мультимедиа на SD-карте, просканируйте содержимое SD-карты или попросите пользователя выбрать файл с помощью средства выбора файлов.To find a media file reliably on the SD card, scan the contents of the SD card, or ask the user to locate the file by using a file picker. Дополнительные сведения см. в разделе Доступ к SD-карте.For more info, see Access the SD card.

Запрос в библиотеки мультимедиаQuerying the media libraries

Чтобы получить коллекцию файлов, укажите библиотеку и нужный тип файлов.To get a collection of files, specify the library and the type of files that you want.

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
    }
}

Результаты запроса включают внутренние хранилища и съемные носителиQuery results include both internal and removable storage

Пользователи могут выбрать хранение файлов на дополнительной SD-карте по умолчанию.Users can choose to store files by default on the optional SD card. Приложения же могут запретить хранение файлов на SD-карте.Apps, however, can opt out of allowing files to be stored on the SD card. В результате библиотеки мультимедиа могут храниться и во внутреннем хранилище устройства, и на SD-карте.As a result, the media libraries can be split across the device's internal storage and the SD card.

Для обработки этой возможности не нужно писать дополнительный код.You don't have to write additional code to handle this possibility. Методы в пространстве имен Windows.Storage, запрашивающие известные папки, прозрачно сочетают результаты запросов из обоих расположений.The methods in the Windows.Storage namespace that query known folders transparently combine the query results from both locations. Чтобы получить эти комбинированные результаты, нет необходимости указывать возможность removableStorage в файле манифеста приложения.You don't have to specify the removableStorage capability in the app manifest file to get these combined results, either.

Рассмотрите состояние хранилища устройства, показанное на следующем изображении.Consider the state of the device's storage shown in the following image:

Изображения телефона и SD-карты

Если вы запросите содержимое библиотеки изображений, вызвав await KnownFolders.PicturesLibrary.GetFilesAsync(), результаты будут включать как internalPic.jpg, так и SDPic.jpg.If you query the contents of the Pictures Library by calling await KnownFolders.PicturesLibrary.GetFilesAsync(), the results include both internalPic.jpg and SDPic.jpg.

Работа с фотографиямиWorking with photos

На устройствах, на которых камера сохраняет каждое изображение и в низком, и в высоком разрешении, глубокий запрос вернет только изображения с низким разрешением.On devices where the camera saves both a low-resolution image and a high-resolution image of every picture, the deep queries return only the low-resolution image.

Папки «Пленка» и «Сохраненные изображения» не поддерживают глубокие запросы.The Camera Roll and the Saved Pictures folder do not support the deep queries.

Открытие фотографии в приложении, с помощью которого она снятаOpening a photo in the app that captured it

Если вы хотите предоставить пользователю возможность открыть фотографию позже в том приложении, с помощью которого она снята, вы можете сохранить CreatorAppId с метаданными фотографии с помощью кода, похожего на приведенный в следующем примере.If you want to let the user open a photo again later in the app that captured it, you can save the CreatorAppId with the photo's metadata by using code similar to the following example. В этом примере testPhoto представляет объект StorageFile.In this example, testPhoto is a StorageFile.

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

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

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

Использование потоковых методов для добавления файла в библиотеку мультимедиаUsing stream methods to add a file to a media library

Когда вы получаете доступ к библиотеке мультимедиа с помощью известной папки, такой как KnownFolders.PictureLibrary, и используете потоковые методы для добавления в библиотеку файла, вам обязательно следует закрыть все потоки, которые открыл ваш код.When you access a media library by using a known folder such as KnownFolders.PictureLibrary, and you use stream methods to add a file to the media library, you have to make sure to close all the streams that your code opens. В противном случае эти методы не смогут добавить файл в библиотеку мультимедиа ожидаемым образом, так как минимум один поток будет по-прежнему обрабатывать файл.Otherwise these methods fail to add the file to the media library as expected because at least one stream still has a handle to the file.

Например, при выполнении следующего кода файл не добавляется в библиотеку мультимедиа.For example, when you run the following code, the file is not added to the media library. В строке кода using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0)) методы OpenAsync и GetOutputStreamAt открывают поток.In the line of code, using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0)), both the OpenAsync method and the GetOutputStreamAt method open a stream. Однако только поток, открытый методом GetOutputStreamAt, ликвидируется в результате выполнения оператора using.However only the stream opened by the GetOutputStreamAt method is disposed as a result of the using statement. Другой поток остается открытым и не позволяет сохранить файл.The other stream remains open and prevents saving the file.

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);
    }
}

Чтобы успешно использовать потоковые методы для добавления файлов в библиотеку мультимедиа, обязательно закрывайте все потоки, открытые кодом, как в следующем примере.To use stream methods successfully to add a file to the media library, make sure to close all the streams that your code opens, as shown in the following example.

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);
            }
        }
    }
}