Опубликован: 10.04.2013 | Доступ: свободный | Студентов: 440 / 9 | Длительность: 16:52:00
Специальности: Программист
Лекция 2:

Состояния, параметры, файлы и документы

API средства выбора файлов и его друзья

Теперь, когда мы видели визуальную часть средства выбора файлов, посмотрим, как можно вызвать его из кода приложения с использованием API Windows.Storage.Pickers (http://msdn.microsoft.com/library/windows/apps/br207928.aspx). Все изображения, которые мы только что видели, взяты из примера "Средство выбора файлов" (http://code.msdn.microsoft.com/windowsapps/File-picker-sample-9f294cba), и мы так же используем его как источник кода.

Для начинающих, Сценарий 1 в функции pickSinglePhoto (js/scenario1.js) использует средство выбора для получения одного объекта StorageFile для открытия (чтения и записи):

function pickSinglePhoto() {	
// Удостоверяемся, что приложение не в прикрепленном режиме, или что мы можем перейти в иной режим для запуска
// средства выбора файлов
var currentState = Windows.UI.ViewManagement.ApplicationView.value;	
if (currentState === Windows.UI.ViewManagement.ApplicationViewState.snapped &&	
!Windows.UI.ViewManagement.ApplicationView.tryUnsnap()) {	
// Не выводим дополнительных сообщений,
 если приложение не вышло из прикрепленного режима	
return;	
}	

// Создаем объект средства выбора файлов и настраиваем параметры	
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();	
openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
openPicker.suggestedStartLocation =	
Windows.Storage.Pickers.PickerLocationId.picturesLibrary;	

// Пользователи ожидают увидеть папки, к содержимому которых 
применен фильтр, который зависит от сценария.	
// Например, при выборе папки документов, ограничьте типы файлов документами вашего приложения
openPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);	


// Открываем средство выбора файлов, чтобы позволить пользователю выбрать файл
 openPicker.pickSingleFileAsync().done(function (file) {
if (file) {
// Теперь у приложения есть доступ к выбранному файлу для чтения и записи
} else {
// Средство выбора файлов было закрыто без выбора файла
}
});
}

 

