Динамичность и активность. Часть 1. Работа с плитками, индикаторами событий и всплывающими уведомлениями

Живые плитки и связанные с ними возможности отображения индикаторов событий, всплывающих уведомлений и push-уведомлений являются одной из отличительных особенностей Windows 8 и приложений Магазина Windows. Их сочетание делает систему "живой и активной": приложения постоянно получают информацию от связанных с ними служб, и эта информация отображается как на начальном экране, так и на экране блокировки, даже когда сами приложения не работают.

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

Ссылки по теме:

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

В первой части (данной записи) мы рассмотрим следующие вопросы:

  • Краткий наглядный обзор интерфейса пользователя: что означает эта "активность" для пользователя?
  • XML-схему для плиток, индикаторов событий и всплывающих уведомлений, выявляющую множество компонентов и возможностей, которые не всегда очевидны при просмотре каталога шаблонов.
  • Связь между плитками, уведомлениями и фоновыми задачами.

Во второй части обсуждается программирование и отладка служб на нескольких языках, в частности использование localhost и Visual Studio 2012 Express для Web/Visual Studio 2012. В ней также рассматривается использование для этого Windows Azure Mobile Services.

В третьей части рассматриваются push-уведомления: как работать со службой push-уведомлений Windows (WNS) и как использовать Windows Azure Mobile Services для поддержки push-уведомлений в вашем приложении.

Три части статьи представляют собой более развернутое изложение моего доклада 3-101 Alive With Activity (Динамичность и активность), представленного на конференции //Build 2012 (видеозапись и слайды этого доклада доступны на канале Channel 9). В них находит свое отражение и дополняется материал раздела 13 моей бесплатной электронной книги Programming Windows 8 Apps in HTML, CSS, and JavaScript (Программирование приложений для Windows 8 на HTML, CSS и JavaScript), выпущенной издательством Microsoft Press. Эта книга, несмотря на название, полезна также разработчикам, использующим и другие языки программирования.

Что означает "активность" для пользователя?

"Активность", о которой мы говорим в этом цикле статей, проявляется для пользователя в трех местах: на начальном экране, на экране блокировки и везде, где отображаются всплывающие уведомления.

На начальном экране она проявляется через плитки, которые, безусловно, вам уже знакомы. Как показано в следующих примерах, плитки могут быть квадратными или широкими, в них могут применяться различные шаблоны структуры для отображения текста, изображений или и того, и другого. Цвета определяются манифестом приложения; пользователь может выбрать, будет плитка квадратной или широкой, если приложение поддерживает оба варианта. В левой нижней части плитки может отображаться имя приложения, логотип, а может и ничего не отображаться. В правой нижней части может отображаться небольшой "индикатор событий", число в диапазоне 1-99 (как для почты, сообщений и т. п.) или один из множества предварительно заданных глифов (см. Каталог изображений для индикаторов событий).

Начальный экран Windows 8 с плитками

Шаблоны плиток также включают в себя множество "обзорных" моделей, переходящих от одной части контента к другой, например от изображения к тексту (в Каталоге шаблонов плиток они выглядят как плитки двойной высоты, на которых отображаются обе половины). Система будет гармонично анимировать переходы между этими двумя частями вместе со всеми другими анимациями плиток. Кроме того, у каждой плитки может быть очередь, состоящая не более чем из пяти обновлений, отображаемых автоматически в цикле. Они также анимируются системой согласованно с анимацией других плиток. Каждое обновление в очереди может иметь тег, чтобы вы могли заменять каждое из них по отдельности, в противном случае очередь отображается по принципу "первым пришёл — первым обслужен".

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

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

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

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

На экране блокировки активность приложений отображается рядом с датой, временем и системными индикаторами событий. Как показано в следующем примере, контент приложения состоит из не более семи логотипов и индикаторов событий, расположенных вдоль нижнего края, и одного обновляемого текстового блока рядом со временем:

Контент этого приложения состоит из не более семи логотипов и индикаторов событий и одного обновляемого текстового блока рядом со временем

