Опубликован: 15.05.2013 | Доступ: свободный | Студентов: 265 / 9 | Длительность: 24:25:00
Специальности: Системный архитектор
Лекция 3:

Объявления в манифесте

< Лекция 2 || Лекция 3: 12345 || Лекция 4 >

Поставщик открытия файлов: локальный файл

Поставщик открытия файлов работает посредством объекта FileOpenPickerUI, поддерживаемого при виде активации fileOpenPicker. Проще говоря, какой бы пользовательский интерфейс не предоставлял бы провайдер для выбора некоторых файлов или данных, он будет связан с различными методами, свойствами и событиями этого объекта.

Во-первых, интерфейс будет использовать свойство allowedFileTypes для фильтрации того, что он предоставит для выбора – очевидно, поставщику не следует отображать элементы, которые не соответствуют тому, что запросили у средства выбора файлов! Далее, интерфейс может использовать свойство selectionMode (значение FileSelectionMode (http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.provider.fileselectionmode.aspx )) для определения того, запущено ли средство выбора файла для выбора одного или нескольких файлов.

Когда пользователь выбирает элемент в интерфейсе, поставщик вызывает метод addFile с объектом StorageFile, который соответствует этому элементу. Очевидно, поставщик должен как-то создать этот объект StorageFile. В средстве для открытия файлов примера, в Сценарии 1, это выполняется с помощью StorageFolder.getFileAsync (где StorageFolder представлено расположением пакета).