Как вы можете видеть, вызывать средство выбора в прикрепленном режиме не следует. Это, как и попытка вызова панели параметров, приведет к исключению. Вы можете проверить это, как показано здесь, или добавить обработчик ошибки в метод done в конце4Я должен отметить, что пример использует вместо done метод then в последнем асинхронном вызове. Хотя и then работает, там следует использовать done, особенно если вы собираетесь обрабатывать там исключения.. В любом случае, для вызова средства выбора файлов мы создаем экземпляр indows.Storage.Pickers.FileOpenPicker (http://msdn.microsoft.com/library/windows/apps/br207847.aspx), настраиваем его и затем вызываем его метод pickSingleFileAsync. Результат работы pickSingleFileAsync – это аргумент file, передаваемый в обработчик завершения, который может быть либо объектом типа StorageFile, либо содержать null, если пользователь не сделал выбор и закрыл интерфейс средства выбора файла. Именно поэтому всегда нужно проверять результат выбора файлов на null.

Настраивая средство выбора файлов, мы задали его viewMode как thumbnail (из перечисления Windows.Storage.Pickers.PickerViewMode), что привело к тому виду, который показан на рис. 2.7. Другая возможность – это list, что показано на рис. 2.10.

Кроме того, мы установили suggestedStartLocation в значение picturesLibrary, что является значением, взятым из перечисления Windows.Storage.Pickers.PickerLocationId. Другие возможности - documentsLibrary, computerFolder, desktop, downloads, homeGroup, musicLibrary, и videosLibrary, практически все остальные расположения вы можете видеть на рис. 2.8. Обратите внимание на то, что использование этих расположений не требует от вас объявления возможностей в манифесте, так как пользователь, используя средство выбора файлов, дает разрешение на доступ к этим файлам. Если вы посмотрите манифест этого примера, вы увидите, что он не объявляет никаких возможостей.

Другой свойство, которое мы задаем, это fileTypeFilter (объект FileExtensionVector (http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.fileextensionvector.aspx)), который отражает типы файлов, которые нас интересуют (PNG и JPEG). Помимо этого, FileOpenPicker так же имеет свойство commitButtonText, которое задает подпись для основной кнопки в пользовательском интерфейсе (та из них, которая не является кнопкой Отмена (Cancel), и settingsIndentifier, средство для запоминания различных контекстов для средства выбора файлов. Например, приложение может использовать один идентификатор для выбора изображений, где начальное расположение установлено на библиотеку изображений и режим просмотра – на просмотр в виде миниатюр, и другой идентификатор для выбора документов с другим начальным расположением, и, возможно, с режимом просмотра в виде списка.

Этот пример, как вы можете видеть, помимо получения файлов, ничего не делает с ними, но очень легко увидеть, что мы можем сделать с ними. Мы можем, например, просто передать StorageFile в URL.createObjectURL и присвоить результат свойству img.src для вывода изображения. То же самое можно сделать с аудио и видео-файлами, эти возможности показаны в Сценарии 1 примера "Использование больших двоичных объектов для сохранения и загрузки содержимого" (http://code.msdn.microsoft.com/windowsapps/Blob-Sample-0e35889e), о котором я говорил ранее. Этот пример так же показывает чтение содержимого файла посредством FileReader из API HTML, вместе с API WinRT и WinJS, которые мы уже видели. Так же вы можете перекодировать изображение (или другие данные), на которое ссылается StorageFile, в другой формат (мы увидим это в "Многоточечные жесты" ), получить эскиз, как показано в примере "Эскизы файлов и папок" (http://code.msdn.microsoft.com/windowsapps/File-thumbnails-sample-17575959), или использовать методы StorageFile для создания копии файла в другом расположении, переименования файла, и так далее. Но, с точки зрения средства выбора файлов, его работа здесь сделана!

Возвращаясь к примеру о средстве выбора файлов, выбор нескольких файлов, во многом – это то же самое, как показано в функции pickMultipleFiles в js/scenario2.js. Здесь мы используем режим просмотра list и начинаем просмотр с documentLibrary. Опять же, это начальное расположение не требует объявления возможностей в манифесте.

function pickMultipleFiles() {
// Проверяем, не находимся ли мы в прикрепленном режиме, и так далее... (часть кода опущена)

// Создаем объект средства выбора файлов и настраиваем параметры	
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();	
openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.list;
openPicker.suggestedStartLocation =	
Windows.Storage.Pickers.PickerLocationId.documentsLibrary;	
openPicker.fileTypeFilter.replaceAll(["*"]);	

// Открываем средство выбора файлов, чтобы позволить пользователю выбрать файл
openPicker.pickMultipleFilesAsync().done(function (files) {
if (files.size > 0) {
// Теперь у приложения есть доступ к выбранному файлу (файлам) для чтения и записи
} else {
// Средство выбора файлов было закрыто без выбора файла
}
});
}
 

При выборе нескольких файлов, результат pickMultipleFilesAsync – это объект FilePickerSelectedFilesArray (http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.filepickerselectedfilesarray.aspx), доступ к которому осуществляется как к любому другому массиву, с использованием [ ] (хотя у него меньше методов, чем у обычного массива).

Сценарий 3 примера демонстрирует вызов pickSingleFolderAsync, результат этой операции – объект StorageFolder. Здесь вы должны задать fileTypeFilter, что поможет пользователям выбрать подходящее расположение, в котором существуют файлы нужного типа, или то, где они смогут создать новые подобные файлы (js/scenario3.js):

 function pickFolder() {
// Проверяем, не находимся ли мы в прикрепленном режиме, и так далее... (часть кода опущена)


// Создаем объект средства выбора файлов и настраиваем параметры	
var folderPicker = new Windows.Storage.Pickers.FolderPicker;	
folderPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.desktop;
folderPicker.fileTypeFilter.replaceAll([".docx", ".xlsx", ".pptx"]);	

folderPicker.pickSingleFolderAsync().then(function (folder) {
if (folder) {
// Кэшируем папку, таким образом позже мы сможем получить доступ к ее содержимому
Windows.Storage.AccessCache.StorageApplicationPermissions.futureAccessList
.addOrReplace("PickedFolderToken", folder);
} else {
// Средство выбора файлов было закрыто без выбора объекта
}
});
}

В этом примере мы так же видим, как сохранить выбранный объект StorageFolder в Windows.Storage.AccessCashe (http://msdn.microsoft.com/library/windows/apps/windows.storage.accesscache.aspx) для последующего использования. Опять же, выбирая эту папку, пользователь дает приложению программный доступ к ее содержимого, но только на время текущего сеанса работы. Для того, чтобы сохранить полученные права, приложение должно записать элемент хранения в futureAccessList, в кэш, откуда эти данные могут быть извлечены позже, с использованием методов futureAccessList.getFolderAsync, getItemAsync, или getFileAsync. Как и ранее, обратитесь к Сценарию 6 примера "Доступ к файлу" (http://code.msdn.microsoft.com/windowsapps/File-access-sample-d723e597) для того, чтобы больше узнать об этой возможности, и обратите внимание на то, что API AccessCache так же можно применять для недавно использованных элементов. Ключевая вещь, которую нужно здесь запомнить, заключается в том, что для любого расположения за пределами пакета приложения, данных приложения, или библиотек, доступ к которым вы объявили в манифесте, вы должны использовать AccessCashe для того, чтобы подобный доступ был у вас в будущем. Обычное сохранение пути к расположению и попытка открыть файлы из него позже не дадут результата.

Последний пример использования средства выбора файлов, в Сценарии 4 примера, создается объект FileSavePicker (http://msdn.microsoft.com/library/windows/apps/br207871.aspx) и вызывается метод pickSaveAsync, что приводит к появлению интерфейса, показанного на рис. 2.12:

function saveFile() {
// Проверяем, не находимся ли мы в прикрепленном режиме, и так далее... (часть кода опущена)

// Создаем объект средства выбора файлов и настраиваем параметры	
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
savePicker.suggestedStartLocation =	
Windows.Storage.Pickers.PickerLocationId.documentsLibrary;
// Выпадающий список типов файлов, применимый при сохранении	
savePicker.fileTypeChoices.insert("Plain Text", [".txt"]);	
savePicker.pickSaveFileAsync().done(function (file) {	
if (file) {	
// Предотвращает обновление удаленной версии файла до тех пор, пока мы не завершим
// изменения и не вызовем CompleteUpdatesAsync.	
Windows.Storage.CachedFileManager.deferUpdates(file);	


// записываем в файл
Windows.Storage.FileIO.writeTextAsync(file, file.name).done(function () {
// Дадим Windows знать, что мы завершили изменение файла и другие приложения
// могут обновлять удаленную версию файла.
// Завершение обновлений может потребовать у Windows запросить у пользователя ввод данных. 
Windows.Storage.CachedFileManager.completeUpdatesAsync(file)
.done(function (updateStatus) {
if (updateStatus === Windows.Storage.Provider.FileUpdateStatus.complete) {
} else {
// ...
}
}
});
});
} else {
// Интерфейс был закрыт
}
});
}
 

У объекта FileSaverPicker есть множество тех же свойств, что и у FileOpenPicker, но fileTypeFilter заменен на fileTypeChoices (для заполнения выпадающего списка), так же имеются свойства suggestedFileName (строка), suggestedSaveFile (объект StorageFile), и defaultFileExtension (строка). На что интересно взглянуть в вышеприведенном коде, так это на взаимодействие с Windows.Storage.CachedFileManager (http://msdn.microsoft.com/library/windows/apps/windows.storage.cachedfilemanager.aspx). Этот объект помогает поставщику средства выбора файлов узнать, следует ли ему синхронизировать локальные файлы и файлы, хранящиеся на удаленном сервисе, что необходимо, когда пользователь файла сохраняет новое содержимое, как мы видим здесь. Со стороны потребителя, то, что мы здесь видим – это обычный шаблон для работы с файлами, полученными от средства выбора файлов (или из кэша доступа, если эти данные были сохранены в предыдущих сеансах работы): нам просто нужно дать знать объекту CashedFileManager, что мы осуществляем запись в файл, и сообщить ему, когда сделаем это. Конечно, этого делать не нужно, когда вы работаете с файлами, о которых вы знаете, что они локальные, как с теми, которые находятся в папках, расположенных в AppData. Больше об этом механизме мы узнаем в лекции 1 курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой", посмотрим на него со стороны поставщика.

Медиабиблиотеки

Теперь, когда мы познакомились с возможностями средства выбора файлов, мы можем направить внимание на библиотеки. Но прежде чем мы начнем проверять возможности, заявленные в манифесте, остановимся на мгновение для того, чтобы спросить себя: нужны ли эти возможности на самом деле. Средство выбора файлов предоставляет весьма широкий доступ ко всем библиотекам без необходимости объявления каких-либо возможностей. С помощью средства выбора файлов, мы можете позволить пользователю выбрать один или несколько файлов для открытия, управления и сохранения, а пользователь может предоставить вам доступ к папке. И пользователь может указать новое имя файла для сохранения пользовательских данных.

Вам нужен доступ к определенной библиотеке, если вы собираетесь работать с ней вне средства выбора файлов. Например, если вы хотите перебрать содержимое папок Изображения или Музыка для того, чтобы отобразить список файлов в элементе управления ListView или FlipView, как мы делали в лекции курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", вам нужно объявлять возможности.

Чтобы быть более конкретным, без использования средства выбора файлов, это – единственный способ получить программный доступ к медиабиблиотекам: получения объекта StorageFolder из объекта Windows.Storage.KnownFolders (http://msdn.microsoft.com/library/windows/apps/windows.storage.knownfolders.aspx). В случае с медиаданными, применимые возможности здесь – picturesLibrary, musicLibrary и videoLibrary. Без объявления соответствующих возможностей, попытка получить одно из этих значения приведет к исключению отказа в доступе.

Если вы не собираетесь пользоваться KnownFolders, это означает, что вам не нужно объявлять возможности! Помните, что объявленные возможности перечислены на странице приложения в Магазине Windows и могут вызвать у пользователя размышления о том, стоит ли устанавливать ваше приложение, поэтому, чем меньше возможностей будет объявлено – тем лучше.

Тем не менее, если вы решите, что вам нужен прямой доступ к медиа-библиотекам, работа с ними включает в себя объекты StorageFolder и StorageFile так же, как при работе с любым другим расположением. Единственная разница, однако, это то, что вы можете работать с метаданными, которые часто существуют вместе с медиафайлами, подробнее об этом мы поговорим в "Многоточечные жесты"

Документы и съемные носители

Как и в случае с доступом к папкам с медиаданными, программный доступ к папке с документами пользователя, так же, как и к съемным носителям, контролируется через объявление возможностей. Важно понимать и то, что обе эти возможности так же требуют, чтобы вы объявили сопоставление типов файлов, что означает, что вы не можете просто просмотреть содержимое папки напрямую, или записать в нее любой файл, какой захотите. Иными словами, получать непосредственный доступ к этим папкам с помощью Windows.Storage.KnownFolders.documentsLibrary и removableDevices, где и то и другое является объектом StorageFolder – просто для работы с ограниченным набором типов файлов, полезно лишь при реализации некоторых сценариев. Для библиотеки документов, на самом деле, документация говорит о том, что "единственное приемлемое использование [возможности] – это поддержка открытия содержимого, внедренного в другие документы". Магазин Windows так же требует оправданного использования объявления возможностей и так же требует, чтобы у вас была корпоративная учетная запись в Магазине Windows, а не только учетная запись индивидуального разработчика.

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

Например, в примере "Съемные носители информации" (http://code.msdn.microsoft.com/windowsapps/Removable-Storage-52cc49f0), для демонстрации доступа к съемным носителям информации, объявляются сопоставления с .gif, .jpg и .png-файлами. В результате, приложение отображается в списке Открыть с помощью… (Open With) в контекстном меню, в Проводнике Windows на Рабочем столе, и в средстве выбора программ по умолчанию:


То же самое справедливо и для документов (снова посмотрите пример Доступ к файлам" ( http://code.msdn.microsoft.com/windowsapps/File-access-sample-d723e597)), таким образом, если ваше приложение не позиционируется как приложение для работы с подобными файлами, вам, возможно, не нужны эти возможности.

На самом деле, объявление сопоставления типов файлов, это разновидность контрактов, мы рассмотрим это подробно в лекции 1 курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой".

Вадик Елетин
Вадик Елетин
Россия, г. Санкт-Петербург
Николай Жигульский
Николай Жигульский
Россия, Тверь, Тверской государственный технический университет