Пользователь управляет тем, что отображается на экране блокировки, через "Параметры компьютера" > "Персонализация" > "Экран блокировки". Ниже приведен пример. Если коснуться одного из квадратов в первой строке, появляется список приложений с поддержкой экрана блокировки, которые будут отображаться как логотип и индикатор событий. Во второй строке можно выбрать приложение, предоставляющее подробный текст. Этот текст берется из последнего обновления плитки данного приложения.

Список приложений с поддержкой экрана блокировки

XML-код обновления

Теперь, когда мы увидели, как пользователь воспринимает активность приложений, изучим следующий вопрос: из чего состоят эти обновления? То есть как описываются обновление плитки, индикатор событий или всплывающее уведомление?

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

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

 <badge value="7"/>

Для индикатора событий с красной точкой у показанной выше плитки (расположенной внизу посередине) аналогичные полезные данные, как часто называют эти XML-фрагменты, будут следующими.

 <badge value="busy"/>

Полезные данные XML для этой же широкой плитки, содержащие ссылку на ее изображение, текст и параметры логотипа и имени, будут более или менее похожи на следующие (универсальный код ресурса изображения является вымышленным) при использовании шаблона TileWideSmallImageAndText01:

 <tile>
  <visual>
    <binding template="TileWideSmallImageAndText01" branding="logo">
      <image id="1" src="https://friends.contoso.com/sally.png" alt="Sally's picture"/>
      <text id="1">Hey, you there? Txt me when you’re back</text>
    </binding>
  </visual>
</tile>

В этих полезных данных видно, что мы определяем шаблон в элементе binding . Windows проверяет остальной XML-код на соответствие этому шаблону. Атрибут branding элемента binding указывает, отображать ли логотип (logo) или имя приложения (name) или не нужно ничего отображать (none). Дочерние элементы элемента binding описывают другие необходимые компоненты шаблона.

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

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

Обновления индикаторов событий являются простейшими, поэтому начнем с них:

 <?xml version="1.0" encoding="utf-8" ?>
<badge value = "1-99" | "none" | "activity" | "alert" | “attention” | "available" |
    "away" | "busy" | "newMessage" | "paused" | "playing" | "unavailable" | "error" 
    version? = "integer" />

Технически все полезные данные XML должны иметь тег заголовка <?xml> . Windows хорошо работает и без них, но я решил включить их для полноты.

Далее вы видите, что элемент badge содержит только атрибут value, который может быть числом (любое число больше 99 отображается как "99+") или одним из набора предварительно заданных слов, определяющих специальные глифы. Эти элементы также описаны в документации на странице Каталога изображений для индикаторов событий.

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

Обновления плиток имеют следующую псевдосхему:

 <?xml version="1.0" encoding="utf-8" ?>
<tile>
  <visual version? = "integer" lang? = "string" baseUri? = "anyURI" fallback? = "string"
    branding? = "none" | "logo" | "name" addImageQuery? = "boolean" >

    <!-- One or more binding elements -->
    <binding template = "TileSquareImage" | "TileSquareBlock" | "TileSquareText01" | ... 
      fallback? = "string" lang? = "string" baseUri? = "anyURI"
      branding? = "none" addImageQuery? = "boolean" >
      
      <!-- Some combination of image and text elements -->
      <image id = "integer" src = "string" alt? = "string" addImageQuery? = "boolean" />
      <text id = "integer" lang? = "string" />
    </binding>
  </visual>
</tile>

В элементе visual, содержащем атрибуты, применяемые к обновлению в целом, мы видим необязательный атрибут version , который в данный момент можно опустить. Остальные атрибуты описываются ниже:

Атрибут

Описание

lang

Необязательная строка с тегом языка BCP-47, определяющая язык данных обновления, например "en-US" или "ru-RU".

baseUri

Необязательный универсальный код ресурса (URI), который будет добавлен в начало всех остальных URI в полезных данных. Это позволяет опустить лишнюю информацию при формировании полезных данных. Значение по умолчанию — "ms-appx:///".

