Etapa 3: adicionar alarmes e notificações

Nesta etapa, você vai aprender:

  • Como ativar o app em intervalos especificados para executar tarefas em segundo plano.
  • Como usar as notificações na tela para chamar a atenção para algo importante.

Tempo estimado para concluir esta etapa: 20 minutos. Para visualizar o que você concluirá nesta etapa, acesse a parte inferior desta página ↓.

Melhore seu app Todo com lembretes

Aprimore o app Todo adicionando funcionalidades para lembrar o usuário se ele tiver tarefas abertas, mesmo quando o app estiver fechado.

Primeiro, você precisa adicionar uma maneira de o app verificar regularmente se há tarefas não finalizadas. Em seguida, o app precisa mostrar uma mensagem para o usuário, mesmo que a janela do app Todo esteja fechada. Para isso, você precisa entender como os alarmes e as notificações funcionam nos Aplicativos do Google Chrome.

Adicionar alarmes

Use chrome.alarms para definir um intervalo de ativação. Enquanto o Chrome estiver em execução, o listener do alarme é chamado aproximadamente no intervalo definido.

Atualizar as permissões de aplicativos

Em manifest.json, solicite a permissão "alarms":

"permissions": ["storage", "alarms"],

Atualizar scripts em segundo plano

Em background.js, adicione um listener onAlarm. Por enquanto, a função de callback só vai registrar uma mensagem para o Console sempre que houver um item de tarefa:

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', {
    id: 'main',
    bounds: { width: 620, height: 500 }
  });
});
chrome.alarms.onAlarm.addListener(function( alarm ) {
  console.log("Got an alarm!", alarm);
});

Atualizar visualização HTML

Em index.html, adicione um botão Ativar alarme:

<footer id="info">
  <button id="toggleAlarm">Activate alarm</button>
  ...
</footer>

Agora você precisa escrever o manipulador de eventos JavaScript para esse novo botão. Lembre-se da Etapa 2 que uma das não conformidades mais comuns de CSP é causada pelo JavaScript inline. Em index.html, adicione este para importar um novo arquivo alarms.js que você criará na etapa seguinte:

  </footer>
  ...
  <script src="js/app.js"></script>
  <script src="js/alarms.js"></script>
</body>

Criar script de alarmes

Crie um novo arquivo na pasta js com o nome alarms.js.

Use o código abaixo para adicionar checkAlarm(), createAlarm(), cancelAlarm() e toggleAlarm() , junto com um manipulador de eventos de clique para alternar o alarme quando o botão Ativar alarme for clicado.

(function () {
  'use strict';
   var alarmName = 'remindme';
   function checkAlarm(callback) {
     chrome.alarms.getAll(function(alarms) {
       var hasAlarm = alarms.some(function(a) {
         return a.name == alarmName;
       });
       var newLabel;
       if (hasAlarm) {
         newLabel = 'Cancel alarm';
       } else {
         newLabel = 'Activate alarm';
       }
       document.getElementById('toggleAlarm').innerText = newLabel;
       if (callback) callback(hasAlarm);
     })
   }
   function createAlarm() {
     chrome.alarms.create(alarmName, {
       delayInMinutes: 0.1, periodInMinutes: 0.1});
   }
   function cancelAlarm() {
     chrome.alarms.clear(alarmName);
   }
   function doToggleAlarm() {
     checkAlarm( function(hasAlarm) {
       if (hasAlarm) {
         cancelAlarm();
       } else {
         createAlarm();
       }
       checkAlarm();
     });
   }
  $$('#toggleAlarm').addEventListener('click', doToggleAlarm);
  checkAlarm();
})();

Atualize seu app e aguarde alguns instantes para ativar (e desativar) o alarme.

Inspecionar mensagens da página de segundo plano

Sempre que o alarme estiver ativado, você verá mensagens de registro impressas no console sempre que o alarme "tocar":

Mensagens de alarme sendo impressas no console

Você vai notar que:

  • Mesmo quando você fecha a janela do app Todo, os alarmes continuam chegando.
  • Em outras plataformas que não o ChromeOS, se você fechar completamente todas as instâncias do navegador Chrome, alarmes não serão acionadas.

Vamos examinar algumas partes em alarms.js que usam métodos chrome.alarms, um por um.

Criar alarmes

Em createAlarm(), use a API chrome.alarms.create() para criar um alarme quando Ativar alarme for ativado.

chrome.alarms.create(alarmName, {delayInMinutes: 0.1, periodInMinutes: 0.1});

O primeiro parâmetro é uma string opcional que identifica um nome exclusivo para seu alarme, por exemplo, remindme: Observação: é necessário definir um nome de alarme para que seja possível cancelá-lo por nome.

O segundo parâmetro é um objeto alarmInfo. As propriedades válidas para alarmInfo incluem when ou delayInMinutes e periodInMinutes. Para reduzir a carga na máquina do usuário, o Chrome limita os alarmes a uma vez por minuto. Estamos usando valores pequenos (0,1 de minuto) aqui para demonstração para fins específicos.

Limpar alarmes

No cancelAlarm(), use a API chrome.alarms.clear() para cancelar um alarme quando a opção Cancelar alarme for ativado.

chrome.alarms.clear(alarmName);

O primeiro parâmetro deve ser a string de identificação que você usou como nome do alarme chrome.alarms.create():

O segundo parâmetro (opcional) é uma função de retorno de chamada que deve assumir o formato:

function(boolean wasCleared) {...};

