Este codelab faz parte do curso Android avançado no Kotlin. Você vai aproveitar mais este curso se fizer os codelabs em sequência, mas isso não é obrigatório. Todos os codelabs do curso estão listados na página de destino dos codelabs do Android avançado em Kotlin.
Introdução
As notificações são mensagens mostradas ao usuário fora da interface do app. As notificações são mostradas na parte de cima da tela se o dispositivo estiver desbloqueado ou, dependendo das configurações de segurança, na tela de bloqueio quando o dispositivo estiver bloqueado.
Uma notificação típica consiste em um título, uma descrição e um ícone. Uma notificação também pode ter ações clicáveis, uma resposta rápida, conteúdo expansível e imagens.
As notificações podem entregar material oportuno e ter botões para permitir que o usuário realize ações rápidas, como enviar uma resposta ou adiar um alarme. Ao clicar em uma notificação, o usuário é direcionado a uma visualização no app relacionada ao conteúdo da notificação.
As notificações são uma maneira útil de lembrar os usuários de uma tarefa importante, informar que algo aconteceu ou comunicar informações importantes que eles precisam imediatamente enquanto o app está em segundo plano. Use as notificações com moderação. Além de respeitar os usuários, isso aumenta a probabilidade de a notificação do app receber a atenção que merece.
Neste codelab, você vai aprender a criar e usar notificações em um app Android.
O que você já precisa saber
Você precisa:
- Como criar apps Android em Kotlin. Em especial, trabalhe com o SDK do Android.
- Como arquitetar apps usando os componentes de arquitetura e a vinculação de dados.
- Noções básicas sobre BroadcastReceivers
- Conhecimentos básicos sobre o AlarmManager
O que você vai aprender
- Como criar, estilizar e enviar uma notificação.
- Como cancelar notificações.
- Como criar canais de notificação.
- Como adicionar ações rápidas às notificações.
- Como mostrar ícones de notificação no ícone do app.
Atividades deste laboratório
- Adicione uma notificação ao app inicial.
- Cancele a notificação enviada anteriormente.
- Crie canais para diferentes tipos de notificações.
- Personalize as notificações no app inicial.
- Adicione ações rápidas para tornar sua notificação interativa.
- Desative os ícones de notificação.
Cozinhar ovos é simples, mas pode ser uma tarefa difícil se você não acompanhar o tempo. Neste codelab, você vai trabalhar em um app de timer de ovos e deixá-lo perfeito, assim como seus futuros ovos. Você vai começar com um app de cronômetro de ovos funcional que permite ao usuário definir diferentes configurações de tempo de cozimento para diferentes estilos de ovos. O timer faz uma contagem regressiva do intervalo de tempo selecionado e mostra uma mensagem de aviso quando os ovos estão prontos.
Isso pode parecer funcional, mas está longe de ser perfeito e não é muito fácil de usar. Para começar, a mensagem de toast é mostrada apenas por um breve período e, portanto, é fácil de perder. Além disso, se o app não estiver em primeiro plano ou o dispositivo estiver bloqueado, não haverá um indicador visual do status do timer depois que a mensagem de toast desaparecer.
O ideal é que o timer use notificações para avisar os usuários quando o tempo acabar. O usuário precisa saber imediatamente se os ovos estão prontos, caso contrário, eles vão ficar cozidos demais. As notificações são visuais, podem incluir sons e fazer o dispositivo vibrar. Tudo isso para chamar a atenção do usuário. Assim, você pode fazer ovos perfeitos e deixar os usuários felizes e bem alimentados.
Para fazer o download do app de exemplo, você pode:
Clone o repositório do GitHub e mude para a ramificação starter.
$ git clone https://github.com/googlecodelabs/android-kotlin-notifications
Se preferir, você pode fazer o download do repositório como um arquivo ZIP, descompactar e abrir no Android Studio.
- Abra e execute o app no Android Studio.
Você vai ver uma imagem de um ovo e um menu suspenso com uma lista de intervalos de tempo predefinidos para cozinhar um ovo. Clique no triângulo do menu suspenso Ovo cozido. A primeira opção da lista é fornecida para fins de teste e define o alarme para apenas 10 segundos. Ao lado da lista, há um botão que inicia o cronômetro de ovos. Use essa chave para iniciar e parar o timer de ovos quando quiser. O código inicial é totalmente funcional. Isso significa que você pode configurar o timer de ovo e assistir a contagem regressiva até zero. Quando o timer termina, uma mensagem curta é exibida, como mostrado abaixo.
- Inspecione o código-fonte. O app inicial consiste em uma única atividade chamada
MainActivity
. Há três subpacotes chamadosreceiver
,ui
eutil
.
- /receiver: o pacote
receiver
contém dois broadcast receivers chamadosAlarmReceiver
eSnoozeReceiver
. OAlarmReceiver
é acionado peloAlarmManager
para enviar a notificação quando o timer definido pelo usuário termina. OSnoozeReceiver
processa o clique do usuário para adiar a notificação. - /ui: contém o
EggTimerFragment
, que faz parte da porção de UI do app. OEggTimerViewModel
é responsável por iniciar e cancelar o timer e por outras tarefas do app relacionadas ao ciclo de vida. - /util: neste pacote, há dois arquivos. O
BindingUtils.kt
tem adaptadores de vinculação para ativar a vinculação de dados entre a interface do app e oViewModel
.NotificationUtils.kt
tem métodos de extensão noNotificationManager
.
Usar notificações é uma ótima maneira de chamar a atenção dos usuários para seu app. Não importa se o app está em execução ou não, uma notificação vai mostrar uma janela pop-up na parte de cima da tela e pode incluir som ou vibração. Para criar uma notificação, use um criador de notificações e forneça um texto de título, um texto de conteúdo e um ícone. Quando o builder tem todos os campos necessários, o NotificationManager
, que é um serviço do sistema, ajuda você a mostrar esse conteúdo como uma notificação. O NotificationManager
é responsável por enviar uma notificação, atualizar o conteúdo dela e cancelar a notificação. Nas etapas a seguir, você vai adicionar métodos de extensão a NotificationManager
. Assim, sempre que você precisar usar NotificationManager
, poderá usar essas funções de extensão para alcançar a funcionalidade necessária.
Etapa 1: criar uma notificação básica
Nesta tarefa, você vai criar uma notificação, definir uma mensagem para o usuário e enviar a notificação.
- Abra a classe
NotificationUtils.kt
e encontreTODO: Step 1.1
. Você vai encontrar tarefas correspondentes neste codelab e no código do app. - Examine a função
sendNotification()
fornecida. Você vai estender essa função de extensão paraNotificationManager
e enviar notificações.
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
* Builds and delivers a notification.
*
* @param messageBody, notification text.
* @param context, activity context.
*/
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
- Receba uma instância do criador de notificações, transmita o contexto do app e um ID do canal. O ID do canal é um valor de string para o canal.
Os canais de notificação são uma forma de agrupar notificações. Ao agrupar tipos semelhantes de notificações, desenvolvedores e usuários podem controlar todas as notificações no canal. Depois de criado, um canal pode ser usado para enviar qualquer número de notificações.
//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
applicationContext,
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Defina o ícone da notificação para representar seu app, um título e o texto do conteúdo da mensagem que você quer enviar ao usuário. Você vai encontrar mais opções para personalizar sua notificação no codelab, mas essa é a quantidade mínima de dados necessária para enviar uma notificação.
//NotificationUtils.kt
// TODO: Step 1.3 set title, text and icon to builder
.setSmallIcon(R.drawable.cooked_egg)
.setContentTitle(applicationContext.getString(R.string.notification_title))
.setContentText(messageBody)
- Em seguida, chame
notify()
com um ID exclusivo para sua notificação e com o objetoNotification
do builder.
Esse ID representa a instância de notificação atual e é necessário para atualizar ou cancelar a notificação. Como o app terá apenas uma notificação ativa por vez, você pode usar o mesmo ID para todas as notificações. Você já tem uma constante para essa finalidade chamada NOTIFICATION_ID
em NotificationUtils.kt
. É possível chamar notify()
diretamente porque você está fazendo a chamada de uma função de extensão na mesma classe.
//NotificationUtils.kt
// TODO: Step 1.4 call notify to send the notification
// Deliver the notification
notify(NOTIFICATION_ID, builder.build())
- Abra
ui/EggTimerViewModel.kt
e encontre a funçãostartTimer()
. Essa função cria um alarme com o intervalo de tempo selecionado quando o usuário ativa o cronômetro de ovos. - Você vai acionar uma notificação nessa função quando o usuário iniciar o timer. Para chamar a função
sendNotification()
implementada anteriormente, você precisa de uma instância deNotificationManager
.NotificationManager
é um serviço do sistema que fornece todas as funções expostas para a API Notifications, incluindo a função de extensão que você adicionou. Sempre que você quiser enviar, cancelar ou atualizar uma notificação, será necessário solicitar uma instância doNotificationManager
do sistema. Chame a funçãosendNotification()|
com a mensagem de notificação e o contexto.
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager
// and call sendNotification
val notificationManager = ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(app.getString(R.string.timer_running), app)
Falta pouco. No entanto, se você executar o app agora e definir o timer, não vai receber uma notificação.
- Abra
logcat
e pesquise"No Channel found"
. Você vai ver uma mensagem de erro informando que oegg_channel
não existe. Nas etapas a seguir, você vai saber mais sobre canais de notificação e corrigir isso.
Etapa 2: canais de notificação
A partir do nível 26 da API, todas as notificações precisam ser atribuídas a um canal. Se você tocar e pressionar o ícone do iniciador de apps, selecionar informações do app e tocar em notificações, vai aparecer uma lista de canais de notificação associados ao app. No momento, a lista está vazia porque o app não criou nenhum canal.
Os canais representam um "tipo" de notificação. Por exemplo, o timer de ovo pode enviar uma notificação quando o ovo estiver cozido e usar outro canal para enviar notificações diárias para lembrar você de comer ovos no café da manhã. Todas as notificações em um canal são agrupadas, e os usuários podem configurar as notificações de um canal inteiro. Assim, os usuários podem personalizar as configurações de notificação com base no tipo de notificação que interessa a eles. Por exemplo, os usuários podem desativar as notificações do café da manhã, mas ainda escolher ver as notificações do timer.
Os desenvolvedores definem as configurações iniciais, a importância e o comportamento a serem aplicados a todas as notificações em um canal. Depois de definir as configurações iniciais, os usuários podem substituir essas configurações.
Na etapa 1.1, você usou egg_notification_channel_id
como canal de notificação. Agora, é preciso criar e personalizar as configurações e o comportamento de notificação desse canal.
- Abra
EggTimerFragment.kt
e encontre a funçãocreateChannel()
. - Transmita o ID exclusivo do canal para o construtor de
NotificationChannel
. - Transmita o nome do canal de notificação, que os usuários também vão ver na tela Configurações.
- Como último parâmetro, transmita o nível de importância do canal de notificação. Os níveis de importância serão abordados mais adiante neste codelab. Por enquanto, use
NotificationManag
er.IMPORTANCE_LOW
. - No objeto
notificationChannel
, definaenableLights
como "true". Essa configuração vai acender as luzes quando uma notificação for mostrada. - No objeto
notificationChannel
, definalightColor
como vermelho para mostrar uma luz vermelha quando uma notificação for exibida. - No objeto
notificationChannel
, definaenableVibration
como "true" para ativar a vibração. - No objeto
notificationChannel
, defina a descrição do canal como‘Time for breakf
ast'. - Para receber uma instância de
NotificationManager
, chamegetSystemService()
. - Chame
createNotificationChannel()
emNotificationManager
e transmita o objetonotificationChannel
que você criou na etapa anterior.
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
// TODO: Step 1.6 START create a channel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_LOW
)
// TODO: Step 2.6 disable badges for this channel
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.description = "Time for breakfast"
val notificationManager = requireActivity().getSystemService(
NotificationManager::class.java
)
notificationManager.createNotificationChannel(notificationChannel)
}
// TODO: Step 1.6 END create channel
}
- Em seguida, para criar um canal, chame a função
createChannel()
que você acabou de escrever (etapa 1.7). Essa função usa dois parâmetros: o ID e o nome do canal. Você precisa pesquisar o ID e o nome do canal nos recursos de string já fornecidos no projeto.
// EggTimerFragment.kt
// TODO: Step 1.7 call createChannel
createChannel(
getString(R.string.egg_notification_channel_id),
getString(R.string.egg_notification_channel_name)
)
- É preciso transmitir o ID do canal para o criador de notificações. Você já fez isso na etapa 1.2. Definir um valor errado como ID do canal vai fazer com que a notificação falhe. Abra
NotificationUtils.kt
para verificar se o ID do canal definido anteriormente está correto.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
applicationContext,
// TODO: Step 1.8 verify the notification channel name
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Execute o app. Ele vai enviar uma notificação sempre que você iniciar o timer.
- Puxe a barra de status e observe que o título, o conteúdo e o ícone da notificação estão como você os definiu nas etapas anteriores.
- Para verificar o canal recém-criado, feche o app e encontre o ícone dele. Toque e mantenha pressionado o ícone do app e selecione Informações do app.
- Selecione Notificações na lista de configurações. Um novo canal chamado Ovo vai aparecer logo abaixo da configuração Mostrar notificações.
Quando você executa o app, a notificação é mostrada. Você, como desenvolvedor de apps, e seus usuários podem personalizar as configurações e o comportamento de todas as notificações enviadas nesse canal. Parabéns, você criou uma notificação!
Etapa 3: adicionar notificações ao app
Até agora, isso mostra o uso básico da API Notifications, mas enviar uma notificação logo após iniciar o timer não faz muito sentido. Os usuários provavelmente preferem receber uma notificação quando o ovo estiver pronto. Na próxima parte do codelab, você vai corrigir isso e mudar a mensagem de toast para uma notificação.
Você já enviou a notificação e observou como ela é mostrada aos usuários, mas essa foi apenas a primeira etapa para criar notificações incríveis. Nesta etapa, você vai mudar a notificação para ser enviada em um horário mais adequado.
O app usa AlarmManager
para configurar um alarme. O código relacionado a AlarmManager
já está no código inicial e é usado para mostrar a mensagem de aviso. O AlarmManager
acompanha a seleção de tempo desejada e aciona a função onReceive()
do AlarmReceiver.kt
quando o tempo acaba. Se você abrir AlarmReceiver.kt
e navegar até onReceive()
, vai ver a mensagem de toast exibida sempre que você configurar um timer de ovo.
- Abra
AlarmReceiver.kt
, uma instância deNotificationManager
, e chame a funçãosendNotification()
com o texto da mensagem e os parâmetros de contexto.
// AlarmReceiver.kt
// TODO: Step 1.9 add call to sendNotification
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(
context.getText(R.string.eggs_ready).toString(),
context
)
- Se quiser, remova o toast, já que o app vai enviar uma notificação quando o timer terminar.
// AlarmReceiver.kt
// TODO: Step 1.10 [Optional] remove toast
// Toast.makeText(
// context,
// context.getText(R.string.eggs_ready),
// Toast.LENGTH_SHORT
// ).show()
- Execute o app . Você vai receber uma notificação sempre que iniciar e quando o timer terminar.
Isso não é o ideal. Não envie muitas notificações aos usuários. Você pode remover a primeira notificação, que é enviada quando o usuário inicia o timer.
- Abra
EggTimerFragment.kt
e remova o código de notificação da etapa 1.5.
// EggTimeViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
// app,
// NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
- Execute o app novamente.
- Defina um timer, coloque-o em segundo plano e aguarde o tempo terminar. Você vai receber uma notificação. Essa é uma notificação muito mais útil.
Etapa 4: adicionar uma intent de conteúdo
- Execute o app novamente, se ele ainda não estiver em execução.
- Clique na notificação. Nada acontece!
Mostrar a notificação e informar o usuário é ótimo, mas quando ele clica em uma notificação, espera voltar ao app correspondente. Nesta parte do codelab, você vai adicionar uma intent à notificação para trazer o usuário de volta à tela do timer.
Uma Intent
é um objeto de mensagem que pode ser usado para solicitar uma ação de outro componente de app. Os intents podem ser usados para iniciar uma atividade, um serviço ou entregar uma transmissão. Nesse caso, use essa intent para informar ao sistema que abra MainActivity
quando o usuário tocar na notificação. Como seu app consiste em apenas uma visualização, você não tem muitas opções aqui. No entanto, em um app maior, a notificação deve criar uma experiência perfeita, levando o usuário a uma tela que faça sentido quando ele interagir com a notificação.
- Abra
NotificationUtils.kt
e encontre a função de extensãosendNotification()
. - Crie uma
Intent
com suaapplicationContext
e a atividade a ser iniciada,MainActivity::class.java
.
// NotificationUtils.kt
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
// Create the content intent for the notification, which launches
// this activity
// TODO: Step 1.11 create intent
val contentIntent = Intent(applicationContext, MainActivity::class.java)
Você criou a intent, mas a notificação é mostrada fora do app. Para que uma intent funcione fora do app, é necessário criar um novo PendingIntent
.
PendingIntent
concede direitos a outro aplicativo ou ao sistema para realizar uma operação em nome do seu aplicativo. Um PendingIntent
é simplesmente uma referência a um token mantido pelo sistema que descreve os dados originais usados para recuperá-lo. Isso significa que, mesmo que o processo do aplicativo proprietário seja encerrado, o próprio PendingIntent
vai continuar utilizável em outros processos a que foi atribuído. Nesse caso, o sistema vai usar a intent pendente para abrir o app em seu nome, independente de o app de timer estar em execução ou não.
- Crie um
PendingIntent
comapplicationContext
,NOTIFICATION_ID
, ocontentIntent
que você criou na etapa anterior e a flagPendingIntent
. A flagPendingIntent
especifica a opção de criar um novoPendingIntent
ou usar um já existente. Você precisa definirPendingIntent.FLAG_UPDATE_CURRENT
como a flag, já que não quer criar uma nova notificação se já houver uma. Assim, você vai modificar oPendingIntent
atual, que está associado à intent que você está fornecendo.
// NotificationUtils.kt
// TODO: Step 1.12 create PendingIntent
val contentPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_ID,
contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
- Transmita o
PendingIntent
para sua notificação. Para isso, chamesetContentIntent()
naNotificationBuilder
. Agora, quando você clicar na notificação, oPendingIntent
será acionado, abrindo oMainActivity
. - Defina também
setAutoCancel()
comotrue
para que, quando o usuário tocar na notificação, ela seja dispensada automaticamente ao direcionar para o app.
// NotificationUtils.kt
// TODO: Step 1.13 set content intent
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
- Execute o app novamente.
- Defina um timer, coloque o app em segundo plano e aguarde a notificação aparecer.
- Quando a notificação aparecer, clique nela puxando a barra de status para baixo e observe como o app é colocado em primeiro plano.
Etapa 5: cancelar a notificação
Você tem um cronômetro de ovos funcional com notificações, mas há um pequeno problema. Se você definir o timer, receber uma notificação e definir o timer novamente, a notificação anterior vai permanecer na barra de status enquanto o novo timer estiver em execução. Isso pode confundir o usuário se o app estiver em segundo plano e resultar em ovos mal cozidos.
Para corrigir isso, limpe a notificação anterior ao iniciar um novo timer. Comece criando outra função de extensão no NotificationUtils.kt
. O NotificationManager
tem uma API para cancelar todas as notificações ativas chamada cancelAll
()
.
- Abra
NotificationsUtil.kt
. - Adicione uma função de extensão em
NotificationManager
que chamacancelAll()
.
// NotificationUtils.kt
// TODO: Step 1.14 Cancel all notifications
/**
* Cancels all notifications.
*
*/
fun NotificationManager.cancelNotifications() {
cancelAll()
}
- Abra
EggTimerViewModel.kt
e navegue até a funçãostartTimer()
. - Em
startTimer()
, receba uma instância doNotificationManager
do sistema e chamecancelNotifications()
.
// EggTimerViewModel.kt
//TODO Step 1.15 call cancel notification
val notificationManager =
ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelNotifications()
- Execute o app e inicie o timer.
- Depois de ver a notificação, inicie o timer novamente e observe como nosso app exclui automaticamente a notificação anterior da barra de status.
O framework de notificações oferece várias opções de personalização para que os desenvolvedores definam ações personalizadas e estilizar as notificações conforme necessário. Nesta tarefa, você vai aprender a personalizar as notificações do seu cronômetro de ovos.
Etapa 1: estilizar sua notificação
Ao estilizar a notificação de acordo com suas necessidades e o conteúdo dela, você a destaca e faz com que ela pareça mais uma extensão do seu aplicativo. O framework de notificação vem com vários estilos integrados para ajudar, e você sempre pode criar o seu próprio.
O NotificationCompat
oferece estilos integrados para:
BigTextStyle
, que pode mostrar um grande bloco de texto, como o conteúdo de um e-mail quando expandido.BigPictureStyle
, que mostra notificações em formato grande com um anexo de imagem grande.InboxStyle
, que mostra um conteúdo de texto em estilo de conversa.MediaStyle
, que mostra controles para reprodução de mídia.MessagingStyle
, que mostra notificações em formato grande com várias mensagens entre qualquer número de pessoas.
Para mais informações sobre outros estilos, consulte a documentação Criar uma notificação expansível. Nesta etapa, você vai usar NotificationCompat.BigPictureStyle
para criar uma notificação expansível que mostra uma imagem grande de um ovo quando expandida.
- Abra
NotificationUtils.kt
e encontre a funçãosendNotification()
. - Comece carregando uma imagem de
resources
usando oBitmapFactory
.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
- Crie um novo
BigPictureStyle
e defina sua imagem. - Defina
bigLargeIcon()
comonull
para que o ícone grande desapareça quando a notificação for expandida.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
.bigPicture(eggImage)
.bigLargeIcon(null)
- Defina o estilo com
setStyle()
comobigPicStyle
. - Defina o ícone grande com
setLargeIcon()
comoeggImage
para que a imagem seja exibida como um ícone menor quando a notificação for recolhida.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
- Execute o app e defina um timer. Quando a notificação é mostrada pela primeira vez, ela fica recolhida na gaveta de notificações. Se você expandir a notificação, uma imagem grande será mostrada na área de notificação estendida.
Etapa 2: ações de notificação
As ações de notificação são outra personalização que você pode adicionar às notificações. No momento, suas notificações redirecionam para o app quando os usuários clicam nelas. Além dessa ação de notificação padrão, você pode adicionar botões de ação que executam uma tarefa relacionada ao app a partir da notificação.
Uma notificação pode oferecer até três botões de ação que permitem ao usuário responder rapidamente, como adiar um lembrete ou responder a uma mensagem de texto. Esses botões de ação não podem duplicar a ação realizada quando o usuário toca na notificação.
Para adicionar um botão de ação, transmita um PendingIntent
para a função addAction()
no builder. Isso é semelhante a configurar a ação de toque padrão da notificação chamando setContentIntent()
, exceto que, em vez de iniciar uma atividade, você pode fazer várias outras coisas, por exemplo, iniciar um BroadcastReceiver
que execute um job em segundo plano para que a ação não interrompa o app que já está aberto.
Neste codelab, você já tem um BoadcastReceiver
chamado SnoozeReceiver
. Você vai usar SnoozeReceiver
para receber o clique do usuário na ação de notificação. Nas etapas a seguir, você vai adicionar um código para adiar a notificação do timer de ovo por 60 segundos quando o usuário clicar no botão de ação de adiamento. Quando a ação de adiar é clicada, o SnoozeReceiver
recebe uma intent e cria um novo alarme para enviar uma nova notificação após 60 segundos.
- Abra
SnoozeReceiver.kt
. Essa classe é semelhante àAlarmReceiver
, que você usou antes. Nas etapas a seguir, você vai adicionar um código que vai acionar a funçãoonReceive()
doSnoozeReceiver
. Em resumo, o código emSnoozeReceiver
vai criar um novo alarme para enviar uma nova notificação um minuto depois. Role para baixo até a parte de baixo da função onReceive, receba uma instância de notificationManager do sistema e chame cancelAll.
// SnoozeReceiver.kt
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelAll()
- Para usar
SnoozeReceiver
, abraNotificationUtils.kt
. - Crie um novo
Intent
snoozeIntent
para oSnoozeReceiver
logo após o estilo na funçãosendNotification()
. - Crie uma intent pendente chamando o método
getBroadcast()
emPendingIntent
, que espera os parâmetros nas etapas a seguir. EssePendingIntent
será usado pelo sistema para configurar um novo alarme e postar uma notificação após 60 segundos quando o botão de adiamento for tocado pelo usuário. - O primeiro parâmetro é o contexto do aplicativo em que esse
PendingIntent
deve iniciar a atividade. - O segundo parâmetro é o código da solicitação, que é o código da intent pendente. Se você precisar atualizar ou cancelar essa intent pendente, use esse código para acessar a intent.
- Em seguida, adicione o objeto
snoozeIntent
, que é a intent da atividade a ser iniciada. - Por fim, adicione o valor da flag
#FLAG_ONE_SHOT
, já que a intent será usada apenas uma vez. A ação rápida e a notificação desaparecem após o primeiro toque. Por isso, a intent só pode ser usada uma vez.
// NotificationUtils.kt
// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
applicationContext,
REQUEST_CODE,
snoozeIntent,
FLAGS
)
- Em seguida, chame a função
addAction()
nonotificationBuilder
. Essa função espera um ícone e um texto para descrever sua ação ao usuário. Também é necessário adicionar osnoozeIntent
. Esse intent será usado para acionar oboadcastReceiver
correto quando a ação for clicada.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
R.drawable.egg_icon,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
- Execute o app de marcação de tempo para testar a ação de adiar.
- Inicie o timer e coloque o app em segundo plano. Quando o timer terminar, abra a notificação. Ela terá um botão de ação de adiamento que adia o timer por mais um minuto.
Etapa 3: importância da notificação
A importância determina o nível em que a notificação pode interromper o usuário visual e sonoramente. As notificações mais importantes causam mais interrupções aos usuários.
Especifique o nível de importância no construtor NotificationChannel
. Você definiu originalmente uma importância baixa para o app de contagem regressiva. É possível usar um dos cinco níveis de importância, que variam de IMPORTANCE_NONE(0)
a IMPORTANCE_HIGH(4)
. O nível de importância que você atribui a um canal é válido para todas as mensagens de notificação que você publica nele.
Níveis de importância do canal
Nível de importância visível para o usuário | Importância (Android 8.0 e versões mais recentes) | Prioridade (Android 7.1 e versões anteriores) |
Emite um som e aparece como uma notificação de alerta (aparece na parte de cima da tela). | ||
Emite um som | ||
Sem som | ||
Não emite som e não aparece na barra de status |
Para mais informações sobre como escolher um nível adequado de prioridade, consulte "Priority levels" (Níveis de prioridade) no Guia de criação de notificações (em inglês). Tenha cuidado ao selecionar um nível de importância para as notificações no seu app. A importância do canal deve ser escolhida considerando o tempo e a atenção do usuário. Quando uma notificação sem importância é disfarçada como urgente, ela pode causar alarme desnecessário e distrair. Os usuários têm controle total sobre o nível de importância das notificações. Portanto, se você criar uma notificação irritante, eles poderão desativar completamente o canal de notificação.
Quando você criou a notificação na etapa 1.6, o cronômetro de ovos foi definido para enviar notificações com baixa prioridade, já que foi projetado para não incomodar o usuário com notificações. No entanto, é recomendável chamar a atenção do usuário antes que o ovo cozinhe demais. Para mudar o nível de importância da notificação, comece pelas configurações do canal. A importância do canal afeta o nível de interrupção de todas as notificações publicadas nele e precisa ser especificada no construtor NotificationChannel
.
- Para mudar o nível de importância do canal de notificação do seu app, abra
EggTimerFragment.kt
e acessecreateChannel()
. Mude o nível de importância deIMPORTANCE_LOW
paraIMPORTANCE_HIGH
.
// EggTimerFragment.kt
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_HIGH
)
Para oferecer compatibilidade com dispositivos com o Android 7.1 (API de nível 25) ou versão anterior, também é preciso chamar setPriority()
para cada notificação, usando uma constante de prioridade da classe NotificationCompat
.
- Abra
NotificationUtils.kt
e adicione o seguinte ao objeto de criação de notificações.
// NotificationUtils.kt
.addAction(
R.drawable.common_google_signin_btn_icon_dark,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
// TODO: Step 2.5 set priority
.setPriority(NotificationCompat.PRIORITY_HIGH)
- Antes de executar o app, toque e mantenha pressionado o ícone dele no dispositivo ou emulador e selecione "Desinstalar" para limpar as configurações anteriores do canal. Se você não desinstalar o app, as configurações de prioridade do canal não vão mudar, e não haverá mudança de comportamento quando a notificação for postada.
- Agora execute o app novamente e inicie o timer. Desta vez, quando a notificação for entregue, um pop-up vai aparecer na parte de cima da tela, independente de o app estar em primeiro ou segundo plano.
Etapa 4: ícones de notificação
Os indicadores de notificação são pequenos pontos que aparecem no ícone da tela de início do app associado quando ele tem uma notificação ativa. Os usuários podem tocar no ícone do app e mantê-lo pressionado para exibir as notificações.
Esses pontos, chamados de indicadores, aparecem por padrão, e não há nada que seu app precise fazer. No entanto, pode haver situações em que os indicadores não fazem sentido para suas notificações. Sendo assim, você pode desativá-los por canal chamando setShowBadge(false)
no objeto NotificationChannel
. Como o timer de ovo tem apenas uma notificação ativa por vez, o ícone do app não oferece muitos benefícios para os usuários. Nas etapas a seguir, você vai desativar o ícone e mostrar apenas uma notificação para o cronômetro de ovos.
- Adicione
setShowBadge(false)
ao código de criação do canal para desativar os selos.
// EggTimerFragment.kt
).apply {
// TODO: Step 2.6 disable badges for this channel
setShowBadge(false)
}
- Execute o app de novo, inicie o timer e observe o ícone do app. Nenhum selo vai aparecer no ícone do app.
O código da solução está na ramificação principal do código baixado.
- Use a classe NotificationManager para criar, enviar, atualizar e cancelar uma notificação.
- Use um objeto NotificationChannel com o método createNotificationChannel para definir um canal para a notificação.
- Use addAction() para adicionar ações rápidas a uma notificação.
- Use setShowBadge() para ativar ou desativar os selos.
- Mude o estilo das notificações usando estilos que se estendem de Notification.Style.
- Defina o nível de importância com NotificationChannel.setImportance().
Curso da Udacity:
Documentação do desenvolvedor Android:
Para acessar links de outros codelabs deste curso, consulte a página inicial dos codelabs do curso Android avançado no Kotlin.