branding

Указывает, отображать ли на плитке логотип приложения ("logo", по умолчанию), его имя ("name") или ничего не отображать ("none").

addImageQuery

Если задано значение "true" (по умолчанию установлено значение "false"), Windows будет добавлять параметры запроса к каждому запросу к универсальным кодам ресурсов в полезных данных, то есть к каждому универсальному коду ресурса изображения, чтобы определить текущий язык, коэффициент масштабирования и контрастность. Эти параметры имеют следующий вид:

?ms-scale=<scale>&ms-contrast=<contrast>&ms-lang=<language>

Подробнее можно прочитать в статье Глобализация и специальные возможности для уведомлений на плитках и всплывающих уведомлений.

В элементе visual полезные данные имеют один или несколько элементов binding, по одному для каждого размера плитки. То есть одни полезные данные могут (и в идеале должны) содержать обновление и для квадратной, и для широкой плиток одновременно. Это важно, поскольку пользователь может изменить размер плитки в любой момент. Если вы пропустите тот или иной размер, для данного уведомления не будет ничего отображаться в случае, если пользователь задал его для плитки. Однако помните, что вы можете отправлять обновления для разных размеров по отдельности, и Windows будет поддерживать оба.

Внутри элемента binding вы видите template, определяющий шаблон XML для проверки, и такие же атрибуты, что и для visual, но они применяются только к элементам из данного binding (и переопределяют заданные в visual). Остался еще один атрибут — fallback, определяющий шаблон, который используется, если не удается найти основной шаблон. Это сделано для обеспечения обратной совместимости в будущем, поэтому нет необходимости использовать его с Windows 8.

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

Для всплывающих уведомлений мы имеем структуру, аналогичную плиткам, но с некоторыми дополнительными компонентами:

 <toast launch? = "string" duration? = "long" | "short" >
  <visual version? = "integer" lang? = "string"
    baseUri? = "anyURI" branding? = "none" | "name" | "logo" addImageQuery? = "boolean" >

    <!-- One or more bindings -->
    <binding template  = "ToastImageAndText01" | "ToastImageAndText02" | ...=""
      fallback? = "string"  lang? = "string" baseUri? = "anyURI"
      branding? = "none" addImageQuery? = "boolean" >

      <!-- Some number of child elements -->
      <image id  = "integer" src = "string" alt = "string" addImageQuery? = "boolean" />
      <text id = "integer" lang? = "string" />
    </binding>
  </visual>

  <!-- Optional audio -->
  <audio src? = "ms-winsoundevent:Notification.Default" | ...=""
    loop? = "boolean" silent? = "boolean" />
</toast>

Все атрибуты lang, baseUri, branding и addImageQuery в элементе visual имеют тот же смысл и заданные по умолчанию значения, как и в случае плиток. То же самое справедливо и для атрибутов, находящихся внутри атрибутов binding, image и text . В этой части полезных данных единственное отличие между обновлением плитки и всплывающим уведомлением фактически заключается в поддерживаемых шаблонах.

Полезные данные всплывающего уведомления отличаются атрибутами самого внешнего элемента toast и его необязательного дочернего элемента audio .

В элементе toast атрибуту launch может быть назначена строка, которая будет передана обработчику активации приложения в качестве аргументов, в точности так же, как в случае со вспомогательной плиткой. Атрибут duration может иметь значение "short"(пять секунд или значение из "Параметры компьютера" > "Специальные возможности") или "long" (25 секунд или значение из "Параметры компьютера" > "Специальные возможности" в зависимости от того, какое из этих значений больше).

В audio атрибут src является строкой, указывающей на один из набора предварительно заданных звуков. Эти параметры можно найти в Каталоге параметров звука для всплывающих уведомлений. В настоящее время можно выбирать только звуки из этого набора. Обычно они соответствуют системным звукам, настроенным на панели управления. (Примечание: если вы выключили все звуки, что я обычно делаю, вы ничего не услышите — помните об этом при тестировании своего приложения!). Это ограничение установлено по множеству причин. Например, включение настраиваемых звуков из удаленного источника создало бы гораздо более напряженный сетевой трафик, который мог бы создать проблемы, когда устройство отображает экран блокировки и старается экономить энергию в режиме ожидания с подключением. Кроме того, это позволяет предотвратить такие злоупотребления, как включение звуковой рекламы во всплывающие уведомления.