Receber alarmes

No checkAlarm(), use a API chrome.alarms.getAll() para receber uma matriz de todos os alarmes criados. para atualizar o estado da interface do botão ativar.

getAll() aceita uma função de callback que transmite uma matriz de objetos Alarm. Para acessar o que tem um Alarm, você pode inspecionar alarmes em execução no Console do DevTools da seguinte maneira:

chrome.alarms.getAll(function(alarms) {
  console.log(alarms);
  console.log(alarms[0]);
});

Isso vai gerar um objeto como {name: "remindme", periodInMinutes: 0.1, scheduledTime: 1397587981166.858}, conforme mostrado abaixo:

Usar getAll() para inspecionar alarmes em execução.

Prepare-se para a próxima seção

Agora que os alarmes estão prontos para consultar o app em intervalos regulares, use isso como base para adicionar notificações visuais.

Adicionar notificações

Vamos mudar a notificação de alarme para algo que o usuário possa notar facilmente. Usar chrome.notifications para mostrar uma notificação na área de trabalho como esta:

Notificação do app Todo

Quando o usuário clica na notificação, a janela do app Todo aparece.

Atualizar as permissões de aplicativos

Em manifest.json, solicite a permissão "notifications":

"permissions": ["storage", "alarms", "notifications"],

Atualizar scripts em segundo plano

Em background.js, refatore o callback chrome.app.window.create() em um método autônomo. para que você possa reutilizá-lo:

chrome.app.runtime.onLaunched.addListener(function() {
function launch() {
  chrome.app.window.create('index.html', {
    id: 'main',
    bounds: { width: 620, height: 500 }
  });
}
});
chrome.app.runtime.onLaunched.addListener(launch);
...

Atualizar listener de alarme

Na parte superior de background.js, adicione uma variável para o nome do banco de dados usado no alarme ouvinte:

var dbName = 'todos-vanillajs';

O valor de dbName é o mesmo nome de banco de dados definido na linha 17 do js/app.js:

var todo = new Todo('todos-vanillajs');

Criar uma notificação

Em vez de apenas registrar um novo alarme no console, atualize o listener onAlarm para que ele seja armazenado. usando chrome.storage.local.get() e chame um método showNotification():

chrome.alarms.onAlarm.addListener(function( alarm ) {
  console.log("Got an alarm!", alarm);
  chrome.storage.local.get(dbName, showNotification);
});

Adicione este método showNotification() a background.js:

function launch(){
  ...
}

function showNotification(storedData) {
  var openTodos = 0;
  if ( storedData[dbName].todos ) {
    storedData[dbName].todos.forEach(function(todo) {
      if ( !todo.completed ) {
        openTodos++;
      }
    });
  }
  if (openTodos>0) {
    // Now create the notification
    chrome.notifications.create('reminder', {
        type: 'basic',
        iconUrl: 'icon_128.png',
        title: 'Don\'t forget!',
        message: 'You have '+openTodos+' things to do. Wake up, dude!'
     }, function(notificationId) {});
  }
}

chrome.app.runtime.onLaunched.addListener(launch);
...

showNotification() vai verificar se há itens de tarefas abertos (não concluídos). Se houver pelo menos um item de lista de tarefas, crie um pop-up de notificação em chrome.notifications.create().

O primeiro parâmetro é um nome de notificação de identificação exclusiva. É necessário ter um ID definido no pedido para limpar ou processar interações com essa notificação específica. Se o ID corresponder a um ID o create() limpa essa notificação antes de fazer outra.

O segundo parâmetro é um objeto NotificationOptions. Há muitas opções de renderização o pop-up de notificação. Aqui, estamos usando uma com um ícone, um título e uma mensagem. Outros tipos de notificação incluem imagens, listas e indicadores de progresso. Sinta-se à vontade para retornar a esta quando concluir a Etapa 3 e teste outros recursos de notificação.

O terceiro parâmetro (opcional) é um método de callback que precisa assumir o formato:

function(string notificationId) {...};

Processar interações de notificação

Abra o app Todo quando o usuário clicar na notificação. No final de background.js, crie Manipulador de eventos do chrome.notifications.onClicked:

chrome.notifications.onClicked.addListener(function() {
  launch();
});

O callback do manipulador de eventos simplesmente chama o método launch(). chrome.app.window.create() ou cria uma nova janela de aplicativo do Google Chrome, caso ainda não exista uma, ou coloca em foco a janela atual janela aberta com o ID da janela main.

Iniciar o app Todo concluído

Você concluiu a Etapa 3! Atualize o app Todo agora com lembretes.

Verifique se estes comportamentos funcionam como esperado:

  • Se você não tem itens de tarefas não concluídos, não há notificações pop-up.
  • Se você clicar na notificação quando o app for fechado, o app Todo vai abrir ou entrar em foco.

Solução de problemas

O arquivo background.js final deve ficar assim. Se as notificações não estiverem aparecendo, Confirme se a versão do Google Chrome é a 28 ou superior. Se mesmo assim as notificações não forem exibidas, verifique o mensagens de erro no Console do DevTools na janela principal (clique com o botão direito do mouse > Inspecionar elemento) e a página de plano de fundo (clique com o botão direito do mouse > Inspecionar página de plano de fundo).

Mais informações

Para informações mais detalhadas sobre algumas das APIs introduzidas nesta etapa, consulte:

Tudo pronto para passar para a próxima etapa? Vá para a Etapa 4: abrir links externos com um WebView »