Россия, Тамбов, ТГТУ, 2009 |
Плитки, уведомления, экран блокировки и фоновые задачи
Использование локальных изображений и изображений, полученных из веб
Сценарий 1 примера, как мы уже видели, показывает обновление плиток с использованием текста, но гораздо интереснее, когда в обновления входят и изображения. Они могут поступать либо из пакета приложения, локальных данных приложений, или из веб, с использованием, соответственно, таких URI, как ms-appx:///, ms-appdata:///local, и http://. Эти URI просто назначены атрибутам src элементов image в шаблонах плиток. (Это именно image, а не img, как в HTML). Снова отметим, что первые два URI обычно имеют три слэша в начале для указания на "текущее приложение". Для URI http:// требуется объявления в манифесте приложения возможности Интернет (Клиент) (Internet (Client)).
Сценарий 2 примера (js/sendLocalImage.js) показывает использование ms-appx:/// для изображения внутри пакета приложения, с вариантами для всех трех методов создания полезных данных, которые мы уже видели. При использовании методов XmlDocument, настройка источника изображения выглядит так:
var tileImageAttributes = tileXml.getElementsByTagName("image"); tileImageAttributes[0].setAttribute("src", "ms-appx:///images/redWide.png"); Notifications Extensions Library дает нам свойства, которым мы можем присваивать URI: var tileContent = NotificationsExtensions.TileContent.TileContentFactory .createTileWideImageAndText01(); tileContent.textCaptionWrap.text = "This tile notification uses ms-appx images"; tileContent.image.src = "ms-appx:///images/redWide.png";
А при использовании XML-строк, вы можете включить URI напрямую в элемент image.
Сценарий 3 (js/sendWebImage.js) показывает то же самое, за исключением того, что вы можете использовать URI http://. Это хороший способ увидеть воздействие указания изображений, которые имеют различные соотношения сторон, как и тех, которые превышают разрешенные размеры в 1024 пикселя и размер файла в 200 Кб. Как вы можете увидеть, в подобных случаях обновления просто не отображаются.
Что касается URI ms-appdata:///local (перемещаемые и временные расположения не разрешены), его использование показано в Сценарии 8, где вы можете выбрать изображение с помощью средства выбора файлов и пример копирует его в папку локальных данных приложения. Затем на него, в составе полезных данных обновления, ссылаются как на файл, по URI ms-appdata:///local (js/imageprotocols.js):
tileContent = NotificationsExtensions.TileContent.TileContentFactory.createTileWideImage(); tileContent.image.src = "ms-appdata:///local/" + imageRelativePath;
Тот же сценарий позволяет вам экспериментировать с URI, указывающими на изображения в пакете и удаленные изображений, что позволяет реализовать инструментарий, представленный в Сценарии 5. Я так же обновил мое приложение "Here My Am!" для этой лекции (в материалах к лекции), добавил обзорный шаблон плитки с обновлением, которое содержит свежие изображения и расположения. Смотрите врезку "PNG против JPG" ниже.
Если говорить об инструментах и изображениях, посмотрите так же Сценарий 10 в SDK-примере. Он даст вам еще один полезный инструмент для обновления файлов, где вы можете обрезать и настроить изображения в соответствии с различнй плотностью пикселей так, чтобы эти изображения хорошо подходили к выбранному шаблону плитки. Вы можете сохранить обработанные изображения для включения в пакет вашего приложения, код для этого сценария так же можно использовать для настройки изображений во время выполнения программы. Как я и сказал, очень полезно!
Последняя возможность, касающаяся изображений, заключается в том, чтобы позволить Windows автоматически добавить строку запроса к URI http://. Эта строка запроса будет описывать текущий коэффициент масштабирования, параметры контрастности (для целей обеспечения доступности приложений), и языка. Это позволяет веб-сервисам соответствующим способом подготовить изображение, избавляя приложение от необходимости самостоятельно поддерживать все эти особенности. Как описано в материале "Схема плитки" ( http://msdn.microsoft.com/library/windows/apps/br212859.aspx), в особенности, для элемента image (http://msdn.microsoft.com/library/windows/apps/br230844.aspx ), эту опцию указывают, устанавливая атрибут addImageQuery элемента image в значение true (это так же поддерживается для элементов visual и binding):
// Форма XmlDocument var tileImageAttributes = tileXml.getElementsByTagName("image"); tileImageAttributes[0].setAttribute("addImageQuery", "true"); // Форма XML-строки (другие строки кода опущены) var tileXmlString = /* ... */ "<image id='1' addImageQuery="true" src='ms-appx:///images/redWide.png'/>" /* ... */ // При использовании Notifications Extensions Library (смотрите Сценарий 9 в примере) var tileContent = NotificationsExtensions.TileContent.TileContentFactory .createTileWideImageAndText01(); tileContent.image.src = "ms-appx:///images/redWide.png"; tileContent.image.addImageQuery = true;
Во всех этих случаях добавленная строка будет иметь такую форму:
?ms-scale=<scale>&ms-contrast=<contrast>&ms-lang=<language>
Здесь <scale> принимает значения 80, 100, 140, или 180, <contrast> принимает значения standard, black, или white, и <language> это код языка в формате BCP-47, например, en-US, jp-JP, de-DE, и так далее. Все это описано в материале "Глобализация и специальные возможности для уведомлений на плитках и всплывающих уведомлени" (http://msdn.microsoft.com/library/windows/apps/Hh831183.aspx ), в том числе и то, как локализовать текст обновления.
Врезка: Размер файлов PNG против JPEG
Если говорить об изображениях для больших масштабов в 140% и 180%, кодировка, которую вы используете для изображений может оказать серьезное влияние и позволить, чтобы изображения не превысили лимит в 200 Кб. В Главе 3 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript" мы видели, что прямоугольная широкая плитка при 180% масштабе занимает 558x270 пикселей, а квадратная – 270x270 пикселей. В случае с прямоугольной плиткой, обычная фотография в формате PNG легко превысит лимит в 200 Кб.
Я столкнулся с этим, когда добавлял в "Here My Am!" поддержку плитки, где я сделал уменьшенную версию текущего фотоснимка в папке локальных данных приложения и использовал URI ms-appdata:///local в полезных данных XML. Сначала я позаимствовал код из Сценария 10 примера "Плитки и индикаторы событий приложения", с которым мы здесь работали, для создания PNG-файла из элемента img с использованием временного canvas и API для работы с большими двоичными объектами. Все это хорошо работало для размера изображения плитки в 270х270 (для масштаба 180%, которое может быть уменьшено), но для размера в 558х270 файл оказался слишком большим. Тогда я взял код из Сценария 3 примера "Простая работа с изображениями" (http://code.msdn.microsoft.com/windowsapps/Simple-Imaging-Sample-a2dec2b0 ) для того, чтобы напрямую перекодировать StorageFile для текущего изображения в формат JPEG, где сжатие гораздо лучше и не нужно использовать временный canvas. Этот код находится в функции transcodeImageFile в pages/home/home.js, подпрограмма, которую мы перепишем в Главе 6 с использованием C# в компоненте WinRT.
Подобные соображения, безусловно, важны для сервисов, которые обрабатывают параметры addImageQuery для целей масштабирования. Для изображений больших размеров, возможно лучше всего остановиться на формате JPEG, для того, чтобы размер изображения оставался в пределах лимита в 200 Кб.
Брэндинг
Если вы – один из тех людей, кому нравится читать документацию по схемам XML (такую, как "Схема плитки" (http://msdn.microsoft.com/library/windows/apps/br212859.aspx ), о которой я недавно упоминал), вы могли заметить еще один атрибут для элементов visual и binding , который называется branding. Он может быть установлен в значения none, logo (по умолчанию), или name для указания того, следует ли поместить на плитку маленький значок компании или краткое имя, и то и другое описывается в манифесте приложения. Сценарий 5 примера "Плитки и индикаторы событий приложения" позволяет вам поэкспериментировать с этими вариантами.
Другие части манифеста, которые влияют на побновление плитки – это параметры Текст переднего плана (Foreground Text) и Цвет фона(Background Color) в разделе Интерфейс приложения (Application UI). Они определяют, как будет отображаться текст при всех обновлениях плитки (и всплывающие уведомления), и они не могут быть изменены в полезных данных плитки. Это позволяет сохранить однородность в брендировании приложения между обновлениями. Пользователь, вероятно, будет сбит с толку, если разные плитки одного и того же приложения будут иметь разные цвета.
В качестве быстрого примера, пример из SDK, с которым мы здесь работаем, использует светлый текст переднего плана и фоновый цвет #00b2f0. Если я перейду в Сценарий 5, выберу шаблон TileWideText09, добавлю немного текста и выберу значок (logo) для брендинга, (где маленький значок содержит изображение с надписью "SDK"), результат будет следующим:
Циклические и запланированные обновления, обновления со сроком действия
Хотя вы могли прочитать заголовок этого раздела и подумать, что это – куча случайных слов, все это, на самом деле, означает, что мы разбираемся с дополнительными методами объекта TileUpdater (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.aspx ) и повторно рассматриваем два свойства объекта TileNotification, которые мы уже упоминали. Проще говоря, сейчас, когда мы уже посмотрели, как выполнять основные операции по обновлению плиток, мы готовы к тому, чтобы разобраться с дополнительными возможностями. Повторюсь, все, о чем идет здесь речь, применимо ко всем плиткам в
Для начала, вот возможность программной очистки всех обновлений и сброса плитки в ее состояние по умолчанию, соответствующему определению в манифесте. Это происходит при простом вызове TileUpdater.clear (показано в Сценарии 1):
Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication().clear();
Следующая возможность, как уже упомянуто, это установка свойства TileNotification.expirationTime перед отправкой уведомления TileUpdater.update. Это гарантирует, что локальное уведомление будет автоматически удалено, и позволяет вам переопределять трехдневный период по умолчанию для обновлений, полученных из облака. Обновление появится немедленно (то есть, при следующем обновлении плитки) и затем будет удалено после того, как истечет его срок. Это показано в Сценарии 7 примера – отправка обновления с датой истечения срока действий приведет к отображению обновления, как на левом рисунке ниже. Когда срок истечет, обновление будет удалено, что приведет к тому, что плитка вернется в свое исходное состояние, как показано справа (и, да, я работаю над этим материалом в воскресенье вечером!):
Для того, чтобы отложить появление обновления до заданного времени, с истечением срока его действия или без него, нужно поступить немного иначе в самом начале: вместо создания объекта TileNotification для отправки его средству обновления, нужно создать ScheduledTileNotification (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.scheduledtilenotification.aspx ) и откравить его TileUpdater.addToSchedule (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.addtoschedule.aspx ).
ScheduledTileNotification, это то же самое, что и TileNotification (включая время истечения срока действия) за исключением того, что этот объект содержит дополнительное свойство, которое называется deliveryTime, указывающее на то, когда, по времени UTC time, а не по местному времени!—следует отобразить обновление. Для того, чтобы найти пример использования этого, мы ненадолго заглянем в Сценарий 1 примера "Запланированные обновления" (http://code.msdn.microsoft.com/windowsapps/Scheduled-notifications-da477093 ). Но, что на самом деле различается, так это то, что мы берем любой XmlDocument , который мы создали, наполнив его полезными данными с помощью любого из рассмотренных ранее, и создаем уведомление с указанием времени его доставки. Вот выборка из кода файла примера js/scenario1.js:
// Пространство имен переменной var Notifications = Windows.UI.Notifications; // Задержка во времени доставки, взятая из элемента управления примера var dueTimeInSeconds = parseInt(document.getElementById("futureTimeBox").value); // Реальные дата и время доставки var currentTime = new Date(); var dueTime = new Date(currentTime.getTime() + dueTimeInSeconds * 1000); // Здесь мы создаем XmlDocument в переменной tileDOM // Теперь создадим обновление с датой доставки var futureTile = new Notifications.ScheduledTileNotification(tileDOM, dueTime); Notifications.TileUpdateManager.createTileUpdaterForApplication().addToSchedule(futureTile);
За исключением этих небольших изменений, все остальное, касающееся обновления плитки такое же, как раньше.
Очевидно, возможно, как вы можете догадываться, поставить в очередь несколько запланированных обновлений. В любое время вы можете вызвать TileUpdater.getScheduledTileNotifications (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.getscheduledtilenotifications.aspx ) для получения вектора активных объектов ScheduledTileNotification. Вы так же можете удалять любые из этих обновлений с помощью TileUpdater.removeFromSchedule (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.removefromschedule.aspx ).
Что происходит, если вы запланируете серию обновлений, которые активизируются в одно и то же время? В примере "Запланированные обновления", например, отправьте серию обновлений плитки, которые должны произойти через 10 секунд и быстро пройдите на Начальный экран чтобы увидеть результаты. Эти обновления будут появляться одно за другим, и одно из них может быть потеряно, если другое запланировано вместе с ним. Как только будет выполнено последнее обновление, оно просто будет оставаться на месте до истечения, очистки плитки или поступления нового обновления.
В подобных случаях лучше будет пользоваться циклическим обновлением плитки с помощью нескольких обновлений, таким образом, плитка будет отображать больше, чем одно последнее обновление.
Динамические плитки поддерживают циклический показ до пяти обновлений, где длительностью каждого из них управляет система для того, чтобы сохранять единообразие на Начальном экране. Для того, чтобы включить эту возможность, сначала вы должны вызвать TileUpdater.enableNotificationQueue(true) ( http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.tileupdater.enablenotificationqueue.aspx), для того, чтобы отключить циклический показ уведомлений, его нужно вызвать с параметром false. Сама по себе очередь устроена по принципу "первый вошел – первый вышел (FIFO, вы не можете иным способом контролировать порядок показа обновлений), в итоге, самое старое уведомление удаляется, если добавляется новое, когда очередь содержит максимальное количество элементов. Другими словами, если вы активируете очередь и отправляют уведомления как обычно, пять самых свежих циклически отображаются на плитке.
Может возникнуть необходимость выборочно заменить присутствующие в очереди уведомления вместо того, чтобы полагаться на FIFO-поведение (или вызвать TileUpdater.clear и повторно отправить уведомления, которые вы хотите оставить). Это – цель свойства tag (тег) в TileNotification и ScheduledTileNotification. Свойство tag, повторюсь, это строка длиной до 16 символов, которая просто идентифицирует конкретное обновление. Если очередь включена, новое обновление с любым заданным параметром tag заменит любое обновление с тем же tag, уже присутствующее в очереди. Если такого тега в элементах очереди нет, обновление заменит самое старое в очереди. Таким образом, например, новостное приложение может иметь пять тегов для разных категорий новостей, таких, например, как world, local, politics, business, и health. Биржевое приложение, очевидно, может использовать теги для разных биржевых символов акций. Похожим образом, приложение, предоставляющее информацию о погоде может использовать теги обновлений в виде почтовых индексов или других идентификаторов расположения.
Вы можете поэкспериментировать со всем этим в Сценарии 6 примера "Плитки и индикаторы событий приложения". В процессе работы вы можете заметить, что при активации приложения с помощью живой плитки, циклически отображающей уведомления, приложение не получает сведений о том какое именно уведомление сейчас отображается. По этой причине в настоящее время рекомендуется, чтобы при активации через циклически обновляющуюся плитку приложение открывалось бы на главной странице, которая отображает содержимое, подходящее ко всем уведомлениям.
Обновления индикаторов событий
Последнее, что вы можете использовать при обновлении динамической плитки – это индикатор событий. Я привожу этот материал отдельно, так как этот механизм работает посредством другого API и не является частью обновления посредством XML, которым мы пользовались.
Индикаторы событий – это просто маленькие значки, глифы – число из одной-двух цифр, или один из некоторого количества символов, которые появляются на плитке вне зависимости от другой деятельности по ее обновлению. Они применяются для оповещения о состоянии приложения, а не для отображения некоторого содержимого, поэтому, наподобие названия или логотипа, они не анимируются вместе с другими обновлениями. Однако, изменения индикатора анимируются особым образом, с использованием WinJS.UI.Animations.updateBadge, как было кратко показано в Главе 5 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript".
То, как можно отправить индикаторы событий на плитку, по структуре напоминает обновление плитки. Начинают с создания полезной нагрузки для XmlDocument, содержащей сведения об обновлении индикатора с использованием шаблона из "Каталога изображений индикатора событий" ( http://msdn.microsoft.com/library/windows/apps/hh761458.aspx), или с использованием Notifications Extensions Library, которая содержит полную поддержку индикаторов событий. В случае с индикаторами событий, это перебор, говорить об XML-"документе", так как он содержит лишь один элемент, badge, с одним атрибутом, value, для которого можно задать число – от 1 до 99 (все, что больше, отображается как 99+), или один из 11 специальных глифов, как показано ниже. Отметим, что хотя глифы показаны здесь на синем фоне, их реальный цвет зависит от Цвета фона (Background Color) в вашем манифесте:
Если хотите, можете использовать функцию BadgeUpdateManager.getTemplateContent (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.badgeupdatemanager.gettemplatecontent.aspx ) для получения XmlDocument с подобным содержимым; на странице справки по этомуметоду есть пример кода, который показывает, как это сделать. Но, так как XML здесь очень простой, так же легко создать объект из строки, использовав команду new Windows.Data.Xml.Dom.XmlDocument , а потом вызвать метод loadXml, как мы уже видели в случае с плитками.В Notifications Extensions Library так же есть методы для этого и для выполнения обновлений. Оба подхода показаны в Сценарии 6 примера "Плитки и индикаторы событий приложения".
Как бы вы ни создали нужный объект, следующий шаг заключается в создании экземпляра BadgeNotification ( http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.badgenotification.aspx) с этим XmlDocument:
var badge = new Windows.UI.Notifications.BadgeNotification(badgeDOM);
Этот объект уведомления так же, как и в случае с плитками, поддерживает свойство expirationTime. Помимо этого, последний шаг заключается в вызове BadgeUpdateManager.createBadgeUpdaterForApplication (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.badgeupdatemanager.createbadgeupdaterforapplication.aspx ) для получения BadgeUpdater (http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.badgeupdater.aspx ) для плитки приложения, или – вы вполне можете это предсказать - BadgeUpdateManager.createBadgeUpdaterForSecondaryTile ( http://msdn.microsoft.com/library/windows/apps/windows.ui.notifications.badgeupdatemanager.createbadgeupdaterforsecondarytile.aspx) для получения BadgeUpdater для дополнительной плитки с заданным tileId. После того, как вы получите BadgeNotification (повторюсь, здесь может помочь Notifications Extensions Library), затем вы вызываете BadgeUpdate.update:
Windows.UI.Notifications.BadgeUpdateManager.createBadgeUpdaterForApplication() .update(badge);
Или:
Windows.UI.Notifications.BadgeUpdateManager.createBadgeUpdaterForSecondaryTile ( "SecondaryTile.LiveTile").update(badge);
Как и при работе с плитками, BadgeUpdater.clear полностью убирает индикатор уведомлений, что эквивалентно отправке обновления со значением none. Вот и все.
Помимо этого, класс BadgeUpdater имеет два дополнительных метода, startPeriodicUpdate и stopPeriodicUpdate, которые присутствуют и в классе TileUpdater. А не знакомы ли они вам? Периодические обновления – это наша следующая тема, - да, я и это запланировал!
Врезка: Сколько сетевого трафика нужно плиткам?
Вместе с многими другими улучшениями, Task Manager (Диспетчер задач) для Windows 8 умеет отслеживать объем данных, переданных приложениями по сети для обновления плитки. Запустите Диспетчер задач, не забудьте нажать на кнопку More Details (Подробнее) в его нижней левой части, и затем выберите вкладку App History (Журнал приложений). Объем сетевого трафика, потребленный для обновления плиток показан в самой правой колонке. Здесь обычно отображаются маленькие значения, но это параметр, благодаря которому вы можете увидеть, не чрезмерны ли эти обновления.