Отдельно, если для атрибута silent задано значение "true", звук всегда будет отключен. Что касается loop, то если для атрибута duration всплывающего уведомления задано значение и для src звука задан один из четырех "Циклических" звуков из каталога (по два варианта для "alarm" и "call"), вы можете также задать для loop значение "true", чтобы звук повторялся, или "false", чтобы звук воспроизводился только один раз (по умолчанию).

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

Активность, когда приложения не запущены

Теперь, когда вы знаете, какие полезные данные XML будут генерировать соответствующие типы обновлений, следует подумать, как эти полезные данные будут поступать в систему в нужное время и как они создаются. Оба этих вопроса обсуждались в предыдущих записях Эффективное использование плиток (часть 1) и Эффективное использование плиток (часть 2), где показано, как генерировать полезные данные в коде. Для этого используется библиотека Notifications Extensions, входящая в комплект многих примеров, а также доступная через Visual Studio как пакет NuGet.

А сейчас давайте сконцентрируемся на способах доставки этих полезных данных. Существует три способа их отправки:

  1. Работающее приложение или фоновая задача приложения может создавать непосредственные или локальные обновления. Они могут отображаться сразу или быть запланированы для отображения в некоторый момент времени в будущем. Кроме того, плитки, индикаторы событий и всплывающие уведомления могут иметь срок действия, по истечении которого они будут автоматически удаляться или удаляться из расписания, если не были доставлены к этому времени.

  2. Работающее приложение может передать Windows до пяти универсальных кодов ресурсов (URI) для периодических обновлений и указать интервалы в диапазоне от 30 минут до одного дня. (Когда используется несколько универсальных кодов ресурсов (URI), каждый соответствует одной из пяти ячеек в очереди обновлений.) После настройки периодического обновления Windows отправляет запрос (HTTP GET) этому URI через определенный интервал времени. Если в ответ Windows получает допустимые полезные данные, она отправляет это обновление соответствующей плитке от имени приложения, как если бы работающее приложение выпустило их напрямую. Мы рассмотрим способы создания служб обновлений во второй части этого цикла статей.

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

  3. Приложение может запросить универсальный код ресурса (URI) канала службы push-уведомлений Windows (WNS) и отправить этот URI своим собственным серверным службам. Затем эти службы могут выпускать специальные обновления любого типа через этот универсальный код ресурса (URI) канала через службу WNS, которая в свою очередь отправит это обновление на конкретное устройство, когда оно подключится к Интернету. Windows получает эти обновления и применяет их к соответствующей плитке или отображает всплывающее уведомление. В качестве альтернативы приложение может настроить фоновую задачу, получающую эти push-уведомления (что является обязательным для необработанного уведомления). Мы обсудим push-уведомления в третьей части этого цикла статей.

В следующей таблице собраны эти варианты, включая компонент циклической очереди плиток и возможности повторения всплывающих уведомлений и воспроизведения звука при их отображении.

Тип уведомления

Очередь

Запланированное

С окончанием срока действия

Повторяющееся

Звук

Периодическое

Push-уведомление

Плитка

   

Индикатор событий

   

   

Всплывающее

 

 

Необработанное

           

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

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

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

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

Фоновые задачи также важны для поддержки необработанных push-уведомлений, когда приложение не запущено. Мы вернемся к ним в третьей части.

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

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

Крэйг Брокшмидт (Kraig Brockschmidt)

Руководитель программы, рабочая группа по экосистеме Windows

Автор книги Programming Windows 8 Apps in HTML, CSS, and JavaScript (Программирование приложений для Windows 8 на HTML, CSS и JavaScript)