Dinâmica e ativa, parte 1: Trabalhando com blocos, notificações e notificações do sistema

Os blocos dinâmicos e as funcionalidades relacionadas às notificações, notificações do sistema e notificações por push são alguns dos recursos mais característicos dos aplicativos do Windows 8 e da Windows Store. Eles se combinam para criar um sistema "dinâmico e ativo": os aplicativos recebem um fluxo constante de informações de seus serviços que são visíveis na tela inicial e na tela de bloqueio, mesmo quando não estão sendo executados.

As postagens anteriores deste blog abordaram vários fundamentos envolvendo blocos dinâmicos e notificações.

Para examiná-los:

Para usar esses recursos, esta postagem dividida em três partes investigará com mais detalhes várias áreas.

Na parte 1 (esta postagem), teremos:

  • Um breve tour visual da experiência do usuário: o que "dinâmico" significa para o usuário?
  • O esquema XML para blocos, notificações e notificações do sistema, que revelam várias funcionalidades e características que nem sempre são óbvias quando examinamos os catálogos de modelos.
  • A relação entre blocos, notificações e tarefas em segundo plano.

A parte 2 discutirá os serviços de gravação e depuração em várias linguagens, especificamente empregando localhost junto com o Visual Studio 2012 Express para a Web/Visual Studio 2012. A parte 2 também abordará o uso dos serviços móveis do Windows Azure para essa finalidade.

A parte 3 explorará a questão das notificações por push. Isso inclui como trabalhar com os Serviços de Notificação por Push do Windows (WNS) e como usar os serviços móveis do Windows Azure para dar suporte às notificações por push no seu aplicativo.

Essas três partes refletem e ampliam a seção I apresentada em //Build 2012, 3-101 Dinâmico e ativo, para a qual o pacote de vídeo e slides está disponível no Channel 9. Elas também refletem e ampliam o material do capítulo 13 do meu livro eletrônico da Microsoft Press, Programming Windows 8 Apps in HTML, CSS, and JavaScript (Programando aplicativos do Windows 8 em HTML, CSS e JavaScript), que, apesar do título, também é útil para desenvolvedores que trabalham com outras linguagens.

O que "dinamismo" significa para o usuário?

O "dinamismo" de que estamos falando nesta série aparece para o usuário em três lugares: na tela inicial, na tela de bloqueio e sempre que é exibida uma notificação do sistema.

Na tela inicial, agora, com certeza você está familiarizado com a ideia dos blocos. Como mostramos nos exemplos a seguir, os blocos podem ser quadrados ou largos, com vários modelos de layout para exibir texto, imagens ou ambos. As cores são definidas pelo manifesto do aplicativo; o usuário pode escolher se um bloco é quadrado ou largo desde que o aplicativo ofereça suporte a ambos. O lado esquerdo do bloco pode mostrar o nome do aplicativo, um logotipo ou nada. O lado direito pode conter uma pequena "notificação", que pode ser um número de 1 a 99 (como para email, mensagens etc.) ou um glifo predefinido (consulte o Catálogo de imagens de notificação).

Tela inicial do Windows 8 mostrando blocos

Os modelos de bloco também incluem vários designs do tipo "peek" divididos entre uma parte do conteúdo, como uma imagem, e outra parte, como texto (no Catálogo de modelo de bloco eles parecem blocos de altura dupla, mas aqui são mostradas apenas as duas metades juntas). O sistema animará as transições entre essas duas partes em harmonia com todas as outras animações de bloco. Além disso, todo bloco pode ter uma fila com até cinco atualizações que se alternam automaticamente, que também são animadas pelo sistema em conformidade com outros blocos. Cada atualização na fila pode receber uma marca para que você possa substituí-la individualmente, caso contrário a fila será pela ordem de entrada.

