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

Плитки, уведомления, экран блокировки и фоновые задачи

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

Активация приложения с помощью дополнительной плитки

Дополнительные плитки предоставляют способ активации приложения с переводом в состояние, которое отличается от состояния по умолчанию. Это похоже на то, как аргументы командной строки работают с классическими приложениями рабочего стола или с консольными программами. Этот процесс полностью зависит от содержимого свойства arguments дополнительной плитки. Когда пользователь касается дополнительной плитки или щелкает по ней мышью, вызывается событие приложения activated с видом активации launch и со значением свойства дополнительной плитки arguments в eventArgs.detail.arguments. Затем приложение предпринимает действия, предписываемые этими данными, такие, как перемещение на конкретную страницу содержимого, получение фрагмента содержимого из онлайнового источника и так далее. В примере о дополнительных плитках, код активации в файле js/default.js перемещается к странице Сценария 5, мы передаем arguments как параметр для WinJS.Navigation.navigate:

function activated(eventObject) {
if (eventObject.detail.kind ===
Windows.ApplicationModel.Activation.ActivationKind.launch) {
if (eventObject.detail.arguments !== "") {
// Аргументы активации присутствуют (они заданы, когда
// дополнительная плитка была закреплена)
eventObject.setPromise(WinJS.UI.processAll().done(function () {
// Перемещение к странице Scenario 5, где пользователю будут показаны
// аргументы активации
return WinJS.Navigation.navigate(scenarios[4].url, eventObject.detail.arguments);
}));
} else {
// Активация по умолчанию
}
}
}
    

Элемент управления страницы (js/LaunchedFromSecondaryTile.js) принимает строку аргументов в параметре options и для метода processed и для метода ready. В примере эта строка просто выводится на экран:

