• Статья
  • Чтение занимает 5 мин

Добавьте существующие папки музыки, изображений или видео в соответствующие библиотеки. Можно также удалить папки из библиотек, получить список папок в библиотеке и найти сохраненные фотографии, музыку и видео.

Библиотека — это виртуальная коллекция папок, которая содержит известную папку по умолчанию и все другие папки, добавленные пользователем в библиотеку с помощью вашего приложения или одного из встроенных приложений. Например, библиотека изображений содержит известную папку изображений по умолчанию. Пользователь может добавлять папки в библиотеку изображений или удалить их из нее с помощью вашего приложения или встроенного приложения «Фотографии».

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

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

    Описание процесса написания асинхронных приложений на C# или Visual Basic см. в статье Вызов асинхронных API в C# и Visual Basic. Сведения о создании асинхронных приложений на C++ см. в статье Асинхронное программирование на языке C++.

  • Права доступа к расположению

    В Visual Studio откройте файл манифеста приложения в Конструкторе манифестов. На странице Возможности выберите библиотеки, которыми управляет приложение.

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

    Дополнительную информацию см. в разделе Разрешения на доступ к файлам.

Получение ссылок на библиотеку

Чтобы получить ссылку на библиотеку музыки, изображений или видео, вызовите метод StorageLibrary.GetLibraryAsync. Предоставьте соответствующее значение из перечисления KnownLibraryId.

  • KnownLibraryId.Music
  • KnownLibraryId.Pictures
  • KnownLibraryId.Videos
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 (и во встроенном приложении «Фотографии»), но папка не отображается как дочерний элемент папки «Изображения» в проводнике.

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

Удаление папки из библиотеки

Чтобы удалить папку из библиотеки, вызовите метод StorageLibrary.RequestRemoveFolderAsync и укажите папку, которую нужно удалить. Можно использовать элемент управления StorageLibrary.Folders и ListView (или подобный ему), чтобы пользователь мог выбрать папку для удаления.

При вызове StorageLibrary.RequestRemoveFolderAsync пользователь видит диалоговое окно подтверждения того, что папка «больше не будет отображаться в «Изображениях», но не будет удалена». Это означает, что папка остается в исходном расположении на диске, удаляется из свойства StorageLibrary.Folders и больше не включается в встроенное приложение «Фотографии».

В следующем примере предполагается, что пользователь выбрал папку для удаления из элемента управления ListView с именем lvPictureFolders.

bool result = await myPictures.RequestRemoveFolderAsync(folder);

Получение уведомлений об изменениях списка папок в библиотеке

Для получения уведомлений об изменениях в списке папок в библиотеке зарегистрируйте обработчик для события StorageLibrary.DefinitionChanged библиотеки.

myPictures.DefinitionChanged += MyPictures_DefinitionChanged;

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

В устройстве предусмотрено пять стандартных расположений для хранения файлов мультимедиа пользователей и приложений. Встроенные приложения хранят в этих расположениях как созданные пользователями, так и загруженные файлы мультимедиа.

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

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

    • Папка Пленка. Содержит фотографии и видео со встроенной камеры.

    • Папка Сохраненные изображения. Содержит изображения, сохраненные пользователем из других приложений.

  • Папка Музыка. Содержит композиции, подкасты и аудиокниги.

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

Пользователи или приложения также могут хранить файлы мультимедиа за пределами папок библиотек на 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 с метаданными фотографии с помощью кода, похожего на приведенный в следующем примере. В этом примере testPhoto представляет объект StorageFile.

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)) методы using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0)) и GetOutputStreamAt открывают поток. Однако только поток, открытый методом GetOutputStreamAt, ликвидируется в результате выполнения оператора using. Другой поток остается открытым и не позволяет сохранить файл.

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