Nesta etapa, você vai aprender:
- Como ativar seu 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 ter uma prévia do que você vai concluir nesta etapa, pule até o final desta página ↓.
Melhore seu app Todo com lembretes
Melhore o app Todo adicionando uma funcionalidade para lembrar o usuário se ele tiver tarefas abertas, mesmo quando o app estiver fechado.
Primeiro, você precisa adicionar uma maneira para que o app verifique regularmente se há tarefas não concluídas. Em seguida, o app precisa mostrar uma mensagem para o usuário, mesmo que a janela do app Todo esteja fechada. Para fazer isso, você precisa entender como os alarmes e notificações funcionam nos apps do Chrome.
Adicionar alarmes
Use chrome.alarms
para definir um intervalo de ativação. Enquanto o Chrome estiver em execução, o listener de alarme
será chamado aproximadamente no intervalo definido.
Atualizar as permissões de aplicativos
No 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 registrará apenas uma mensagem no Console sempre que houver um item de lista de tarefas:
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 criar o manipulador de eventos JavaScript para esse novo botão. Lembre-se da Etapa 2 que uma das não conformidades mais comuns da CSP é causada pelo JavaScript in-line. Em index.html, adicione esta linha para importar um novo arquivo alarms.js que você criará na seguinte etapa:
</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 os métodos checkAlarm()
, createAlarm()
, cancelAlarm()
e toggleAlarm()
, 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 o app e ative (e desative) o alarme por alguns instantes.
.Sempre que o alarme estiver ativado, você vai ver mensagens de registro impressas no console toda vez que o alarme "tocar":
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, os alarmes não serão acionados.
Vamos analisar algumas das partes em alarms.js que usam métodos chrome.alarms
, um a um.
Criar alarmes
Em createAlarm()
, use a API chrome.alarms.create()
para criar um alarme quando a opção Ativar
alarme for ativada.
chrome.alarms.create(alarmName, {delayInMinutes: 0.1, periodInMinutes: 0.1});
O primeiro parâmetro é uma string opcional que identifica um nome exclusivo para o alarme, por exemplo,
remindme
. (Observação: é necessário definir um nome de alarme para poder cancelá-lo pelo 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 um minuto) apenas para fins de
demonstração.
Limpar alarmes
Em cancelAlarm()
, use a API chrome.alarms.clear()
para cancelar um alarme quando a opção Cancelar
alarme estiver ativada.
chrome.alarms.clear(alarmName);
O primeiro parâmetro precisa ser a string de identificação que você usou como nome de alarme em
chrome.alarms.create()
.
O segundo parâmetro (opcional) é uma função de callback que precisa seguir o formato:
function(boolean wasCleared) {...};
Receber alarmes
Em checkAlarm()
, use a API chrome.alarms.getAll()
para acessar uma matriz de todos os alarmes criados
e atualizar o estado do botão de ativação na interface.
getAll()
aceita uma função de callback que transmite uma matriz de objetos Alarm
. Para ver o que há em uma
Alarm
, você pode inspecionar os alarmes em execução no Console do DevTools desta forma:
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:
Prepare-se para a próxima seção
Agora que os alarmes estão configurados para pesquisar o app em intervalos regulares, use isso como base para adicionar notificações visuais.
Adicionar notificações
Vamos alterar a notificação de alarme para algo que o usuário possa notar facilmente. Use
chrome.notifications
para mostrar uma notificação na área de trabalho como a abaixo:
Quando o usuário clica na notificação, a janela do app Todo deve ser exibida.
Atualizar as permissões de aplicativos
No 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 seja possível 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 alarmes
Na parte superior do background.js, adicione uma variável para um nome de banco de dados usado no listener de alarmes:
var dbName = 'todos-vanillajs';
O valor de dbName
é o mesmo nome de banco de dados definido na linha 17 de js/app.js:
var todo = new Todo('todos-vanillajs');
Criar uma notificação
Em vez de simplesmente registrar um novo alarme no Console, atualize o listener onAlarm
para receber dados armazenados
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);
...
O showNotification()
vai verificar se há itens abertos (não concluídos). Se houver pelo menos um item de tarefas
abertos, crie um pop-up de notificação usando o chrome.notifications.create()
.
O primeiro parâmetro é um nome de notificação de identificação exclusiva. Você precisa ter um ID definido para
limpar ou processar interações com essa notificação específica. Se o ID corresponder a uma notificação
existente, o create()
limpará essa notificação antes de criar uma nova.
O segundo parâmetro é um objeto NotificationOptions
. Há muitas opções para renderizar
o pop-up de notificação. Aqui, estamos usando uma notificação "básica" com um ícone, um título e uma mensagem.
Outros tipos de notificação incluem imagens, listas e indicadores de progresso. Volte a esta
seção quando concluir a Etapa 3 e teste outros recursos de notificação.
O terceiro parâmetro (opcional) é um método de callback que precisa seguir o formato:
function(string notificationId) {...};
Gerenciar interações de notificação
Abrir o app Todo quando o usuário clicar na notificação. No final de background.js, crie um manipulador de eventos 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()
cria
uma nova janela de apps do Chrome, se ainda não existir, ou coloca o foco na janela
aberta no momento que tem o ID de 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 conforme o esperado:
- Se você não tiver nenhum item do Google Atividades não concluído, não vai haver notificações pop-up.
- Se você clicar na notificação quando o app for fechado, o app Todo será aberto ou entrará em foco.
Solução de problemas
Seu arquivo background.js final terá esta aparência. Se as notificações não estiverem aparecendo, confirme se a versão do Chrome é a 28 ou mais recente. Se as notificações ainda não aparecerem, verifique se há mensagens de erro no Console do DevTools na janela principal (clique com o botão direito do mouse > Inspecionar elemento) e na página de fundo (clique com o botão direito do mouse > Inspect Background Page).
Mais informações
Para informações mais detalhadas sobre algumas das APIs introduzidas nesta etapa, consulte:
- Declarar permissões ↑
- chrome.alarms ↑
- chrome.alarms.onAlarm ↑
- chrome.alarms.create() ↑
- chrome.alarms.clear() ↑
- chrome.alarms.getAll() ↑
- chrome.notifications ↑
- chrome.notifications.create() ↑
- NotificationOptions ↑
- chrome.notifications.onClicked ↑
Tudo pronto para passar à próxima etapa? Vá para a Etapa 4: abrir links externos com um WebView »