Essa coordenação entre as animações nos ajuda a entender por que o Windows restringe as atualizações de bloco a um conjunto de modelos predefinidos. Considere com seria a experiência da tela inicial se os aplicativos pudessem fazer tudo que desejassem em seus blocos. Além do fato de que a liberdade de reproduzir vídeos em blocos esgotaria a bateria muito mais rápido, essa liberdade geral seria uma receita certa para o caos total. Sem dúvida, seria o contraponto para uma tela inicial estática completa, mas não muito agradável de se olhar! Os designers do Windows queriam uma tela inicial agradável de olhar mesmo por um longo período, por isso criaram uma experiência dinâmica e ativa, mas que também expressa uma ideia de unidade e harmonia em todos os blocos. Os modelos e as animações controladas pelo sistema fornecem uma certa uniformidade, mas também permitem um pouco de variação entre os aplicativos. E lembre-se de que você pode usar um modelo só de imagem e aplicar qualquer design que desejar, mas evite criar imagens como botões que sugerem diferentes comportamentos para diferentes partes do bloco que não possuem suporte.

As notificações do sistema aparecem na parte superior da tela inicial, na tela de bloqueio, na área de trabalho ou em qualquer aplicativo que estiver em execução. Tocar em uma notificação do sistema ativa o aplicativo associado com qualquer argumento que tenha sido especificado quando ela foi emitida. Uma notificação do sistema aparece na cor definida pelo manifesto do aplicativo associado e inclui o logotipo do aplicativo na parte inferior direita; a cor e o logotipo ajudam o usuário a identificar o aplicativo que será ativado quando ele tocar na notificação do sistema.

Assim como nos blocos, o layout de cada notificação do sistema é definido por um modelo do Catálogo de modelos de notificação, no qual as escolhas fornecem apenas opções de texto + imagem e somente texto. As notificações do sistema aparecem por um tempo e depois desaparecem, podem ser acompanhadas de som e se repetirem dentro de um lembrete de reunião.

As notificações do sistema aparecem por um tempo e depois desaparecem.

Na tela de bloqueio, a atividade do aplicativo é exibida junto com a data, a hora e as notificações do sistema. Como mostramos no exemplo a seguir, o conteúdo do aplicativo consiste em sete logotipos + notificações na parte inferior e uma atualização de texto ao lado da hora:

Este conteúdo de aplicativo inclui até 7 logotipos e notificações e uma atualização de texto ao lado da hora

O usuário controla o que aparece na tela de bloqueio em Configurações do Computador > Personalizar > Tela de Bloqueio, como mostramos no exemplo a seguir. Quando você toca em um quadrado na primeira linha, aparece uma lista de aplicativos habilitados para tela de bloqueio que aparecem como um logotipo e notificação. Na segunda linha, você pode escolher o aplicativo que fornece o texto detalhado. Esse texto é gerado especificamente da atualização de bloco mais recente para esse aplicativo.

Lista de aplicativos habilitados para tela de bloqueio

XML de atualização

Agora que vimos como o usuário experimenta o dinamismo, a próxima questão é: como exatamente são feitas essas atualizações? Quer dizer, o que caracteriza uma atualização de bloco, notificação ou notificação do sistema?

Em todos os casos, à exceção do que chamamos de notificações brutas, as atualizações são basicamente trechos de XML que o Windows pode processar para atualizar um bloco ou exibir uma notificação do sistema. As notificações brutas contêm texto específico do aplicativo ou dados binários. Um aplicativo ou tarefa em segundo plano que recebe essas notificações normalmente processa esses dados e, em resposta, emite atualizações de bloco, atualizações de notificação ou notificações do sistema.

Os modelos que estamos citando são apenas estruturas XML específicas para essas atualizações. Uma atualização de notificação, por exemplo, para o número 7, é semelhante à seguinte:

 <badge value="7"/>

Uma carga semelhante, como em geral são chamados esses trechos de XML, para a notificação de ponto vermelho no bloco inferior central que vimos anteriormente seria a seguinte.

 <badge value="busy"/>

A carga XML para esse mesmo bloco grande, que inclui uma referência à sua imagem e as opções de logotipo/nome, seria parecida com a seguinte (o URI da imagem é fictício), usando o modelo 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>

Nessa carga, você pode ver que identificamos o modelo dentro do elemento binding. O Windows valida o resto do XML conforme esse modelo. O atributo branding do elemento binding indica se será mostrado o logotipo, o nome do aplicativo ou nenhum. Os elementos filho de binding descrevem as outras partes necessárias do modelo.

O que é instrutivo agora, mais os modelos específicos para essas atualizações, é examinar o esquema XML geral, já que esses esquemas revelam funcionalidades adicionais que podem ser utilizadas com cada atualização. Isto é, o Catálogo de modelos de bloco, Catálogo de imagens de notificação e Catálogo de modelos de notificação do sistema só mostram os elementos necessários, o esquema, mas aparecem em todas as opções adicionais.

O esquema está documentado na seção Tile, toast, and badge schemas (Esquemas de bloco, de notificação do sistema e de notificação) da documentação. Entretanto, os detalhes aparecem em vários tópicos diferentes, por isso tentarei condensá-los aqui em um pseudoesquema que nos permita examinar as estruturas como um todo.

As atualizações de notificação são as mais simples, por isso começaremos por elas:

 <?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" />

Tecnicamente, toda carga XML deveria ter a marca de cabeçalho <?xml> ; o Windows funciona bem sem ela, mas eu gosto de incluí-la para que fique completo.

Depois, você pode ver que o elemento badge só contém um atributo value que pode ser um número (qualquer coisa maior que 99 é exibido como "99+") ou um conjunto de palavras predefinidas que identificam glifos específicos. Isso também está registrado na página O catálogo de imagens de notificação da documentação.

O único outro atributo é o opcional version (o ? depois do nome significa opcional), que permite alterações futuras no esquema. Como é opcional, você pode omiti-lo das suas cargas neste momento.

As atualizações de bloco têm o seguinte pseudoesquema:

 <?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>

No elemento visual, que contém atributos que se aplicam à atualização como um todo, vemos o atributo opcional version , que você também pode omitir agora. Os outros atributos são descritos a seguir:

Atributo

Descrição

lang

Uma cadeia de caracteres opcional da linguagem BCP-47 identificando a linguagem dos dados da atualização, como "en-US" ou "de-DE".

baseUri

Um URI opcional que precederá a todos os outros URIs na carga, permitindo que você omita essas informações redundantes ao construí-la. O padrão é "ms-appx:///".

branding

Indica se o logotipo do aplicativo será mostrado no bloco ("logo", o padrão), seu nome ("name") ou nada ("none").

addImageQuery

Se definido como "true" (o padrão é "false"), instrui o Windows a anexar parâmetros de consulta a toda solicitação feita a URIs na carga, isto é, a cada URI de imagem, para identificar a linguagem atual, o fator de escala e a configuração de contraste. O formato dos parâmetros é:

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

Para obter mais detalhes, consulte Globalização e acessibilidade de blocos e notificações do sistema.

Dentro de visual, a carga tem um ou mais elementos binding , um para cada tamanho de bloco. Quer dizer, uma única carga pode (e, de preferência, deve) conter uma atualização para os blocos quadrados e grandes simultaneamente, o que é importante porque o usuário pode alterar seu tamanho a qualquer momento. Se você omitir um dos tamanhos, nada aparecerá para essa atualização se o usuário definiu o bloco com esse tamanho específico. Observe, porém, que você pode enviar atualizações para os diferentes tamanhos separadamente, e o Windows manterá os dois.

Dentro de binding, você pode ver que template identifica o modelo XML para validar, e você vê os mesmos atributos que existem para visual exceto que eles se aplicam somente aos elementos desse binding (e sobrescrevem os de visual). O outro atributo é fallback, que identifica um modelo a ser usado se o modelo principal não puder ser encontrado. Isso é para uso futuro de compatibilidade com versões anteriores, para que não haja necessidade de usá-lo com o Windows 8.

Dentro de cada binding, então, existe uma combinação de elementos image e text dependendo do modelo, os atributos para cada um deles são, acredito, autoexplicativos ou já foram descritos. Observe que qualquer atributo em image ou text que também aparece em binding ou visual substitui os valores dos elementos pai, como é de se esperar.

Para notificações do sistema, temos uma estrutura semelhante aos blocos, mas com alguns recursos adicionais:

 <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>

Todos os atributos lang, baseUri, branding e addImageQuery dentro de visual têm o mesmo significado e padrões que possuem para blocos, assim como todos os atributos dentro dos atributos binding, image e text . Nessa parte da carga, então, a única verdadeira diferença entre uma atualização de bloco e uma notificação do sistema são os modelos com suporte.

O que diferencia uma carga de notificação do sistema são os atributos do elemento toast mais externo e seu filho opcional audio.

Com toast, é possível designar ao atributo launch uma cadeia de caracteres que será passada para o manipulador de ativação de aplicativos como argumentos, exatamente como acontece com um bloco secundário. O atributo duration pode ter valores de "short"(cinco segundos ou o valor em Configurações do computador > Facilidade de acesso) ou "long" (25 segundos ou o valor de Configurações do computador > Facilidade de acesso, o que for maior.

Em audio, o atributo src é uma cadeia de caracteres que indica um conjunto predefinido de sons como os encontrados no Catálogo de opções de áudio de notificações do sistema. No momento, você pode apenas escolher um desses sons, que realmente são mapeados para os sons de sistema que você configurou no Painel de Controle. Observação: se você desativar todos os sons, como normalmente eu faço, não ouvirá nada; lembre-se disso quando testar seu aplicativo! Essa limitação existe por vários motivos. Para começar, incluir sons personalizados de uma fonte remota geraria muito mais tráfego de rede, o que pode ser um problema se o dispositivo estiver na tela de bloqueio e tentar conservar energia no modo de espera conectado. Ela também evita um possível abuso, como a inclusão de anúncios de áudio com notificações do sistema.

Separadamente, o atributo silent, se definido como "true", sempre desativará o áudio. Quanto a loop, se o atributo duration das notificações do sistema for definido e você definir src do áudio como um dos quatro sons "Looping" do catálogo (cada um com duas variações em "alarm" e "call"), também poderá definir loop como "true" para repetir o som ou "false" para reproduzir o som apenas uma vez, que é o padrão.

Além do loop de áudio, também é possível agendar uma notificação do sistema recorrente. Isso não faz parte da carga XML; é algo que você indica ao criar um objeto ScheduledToastNotification. Nesses casos, a mesma carga (áudio e outras) aparecerá em cada intervalo.

Dinâmicos com atividade sem aplicativos em execução

Sabendo quais tipos de atualização as cargas XML gerarão, a próxima etapa é determinar como essas cargas chegarão ao sistema no tempo apropriado e como serão criadas. Esses tópicos foram discutidos nas postagens anteriores, Criando uma fantástica experiência com o bloco (parte 1) e Criando uma fantástica experiência com o bloco (parte 2), que mostram como gerar as cargas em código. Isso inclui o uso da biblioteca Notifications Extensions que é incluída com vários exemplos e também está disponível em um pacote NuGet do Visual Studio.

Aqui, vamos nos concentrar nos métodos de entrega dessas cargas. Há três maneiras pelas quais elas podem ser emitidas:

  1. Um aplicativo em execução ou uma tarefa em segundo plano de aplicativo pode emitir atualizações diretas ou locais. Elas podem ser imediatas ou agendadas para um momento no futuro. Blocos, notificações e notificações do sistema também podem ter um tempo de expiração após o qual elas são automaticamente removidas ou eliminadas do agendamento quando não são entregues naquele momento.

  2. Um aplicativo em execução pode dar ao Windows até cinco URIs para atualizações periódicas e especificar intervalos entre 30 minutos e um dia. Quando vários URIs são usados, cada um corresponde a um dos cinco slots na fila de atualização. Assim que uma atualização periódica é configurada, o Windows envia uma solicitação (HTTP GET) para o URI em cada intervalo. Se o Windows receber de volta uma carga válida, ele enviará a atualização para o bloco apropriado em nome do aplicativo, exatamente como se um aplicativo em execução o tivesse emitido diretamente. Veremos como criar serviços de atualização na parte 2 desta série.

    O principal benefício das atualizações periódicas é que as solicitações continuam mesmo quando o aplicativo não está em execução, permitindo que o bloco receba atualizações e notificações em andamento por um longo período sem o usuário iniciar o aplicativo. É claro que espero que suas atualizações sejam interessantes o bastante para encorajar o usuário a usar o seu aplicativo novamente!

  3. Um aplicativo pode solicitar um URI de canal dos Serviços de Notificação por Push do Windows (WNS) e enviá-lo para seus próprios serviços de back-end. Esses serviços podem então emitir atualizações específicas de qualquer tipo pelo URI de canal através do WNS, que por sua vez as enviará para o dispositivo específico, quando ele estiver online. O Windows recebe essas atualizações e as aplica ao bloco apropriado ou exibe a notificação do sistema. Alternadamente, um aplicativo pode configurar uma tarefa em segundo plano para receber essas notificações por push (o que é necessário para uma notificação bruta). Falaremos sobre notificações por push na parte 3 desta série.

A tabela a seguir resume essas opções e inclui o recurso de fila de blocos em ciclo e as funcionalidades de áudio/recorrência de notificações do sistema:

Tipo de notificação

Fila

Agendado

Expirando

Recorrente

Áudio

Periódico

Por push

Bloco

   

Notificação

   

   

Notificação do sistema

 

 

Bruto

           

É importante notar que tudo o que você vê aqui para blocos e notificações se aplica tanto aos blocos principais de um aplicativo quanto aos secundários. As postagens do blog mencionadas anteriormente fornecem os detalhes para blocos secundários. Você também pode consultar Secondary tiles sample (Exemplo de blocos secundários).

Falando de exemplos, aproveito também para indicar App tiles and badges sample (Exemplo de blocos e notificações de aplicativo), Scheduled notifications sample (Exemplo de notificações agendadas) e Push and periodic notifications client-side sample (Exemplo notificações periódicas e por push de cliente) para completar os exemplos de todos os diferentes cenários. Em qualquer trabalho de blocos e notificações no seu aplicativo, é importante reservar um tempo para familiarizar-se com o código desses exemplos.

Lembre-se sempre também de que as atualizações de bloco, notificação e notificação do sistema podem ser emitidas com tarefas em segundo plano. Gosto de pensar nas tarefas em segundo plano como uma forma de código de aplicativo que é executado mesmo quando o aplicativo está totalmente suspenso ou nem está na memória. A emissão de uma atualização com uma tarefa em segundo plano é feita com o mesmo código usado no aplicativo principal, por isso não há muita diferença.

As tarefas em segundo plano são ótimas para verificar o status de várias condições, o que pode ser feito rapidamente e respeita as cotas da CPU colocadas nessas tarefas. Quando as condições exigem, a tarefa em segundo plano pode gerar uma notificação apropriada. Na verdade, as principais ações de uma tarefa em segundo plano são: (a) emitir essas atualizações ou (b) salvar valores nas pastas AppData do aplicativo ou no contêiner de configurações que o aplicativo processará na próxima vez que for executado.

As tarefas em segundo plano também são essenciais para manipular notificações por push quando um aplicativo não está sendo executado, o que abordaremos novamente na parte 3.

Para obter mais informações sobre tarefas em segundo plano, consulte a postagem anterior deste blog, Ser produtivo no segundo plano, e uma visão mais geral Continuar produtivo quando seu aplicativo não está sendo exibido na tela.

E com isso, agora estamos prontos para sair do território conhecido dos aplicativos cliente e explorar a função dos serviços online com seus blocos, notificações e notificações do sistema, o que faremos nas partes 2 e 3.

Kraig Brockschmidt

Gerente de programas, equipe de ecossistema do Windows

Autor de Programming Windows 8 Apps in HTML, CSS, and JavaScript (Programando aplicativos do Windows 8 em HTML, CSS e JavaScript)