Windows.ApplicationModel.Package.current.installedLocation
.getFileAsync("images\\squareTile-sdk.png").then(function (fileToAdd) {
addFileToBasket(localFileId, fileToAdd);
}
      

Здесь addFileToBasket просто вызывает FileOpenPickerUI.addFile и отображает сообщения для результата. Этот результат является значением из Windows.Storage.Pickers.Provider.AddFileResult: added (успешно добавлено), alreadyAdded (избыточная операция, так как файл уже добавлен), notAllowed (добавление запрещено, по причине несоответствующего типа файла), и unavailable (приложение не видимо). Это, на самом деле, лишь помогает вам сообщить пользователю о результате в вашем интерфейсе. Обратите так же внимание на то, что метод canAddFile может быть полезен для включения или выключения команд добавления в вашем интерфейсе, что позволяет предотвратить некоторые из этих ошибок, просто не позволяя происходить неверным действиям.

Приложение-поставщик так же должно реагировать на запросы, касающиеся удаления ранее добавленных элементов, в случаях, когда пользователь удаляет ранее выбранные файлы из "корзины" в интерфейсе средства выбора файлов, допускающего выбор нескольких файлов. Для того, чтобы это сделать прослушивайте событие fileRemoved объекта FileOpenPickerUI, которое, в качестве аргумента, предоставляет ID файла. Вы передаёте этот ID в containsFile, за которым следует removeFile, как это сделано в примере (js/fileOpenPickerScenario1.js):

// Подключает события в коде инициализации страницы
fileOpenPickerUI.addEventListener("fileremoved", onFileRemovedFromBasket, false);

function removeFileFromBasket(fileId) {
if (fileOpenPickerUI.containsFile(fileId)) {
fileOpenPickerUI.removeFile(fileId);
}
}
      

Если вам нужно знать, когда интерфейс средства выбора файла закрывает вашу страницу (как происходит, когда пользователь нажимает на кнопку Open (Открыть) или Cancel (отменить), как показано на рис. 3.1), прослушивайте событие closing. Это даёт вам возможность закрыть любые сеансы, которые были открыты при взаимодействии с онлайновыми сервисами и выполнить любые необходимые задачи по очистке. В eventArgs вы можете найти свойство isCanceled, которое показывает, был ли отменен сеанс работы со средством выбора файла (значение true), или интерфейс был закрыт кнопкой Open (Открыть) (false). Объект eventArgs.closingOperation так же содержит метод getDeferral и свойство deadline, что позволяет вам производить, так же, асинхронные операции, это похоже на то, что показано в Главе 3 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript" для события suspending.

Последнее замечание касается того, что средство выбора файлов должно учитывать FileOpenPickerUI.settingsIdentifier для перезапуска приложения-поставщика и приведения его в предыдущее состояние (то есть, к состоянию предыдущего сеанса работы с файлами). Если вы помните о другой стороне этого процесса, то приложение, которое использует средство выбора файла может использовать settingsIdentifier для различения внутри себя различных вариантов использования, возможно – для различения определенных типов файла или особенностей контекстов. Идентификатор так же может отличаться у различных приложений, которые запускают средство выбора файла. Таким образом, учитывая это свойство, приложение-поставщик может управлять контекстом, зависящим от каждого конкретного случая его активации (обычно, используя settingsIdentifier в именах файлов в пакете приложения и в именах контейнеров параметров), именно так работают встроенные средства выбора файлов для работы с файловой системой.

Так же приложение-поставщик может быть приостановлено, отображая свой пользовательский интерфейс, и, возможно, что оно может быть остановлено, если вызывающее приложение будет закрыто. Однако, если вы управляете состоянием средства выбора файлов на основе использования значений settingIdentifier, вам не нужно сохранять или управлять другими состояниями сеанса, которые касаются функциональности средства выбора файлов.

Поставщик открытия файлов: URI

В основном, Сценарий 2 варианта средства открытия файлов в примере поставщика очень похож на то, что мы видели в предыдущем разделе. Единственное различие заключается в том, как создать StorageFile из источника, который не является файлом, как, например, из изображения, которое получено по удалённому URI. В этой ситуации нам нужно получить поток данных для удалённого URI и конвертировать этот поток в объект StorageFile. К счастью, несколько API WinRT серьезно упрощают эту задачу, как показано в js/fileOpenPickerScenario2.js, в методе onAddFileUri:

  function onAddUriFile() {
      // Ответ на нажатие кнопки Add (Добавить)
      var imageSrcInput = document.getElementById("imageSrcInput");

      if (imageSrcInput.value !== "") {
      var uri = new Windows.Foundation.Uri(imageSrcInput.value);
      var thumbnail =
      Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(uri);

      // Получение файла по URI для добавления в корзину средства выбора файлов
      Windows.Storage.StorageFile.createStreamedFileFromUriAsync("URI.png", uri, thumbnail).then(function (fileToAdd) {
      addFileToBasket(uriFileId, fileToAdd);
      },
      function (error) {
      // ...
      });
      } else {
      // ...
      }
      }

Здесь Windows.Storage.StorageFile.createStreamedFileFromUriAsync выполняет всё необходимое для того, чтобы дать нам StorageFile для URI, а addFileToBasket это внутренний метод, который просто вызывает метод addFile method объекта FileOpenPickerUI.

Заметьте, что если вам нужно произвести проверку подлинности или выполнить какие-то другие особые шаги для получения содержимого с веб-сервиса, вам обычно нужно использовать API Windows.Netwoking.BackgroundTransfer (http://msdn.microsoft.com/library/windows/apps/windows.networking.backgroundtransfer.aspx ) для того, чтобы получить это содержимое (здесь вы можете задать учетные данные), за ним последует StorageFile.createStreamedFile для того, чтобы передать полученный файл через контракт. StorageFile.createStreamedFileFromUriAsync выполяет то же самое, но не предусматривает проверку подлинности.

Поставщик сохранения файлов: сохранение файла

Так же, как поставщик открытия файлов взаимодействует с объектом FileOpenPickerUI, поставщик для сохранения файлов работает со специальными методами, свойствам и событиями класса FileSavePickerUI. Повторюсь, контракты открытия и сохранения имеют дело с источниками данных, для которых вы можете создать приложение-поставщик, и которые могут поддерживать или не поддерживать операции сохранения независимо от операций открытия. Если вы поддерживаете и то и другое, вы, вероятно, повторно используете тот же пользовательский интерфейс и используете ту же начальную страницу и путь активации.

В классе FileSavePickerUI у нас, для начала, имеется свойство allowedFileTypes, соответствующее тому, что предоставлено приложением, которое активирует интерфейс средства сохранения файла. Как и в случае с открытием, вы будете использовать это свойство для фильтрации того, что будет отображено в вашем собственном интерфейсе, таким образом пользователь может точно видеть, какие элементы заданных типов уже существуют. Так же при этом обычно заполняют выпадающий список типов файлов теми же типами файлов.

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

Возвращаясь к рис. 3.2., обратите внимание на элементы управления вдоль нижней стороны экрана, они автоматически предоставляются интерфейсом средства выбора файлов, когда запускается приложение-поставщик. Когда пользователь меняет поле, содержащее имя файла, приложение-поставщик может прослушать и обработать событие filenameChanged объекта FileSavePickerUI. В обработчике вы можете получить новое значение из свойства fileName. Однако, если приложение-поставщик имеет интерфейс для задания имени файла, оно не может осуществлять запись в это свойство. Вместо этого оно должно вызывать метод trySetFileName, который возвратит значение из перечисления SetFileNameResult ( http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.provider.setfilenameresult.aspx), которое может принимать значения succeeded, notAllowed (обычно при неподходящем типе файла), или unavailable. Обычно это используется, когда пользователь касается элемента в списке, ожидаемое поведение системы в таком случае заключается в установке имени файла в значение имени выбранного элемента.

Самое важное событие, конечно, происходит, когда пользователь, в итоге, нажимает на кнопку Save (Сохранить). Это действие вызывает событие targetFileRequested (http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.provider.filesavepickerui.targetfilerequested.aspx ) объекта FileSavePickerUI. Вы должны предоставить обработчик для этого события, в котором вы должны создать пустой объект StorageFile, в котором приложение, которое активировало интерфейс средства сохранения файлов сможет сохранить свои данные. Имя этого StorageFile должно совпадать со свойством fileName.

Свойство eventArgs для этого события является объектом Windows.Storage.Pickers.Providers.TargetFile-RequestedEventArgs (http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.provider.targetfilerequestedeventargs.aspx). Оно содержит единственное свойство, которое имеет имя request, которое является объектом TargetFileRequest ( http://msdn.microsoft.com/library/windows/apps/windows.storage.pickers.provider.targetfilerequest.aspx). В его свойство targetFile помещают созданный StorageFile (или null, если произошла ошибка). Вы должны установить это свойство, прежде чем вернетесь из обработчика события, но, конечно, для того, чтобы это сделать вам может понадобиться асинхронная операция. Для этой цели, как мы видели уже много раз, запрос так же содержит метод getDeferral. Он использован в Сценарии 1 примера поставщика, при сохранении файла (js/fileSavePickerScenario1.js):

 function onTargetFileRequested(e) {
      var deferral = e.request.getDeferral();
      // Создаём файл для передачи его средству работы с файлами
      Windows.Storage.ApplicationData.current.localFolder.createFileAsync(
      fileSavePickerUI.fileName).done(function (file) {
      // Присваиваем полученный файл свойству targetFile и завершаем отложенную операцию
      e.request.targetFile = file;
      deferral.complete();
      }, function () {
      // Устанавливаем targetFile в null и завершаем отложенную операцию для того,
      // чтобы показать, что произошла ошибка
      e.request.targetFile = null;
      deferral.complete();
      });
      };

В вашем приложении, конечно, замените вызов createFileAsync в локальной папке любыми необходимыми шагами для создания файла или объекта данных. Если, с другой стороны, речь идёт об удалённых файлах, вам нужно задействовать контракт Обновление кэшированных файлов (Cached File Updater) (смотрите соответствующий раздел ниже).

Поставщик сохранения файлов: ошибка

Сценарий 2 интерфейса сохранения файлов примера поставщика показывает еще один аспект этого процесса: отображение сообщений об ошибках, если возникают ошибки при создании необходимого StorageFile. Вообще говоря, вы, для того, чтобы сообщить пользователю о том, что ему нужно сделать, можете использовать любой интерфейс, который кажется вам подходящим и соответствующим стилю приложения. В примере использован MessageDialog:

 function onTargetFileRequestedFail(e) {
      var deferral = e.request.getDeferral();

      var messageDialog = new Windows.UI.Popups.MessageDialog("If the app needs the user to
       correct a problem before the app can save the file, the app can use a message like this to
      tell the user about the problem and how to correct it.");

      messageDialog.showAsync().done(function () {
      // Устанавливаем свойство targetFile в null и завершаем отложенную операцию для того,
      // чтобы показать, что произошла ошибка, как только пользователь закроет диалоговое окно.
      // Это позволит пользователю выполнить необходимые исправления и затем снова нажать на кнопку
      // Save (Сохранить).
      e.request.targetFile = null;
      deferral.complete();
      });
      };
< Лекция 2 || Лекция 3: 12345 || Лекция 4 >