var page = WinJS.UI.Pages.define("/html/LaunchedFromSecondaryTile.html", {
processed: function (element, options) {
if (options) {
document.getElementById("launchedFromSecondaryTileOutput").innerHTML += "
  " + "App was activated from a secondary tile with the following activation" +
  "arguments : " + options + "
     ";
}
},
ready: function (element, options) {
});
    

Ваше собственно приложение, конечно, будет делать с arguments что-нибудь гораздо более интересное!

Управление дополнительными плитками

В дополнение к методам и свойствам для создания дополнительных плиток, класс SecondaryTile имеет два статических метода для управления дополнительными плитками приложения:

exists ( http://msdn.microsoft.com/library/windows/apps/windows.ui.startscreen.secondarytile.exists.aspx) Возвращает логическое значение, показывающее существует ли на Начальном экране дополнительная плитка, идентифицируемая ее свойством tileId. Это сообщает вам о том, заменит ли метод requestCreate*, вызванный с тем же самы tileId существующую плитку другой. Это показано в Сценарии 4 примера о дополнительных плитках.

findAllAsync (http://msdn.microsoft.com/library/windows/apps/br242208.aspx ) Возвращает вектор объектов SecondaryTile, созданных приложением. Этот список включает в себя и плитки, перемещенные с другого устройства (они создаются с помощью опции copyOnDeployment) . Это показано в Сценарии 3 примера.

В дополнение, есть и несколько методов для работы с конкретным экземпляром SecondaryTile:

  • requestDeleteAsync и requestDeleteForSelectionAsync Непосредственные аналоги, с теми же вариантами размещения, что и в методах requestCreate*, удаление дополнительной плитки (открепление) так же требует согласия пользователя. Это показано в Сценариях 2 и 7 примера.
  • updateAsync Применяет к объекту SecondaryTile изменения свойств после того, как плитка была закреплена на Начальном экране. Это можно видеть в Сценарии 8 примера.

Если вы внимательно читали этот раздел, вы могли заметить, что я еще не упоминал Сценарий 6 примера. Это потому, что он показывает, как сделать дополнительную плитку динамической плиткой с возможностью обновления. Для того, чтобы это понять, нам нужно разобраться с обновлениями, так как используемый механизм обновлений сходен для всех плиток. Это будет следующей нашей темой. – я так и планировал!

Основы обновлений плиток

Локальное обновление для плитки, как было описано выше в этой лекции, это обновление, которое приложение выполняет, когда оно исполняется. На самом деле, это один из лучших моментов для отправки обновлений, так как весьма вероятно, что у приложения уже есть информация для обновления любых своих плиток. Во множестве случаев, особенно, когда приложение не связано с веб-сервисом, информация, нужная для динамических плиток приложения доступна лишь во время исполнения программы. Игра, например, может отправить обновления, показывающие лучшие результаты, новые соревнования, сведения о прохождении игры и другие виды интригующих приглашений, побуждающих пользователя снова запустить приложение. (Должен отметить, что лично для меня это отлично работает с игрой Fruit Ninja.)

Процесс отправки локального обновления плитки довольно прост, он использует API в пространстве имен Windows.UI.Notifications:

  • Создать полезные данные XML (XML Payload), как это называют, которые описывают обновление в объекте XmlDocument (http://msdn.microsoft.com/library/windows/apps/windows.data.xml.dom.xmldocument.aspx ). XML должен всегда соответствовать одному из предопределенных шаблонов плитки. Вы можете начать с XmlDocument, предоставленного системой, создать его с нуля, или использовать Notifications Extensions Library (Библиотеку расширений уведомлений), которая предоставляет объектную модель и подсказки IntelliSense для нее.
  • Создать объект TileNotification (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tilenotification.aspx ) с этим XML. XML становится свойством content объекта TileNotification и может быть установлен отдельно.
  • При необходимости, установить свойства expirationTime и tag объекта TileNotification. По умолчанию, локальные обновления не имеют срока давности и удаляются лишь при поступлении более свежих обновлений или тогда, когда применяется операция очистки. Установка expirationDate приведет к их удалению в заданное время. (Срок уведомлений, поступивших из облака, автоматически истекает через три дня). Свойство tag – это строка из 16 или меньшего количества символов, которая используется для управления стеком обновлений, которые циклически отображаются на плитке. Подробнее об этом – немного позже.
  • Вызвать TileUpdateManager.createTileUpdaterForApplication (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdatemanager.createtileupdaterforapplication.aspx ) для получения объекта TileUpdater (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.aspx ), который связан с плиткой вашего приложения. Вызвать TileUpdateManager.createTileUpdaterForSecondaryTile ( http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdatemanager.createtileupdaterforsecondarytile.aspx) (задумайтесь над этим именем!) для получения объекта TileUpdater для дополнительной плитки с заданным tileId.
  • Вызвать TileUpdater.update с вашим объектом TileNotification. (Анимация, которая используется при отображении поступившего обновления похожа на WinJS.UI.Animation.createPeekAnimation, которая описана в Главе 5 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript").

Совет. Если вы отправляете обновления или другие уведомления, когда ваше приложение исполняется, подумайте о том, чтобы отправлять обновления и в обработчике события resuming, если вы не собираетесь использовать другие средства, наподобие периодических обновлений или push-уведомлений для обновления плитки. С тех пор, когда приложение было приостановлено, может пройти немало времени, поэтому возобновление работы приложения – это хорошая возможность для отправки обновлений.

Обратимся теперь к примеру "Плитки и индикаторы событий приложения" ( http://code.msdn.microsoft.com/windowsapps/App-tiles-and-badges-sample-5fc49148) для того, чтобы увидеть, как обновления выглядят в коде. Так как имитатор Visual Studio не поддерживает динамические плитки и всплывающие уведомления, не забудьте запустить пример с опциями Локальный компьютер (Local Machine) или Удаленный компьютер (Remote Machine).

Предполагая, что у нас есть XMLDocument с обновлением в переменной tileXml, отправка обновления занимает лишь две строчки кода (смотрите js/sendTextTile.js):

var tileNotification = new Windows.UI.Notifications.TileNotification(tileXml);
Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication()
.update(tileNotification);
    

Похожим образом выглядит обновление дополнительных плиток в Сценарии 6 примера "Дополнительные плитки" (js/SecondaryTileNotification.js):

var tileNotification = new Windows.UI.Notifications.TileNotification(tileXml);
Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForSecondaryTile(
"SecondaryTile.LiveTile").update(tileNotification);
    

Гораздо более интересный вопрос заключается в том, как мы создаем переменную tileXml, содержащую полезные данные, в первом случае. Этот процесс включает в себя использование одного из предопределенных визуальных шаблонов плитки, и затем выбор метода для создания XMLDocument. Тогда мы увидим, как использовать изображения при обновлениях, а так же, как применять рекомендацию по брендированию. Локализация и обеспечение доступности – это дополнительные соображения, касающиеся обновления плиток, но мы вернемся к этим темам в Главе 6.

Выбор шаблона плитки

Первый шаг в создании обновления плитки заключается в выборе подходящего шаблона из "Каталога шаблонов плиток" ( http://msdn.microsoft.com/library/windows/apps/hh761491.aspx). Здесь вы найдете описания, изображения и XML для 10 доступных квадратных шаблонов и 36 прямоугольных шаблонов. Да, всего 46 разных шаблонов (надеюсь, вы понимаете, почему я не показываю здесь их все!). Некоторые – только текстовые, некоторые – графические, некоторые и с текстом и с изображением (только для прямоугольных плиток), и здесь представлено множество шаблонов, называемых обзорными (peek) шаблонами. Эти шаблоны, если вы на них взглянете на вышеупомянутой странице , составлены из двух частей, каждая из которых имеет размер всей плитки, как показано ниже для квадратной плитки (слева) и прямоугольной (справа):



С помощью обзорных шаблонов вы можете показать вдвое больше содержимого, чем с помощью ругих. Когда обзорное обновление отображается на динамической плитке, верхняя часть появляется сразу, и затем плитка переворачивается, или дает вам возможность "взглянуть" на нижнюю часть, и затем снова переключается на верхнюю часть, после чего динамическая плитка переключается к следующему обновлению в цикле, если оно есть (Приложение Travel (Путешествия) использует обзорные шаблоны, если вам нужен пример. Анимация, которая здесь применяется, похожа на WinJS.UI.Animation.createPeekAnimation.). Конечно, обе части должны содержать связанные данные, так как они являются частями единичного обновления.

По поводу макетов шаблонов есть несколько важных замечаний. Во-первых, во многих представленных в настоящее время шаблонах последняя строка текста не будет отображатья, если вы так же показываете на плитке логотип или короткое название (для предотвращения перекрытия). Вероятно, в будущем это изменится, но сейчас это так.

Во-вторых, изображения ограничены размером в 1024x1024 и максимальным размером в 200 Кб. Если любое изображение превышает данные лимиты, все обновление не будет отображено. Очевидно, лучше стараться не использовать большие изображения, если это возможно, так как подобные изображения лишь повышают уровень потребления памяти и возможную нагрузку на сеть (если выполняется загрузка изображения). Так же, для изображений на плитках, полезно принимать во внимание коэффициенты масштабирования 80%, 100%, 140%, и 180%. Однако, если вы не хотите работать с отдельными коэффициентами масштабирования, создайте изображение для плитки для масштаба в 180% и позвольте системе уменьшить его (здесь используется высококачественный алгоритм, поэтому изображение будет выглядеть так же хорошо, как если бы вы уменьшили его с помощью ПО для редактирования фотографий). Кроме того, для фотографий, рассмотрите использование JPEG вместо PNG, так как первый обладает лучшими возможностями по сжатию подобных изображений.

В-третьих, если вы работаете с изображениями, которые не соответствуют итоговому соотношению сторон, изображения будут масштабированы по ширине и обрезаны сверху и снизу. Отметим так же, что соотношение сторон прямоугольной плитки, не в точности 2:1. При 100% прямоугольная плитка имеет размеры 310x150 пикселей, что означает, что изображение, занимающее ее половину, будет иметь размеры в 155x150 пикселей (не вполне квадратное) и изображение в режиме просмотра коллекций (верхний правый угол правого изображения выше) будет 77.5x75.

В-четвертых, если вам нужна плитка с изображением и текстом, которые не вписываются в существующие шаблоны, вы всегда можете использовать графический шаблон, без текста (TileSquareImage и TileWideImage), в который можно поместить изображение, которое создается во время выполнения приложения. Однако, не придавайте плитке такой вид, будто она имеет отдельные кнопки или другие зоны нажатия: вся плитка всегда действует как неделимый объект для запуска приложения, поэтому подобный дизайн дезориентирует пользователя.

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

Сценарий 5 примера "Плитки и индикаторы событий приложения" показывает пример очень полезного дизайна и инструмента для экспериментирования с плитками, как показано на рис. 4.15. Эта часть примера скорее представляет собой инструмент, нежели код, который можно использовать в своем приложении. Его средства позволяют вам просто экспериментировать со всеми шаблонами и их содержимым, включая изображения, получаемые из локальных и удаленных источников, без необходимости каждый раз писать для этого код. Он так же позволяет вам испытать различные возможности брендинга приложений и отправки результата в качестве обновления на плитку примера на Начальном экране.

Сценарий 5 примера "Плитки и индикаторы событий приложения" представляет собой инструмент для испытаний различных шаблонов плиток

Рис. 4.15. Сценарий 5 примера "Плитки и индикаторы событий приложения" представляет собой инструмент для испытаний различных шаблонов плиток

Создание полезных данных, Метод 1: заполнение содержимого шаблона

Первый способ создания полезных данных XML для заданного шаблона заключается в использовании метода TileUpdateManager.getTemplateContent (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdatemanager.gettemplatecontent.aspx ), которому вы передаете имя шаблона (значение из TileTemplateType (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tiletemplatetype.aspx )). Это показано в Сценарии 1 примера (js/sendTextTile.js):

function sendTileTextNotificationWithXmlManipulation() {
var tileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(
Windows.UI.Notifications.TileTemplateType.tileWideText03);

Этот метод возвращает объект XmlDocument, который содержит структуру XML для шаблона, но никакого содержимого. Если вы запустите пример и просмотрите tileXml сразу после вышеприведенного вызова, он будет содержать лишь следующее – элементы, но не данные:

<tile>
   <visual>
     <binding template="TileWideText03">
       <text id="1"></text>
     </binding>
   </visual>
 </tile>

Следующий шаг заключается в заполнении значений (в основном атрибутов) с использованием методов XmlDocument, которые вы уже, возможно, знаете (и они вам могут нравиться, а могут и нет):

var tileAttributes = tileXml.getElementsByTagName("text");
tileAttributes[0].appendChild(tileXml.createTextNode(
"Hello World! My very own tile notification"));

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

var squareTileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(
Windows.UI.Notifications.TileTemplateType.tileSquareText04);
var squareTileTextAttributes = squareTileXml.getElementsByTagName("text");
squareTileTextAttributes[0].appendChild(squareTileXml.createTextNode(
"Hello World! My very own tile notification"));

var node = tileXml.importNode(squareTileXml.getElementsByTagName("binding").item(0), true);
tileXml.getElementsByTagName("visual").item(0).appendChild(node);
Теперь все готово для того, чтобы отправить обновление плитке:
// отправка уведомления плитке приложения
Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication()
.update(tileNotification);
}

Отметим, что элементы visual в XML поддерживают version (версии) атрибутов, значение по умолчанию которых равняется 1. Это поможет поддерживать будущие изменения, где добавленные элементы с более новыми версиями XML, чем та, что сейчас поставляется в Windows 8, просто будут игнорироваться. Схему, которая применяется в плитках, если вам интересно, можно найти на странице "Схема плитки" ( http://msdn.microsoft.com/library/windows/apps/br212859.aspx).

Создание полезных данных, Метод 2: XML-строки

Вместо того, чтобы вызывать TileUpdateManager.getTemplateContent для получения XmlDocument с содержимым шаблона, вы просто можете создать нужный XmlDocument напрямую, из строки. Это очень похоже на создание элементов в DOM с помощью использования innerHTML вместо использования DOM API. Это предусматривает уменьшение общего количества вызываемых функций для создания необходимых полезных данных и хорошо подходит для предварительного задания большого количества почти полностью заполненых вариантов обновлений

Этот метод прост. Задайте XML-строку с содержимым для обновления, создайте новый XmlDocument, и воспользуйтесь его методом loadXml для превращения строки в полезные данные. В Сценарии 1 мы видим, как это реализуется для создания тех же полезных данных, что и в предыдущем разделе:

function sendTileTextNotificationWithStringManipulation() {
// создадим строку с XML-шаблоном плитки
var tileXmlString = "<tile>
  "
  + "<visual>
    "
    + "<binding template='TileWideText03'>
      "
      + "<text id='1'>Hello World! My very own tile notification</text>"
      + "
    </binding>"
    + "<binding template='TileSquareText04'>
      "
      + "<text id='1'>Hello World! My very own tile notification</text>"
      + "
    </binding>"
    + "
  </visual>"
  + "
</tile>";

var tileDOM = new Windows.Data.Xml.Dom.XmlDocument();
tileDOM.loadXml(tileXmlString); // Хорошая мысль – поместить это в блок try/catch

var tile = new Windows.UI.Notifications.TileNotification(tileDOM);
Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication()
.update(tile);
}

Очевидно, этот метод очень просто, но имеет недостаток, требуя ручной обработки. Кроме того, его сложнее отлаживать. (Поиск мелких ошибок в строках не относится к моему любимому времяпрепровождению!). К счастью, есть и еще один метод: Notifications Extensions Library, который предоставляет простоту использования строк с высоким уровнем надежности.

Создание полезных данных, Метод 3: Notifications Extensions Library

Третье средство создания необходимого XmlDocument для обновления плитки заключается в использовании того, что называется Notifications Extensions Library(Библиотека расширений уведомлений). Это WinRT-компонент, написанный на C#, который включен во многие примеры SDK, в том числе и в пример "Плитки и индикаторы событий приложения", который мы здесь рассматриваем. (Отметим, он включен в Ссылки (References) проекта.). Мы посмотрим на структуру подобных компонентов в Главе 5. Вероятнее всего эта библиотека в будущем войдет в состав Windows API, поэтому мы рекомендуем разработчикам использовать ее.

Библиотека упрощает заполнение шаблонов посредством свойств объекта, а не методов XmlDocument, и, так как она отлично протестирована в Microsoft, она гораздо более надежна, чем создание XmlDocument с использованием строк. Вот, как она используется в Сценарии 1 для создания, еще раз, тех же самых полезных данных, которые мы уже видели:

function sendTileTextNotification() {
 var tileContent =
 NotificationsExtensions.TileContent.TileContentFactory.createTileWideText03();
 tileContent.textHeadingWrap.text = "Hello World! My very own tile notification";

 var squareTileContent = NotificationsExtensions.TileContent.TileContentFactory
 .createTileSquareText04();
 squareTileContent.textBodyWrap.text = "Hello World! My very own tile notification";
 tileContent.squareContent = squareTileContent;

 Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication()
 .update(tileContent.createNotification());
 }

Проще говоря, объект библиотеки TileContentFactory предоставляет методы для создания объектов, эквивалентных XML-документам, предоставлеяемых TileUpdateManager.getTemplateContent. Как показано в вышеприведенном коде, эти объекты имеют свойства, эквивалентные каждому из полей шаблона и когда вы готовы передать данные в TileUpdater.update, вы просто вызываете метод createNotification.

Другая причина, по которой существует эта библиотека – это упрощение процесса создания ASP.NET веб-сервисов для периодических обновлений и push-уведомлений (где в уведомлении можно отправить обновление для плитки, обновления индикатора событий и всплывающие уведомления). Вместо создания полезных данных XML вручную – ненадежный и подверженный ошибкам подход – сервис может использовать Notifications Extensions Library для простого и последовательного создания XML для всех этих уведомлений.

Так как объектная модель библиотеки четко описывает XML, ей очень просто пользоваться. Вот еще один материал в документации на эту тему: "Краткое руководство: использование библиотеки NotificationsExtensions в коде приложения" (http://msdn.microsoft.com/library/windows/apps/hh969156.aspx ). И примеры, которые мы рассматриваем в этой лекции, показывают большинство вариантов ее использования.

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >