Поделиться через


Файлы и папки в библиотеках музыки, изображений и видео

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

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

Предпосылки

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

    Вы можете узнать, как писать асинхронные приложения в C# или Visual Basic, см. в статье Вызов асинхронных API в C# или Visual Basic. Чтобы узнать, как писать асинхронные приложения в C++, см. раздел Асинхронное программирование в C++.

  • Разрешения доступа к местоположению

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

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

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

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

Замечание

Не забудьте задекларировать соответствующую возможность. Дополнительные сведения см. в статье Объявление возможностей приложения.  

Чтобы получить ссылку на библиотеку музыки, рисунков или видео пользователя, вызовите метод 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.Folder (и в встроенном приложении "Фотографии"), но папка не отображается как дочерний элемент папки "Изображения" в проводнике.

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

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

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

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

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

Рассмотрим состояние хранилища устройства, показанное на следующем рисунке:

изображения на телефоне и 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))метод 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);
            }
        }
    }
}