Este codelab faz parte do curso Android avançado no Kotlin. Você aproveitará mais o 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 avançados do Android em Kotlin (link em inglês).
Introdução
As notificações são mensagens mostradas ao usuário fora da IU do app. As notificações serão exibidas na parte superior 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 extensível e imagens.
As notificações podem apresentar material oportuno e podem ter botões que permitam ao usuário realizar 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.
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 imediatamente enquanto o app está em segundo plano. Use as notificações com moderação. Isso não só respeita os usuários, mas também torna mais provável que a notificação do seu app receba a atenção que ele merece.
Neste codelab, você 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. Especificamente, trabalhe com o SDK do Android.
- Como arquitetar apps usando os Componentes da arquitetura e a vinculação de dados.
- Entendimento básico de BroadcastReceivers
- Entendimento básico do AlarmManager
O que você vai aprender
- Como criar, definir o estilo 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 exibir ícones de notificação no ícone do app.
Atividades do laboratório
- Adicione uma notificação ao app inicial.
- Cancele a notificação que você enviou.
- Crie canais para diferentes tipos de notificações.
- Personalize as notificações no app inicial.
- Adicione ações rápidas para tornar a notificação interativa.
- Desative os selos de notificação.
Cozinhar ovos é simples, mas pode ser uma tarefa desafiadora se você não monitorar o tempo. Neste codelab, você trabalhará em um app de timer de ovo e será perfeito, assim como seus ovos futuros. Você começará com um app de timer de ovo funcional que permite ao usuário definir diferentes configurações de tempo de cozimento para diferentes estilos de ovos. O timer fará a contagem regressiva do intervalo de tempo selecionado e exibirá uma mensagem de aviso quando os ovos estiverem prontos.
Pode parecer funcional, mas está longe de ser perfeito e de não ser fácil de usar. Para começar, a mensagem de aviso é mostrada apenas por um breve período e, portanto, é fácil de esquecer. Além disso, se o aplicativo não estiver em primeiro plano ou o dispositivo estiver bloqueado, não haverá um indicador visual para o status do timer quando a mensagem de aviso desaparecer.
O ideal é que o timer do ovo use notificações para informar aos usuários quando o tempo se esgotar. O usuário precisa saber que os ovos estão prontos de outra forma, caso contrário, eles serão preparados! As notificações são visuais, podem incluir sons e podem fazer o dispositivo vibrar. Isso é tudo que chama a atenção do usuário. Assim, você pode alcançar ovos perfeitos e usuários satisfeitos e bem alimentados.
Para fazer o download do app de exemplo:
Clone o repositório do GitHub e mude para a ramificação starter.
$ git clone https://github.com/googlecodelabs/android-kotlin-notifications
Como alternativa, é possível fazer o download do repositório como um arquivo ZIP, descompactá-lo e abri-lo no Android Studio.
- Abra e execute o app no Android Studio.
Você verá uma imagem de ovo e um menu suspenso com uma lista de intervalos de tempo predefinidos para cozinhar um ovo. Clique no triângulo do menu suspenso Soft Boiled. 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 interruptor que inicia o timer do ovo. Você pode usar este interruptor para iniciar e parar o timer de quando quiser. O código inicial é totalmente funcional, o que significa que você pode configurar o timer do ovo e observar a contagem como 0. Quando o timer terminar, uma mensagem de aviso será exibida, conforme mostrado abaixo.
- Inspecionar o código-fonte. O app inicial consiste em uma única atividade chamada
MainActivity
. Há três subpacotes com o nomereceiver
,ui
eutil
.
- /receiver: o pacote
receiver
contém dois broadcast receivers chamadosAlarmReceiver
eSnoozeReceiver
.AlarmReceiver
é acionado peloAlarmManager
para enviar a notificação quando o timer definido pelo usuário estiver ativo.SnoozeReceiver
gerencia o clique do usuário para adiar a notificação. - /ui: contém a
EggTimerFragment
, que faz parte da parte da IU 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.
BindingUtils.kt
tem adaptadores de vinculação para ativar a vinculação de dados entre a IU do app e oViewModel
.NotificationUtils.kt
tem métodos de extensão naNotificationManager
.
O uso de notificações é uma ótima maneira de chamar a atenção dos usuários para o app. Se o app não estiver em execução ou em primeiro plano, uma notificação mostrará uma janela pop-up na parte superior da tela e pode incluir som ou vibração. Para criar uma notificação, é necessário usar um criador de notificações e fornecer um texto de título, um texto de conteúdo e um ícone. Quando o builder tiver todos os campos necessários, o NotificationManager
, que é um serviço do sistema, ajuda a exibir esse conteúdo como uma notificação. O NotificationManager
é responsável por enviar uma notificação, atualizar seu conteúdo e cancelá-la. Nas etapas a seguir, você adicionará métodos de extensão a NotificationManager
. Dessa forma, sempre que você precisar usar NotificationManager
, poderá usar as funções de extensão para ter 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 localizeTODO: Step 1.1
. Neste codelab, você encontrará o código correspondente do app e todo o conteúdo correspondente. - Examina a função
sendNotification()
especificada. Você estenderá essa função de extensão para oNotificationManager
para 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 aplicativo e um ID do canal. O ID do canal é um valor de string do canal.
Canais de notificação são uma forma de agrupar notificações. Ao agrupar tipos semelhantes de notificações, os desenvolvedores e usuários podem controlar todas as notificações no canal. Depois de ser criado, o 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 de notificação para representar seu app, um título e o texto do conteúdo da mensagem que você quer transmitir ao usuário. Você verá mais opções para personalizar ainda mais as notificações no codelab, mas essa é a quantidade mínima de dados que precisam ser definidas 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, é necessário chamar
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 essa notificação. Como seu app terá apenas uma notificação ativa por vez, você pode usar o mesmo ID para todas elas. Você já recebe uma constante para essa finalidade chamada NOTIFICATION_ID
em NotificationUtils.kt
. Observe que você pode chamar diretamente notify()
porque 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 localize a funçãostartTimer()
. Essa função cria um alarme com o intervalo de tempo selecionado quando o usuário ativa o timer do ovo. - Você 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
. ONotificationManager
é um serviço do sistema que oferece todas as funções expostas para a API de notificações, incluindo a função de extensão adicionada. Sempre que você quiser enviar, cancelar ou atualizar uma notificação, precisará solicitar uma instância doNotificationManager
ao 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)
Quase lá. No entanto, se você executar o app agora e definir o timer, não receberá uma notificação.
- Abra o arquivo
logcat
e pesquise"No Channel found"
. Você verá uma mensagem de erro informando queegg_channel
não existe. Nas etapas a seguir, você aprenderá mais sobre os canais de notificação e corrigirá esse problema.
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 no ícone do app na tela de início e mantê-lo pressionado, selecione as informações do app e toque em notificações para ver uma lista de canais de notificação associados ao app. Neste momento, a lista está vazia porque seu app não criou nenhum canal.
Os canais representam um tipo de notificação; por exemplo, o timer do ovo pode enviar uma notificação quando o ovo estiver cozido, além de usar outro canal para enviar notificações diárias para lembrá-lo de ter ovos com seu café da manhã. Todas as notificações de um canal são agrupadas, e os usuários podem definir as configurações de notificação para um canal inteiro. Isso permite que os usuários personalizem as configurações de notificação com base no tipo de notificação em que estão interessados. Por exemplo, os usuários podem desativar as notificações de café da manhã, mas ainda optarem por vê-las no timer.
Os desenvolvedores definem as configurações iniciais, a importância e o comportamento para serem aplicadas a todas as notificações em um canal. Depois que você definir as configurações iniciais, os usuários poderão substituí-las.
Na Etapa 1.1, você usou o egg_notification_channel_id
como seu canal de notificação. Portanto, agora você precisa criar e personalizar as configurações e o comportamento desse canal.
- Abra
EggTimerFragment.kt
e localize 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 verão na tela Configurações.
- Como o ú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. Assim, você pode usar o
NotificationManag
er.IMPORTANCE_LOW
. - No objeto
notificationChannel
, definaenableLights
como verdadeiro. Esta configuração ativará as luzes quando uma notificação for exibida. - No objeto
notificationChannel
, definalightColor
como vermelho para exibir uma luz vermelha quando uma notificação for exibida. - No objeto
notificationChannel
, definaenableVibration
como verdadeiro 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, é preciso chamar 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 procurar o ID e o nome do seu canal nos recursos de string que já estão 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)
)
- Você precisa transmitir o ID do canal ao criador de notificações. Você já fez isso na Etapa 1.2. Definir um valor errado como ID do canal fará com que a notificação falhe. Abra
NotificationUtils.kt
para verificar se o ID do canal que você definiu 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. Você verá uma notificação sempre que iniciar o timer.
- Puxe a barra de status e observe que o título, o conteúdo e o ícone da notificação são os mesmos que você definiu nas etapas anteriores.
- Para verificar o canal recém-criado, feche o app e encontre o ícone dele. Toque no ícone do app e o mantenha pressionado e selecione Informações do app.
- Selecione Notificações na lista de configurações. Você verá um novo canal chamado Egg abaixo da configuração Mostrar notificações.
Quando você executa o app, a notificação agora é exibida. Você como desenvolvedor de apps e seus usuários podem personalizar as configurações e o comportamento de todas as notificações enviadas neste 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 de notificações, mas enviar uma notificação logo depois de iniciar o timer não faz muito sentido. Os usuários provavelmente preferem receber uma notificação quando o ovo estiver pronto. Na parte a seguir do codelab, você corrigirá isso e mudará a mensagem de aviso para uma notificação.
Você já enviou a notificação e observou como ela é exibida para os usuários, mas este é apenas o primeiro passo para criar notificações incríveis. Nesta etapa, você mudará a notificação para ser enviada no horário mais apropriado.
Seu app usa o AlarmManager
para configurar um alarme. O código relacionado a AlarmManager
já é fornecido no código inicial e usado para mostrar a mensagem de aviso. AlarmManager
monitora a seleção de horário desejada e aciona a função onReceive()
de AlarmReceiver.kt
quando o tempo termina. Se você abrir o AlarmReceiver.kt
e navegar para o onReceive()
, verá a mensagem de aviso exibida sempre que 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
)
- Como alternativa, remova o aviso, já que o app enviará uma notificação quando o timer chegar ao fim.
// 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ê verá uma notificação sempre que iniciar o timer e sempre que ele acabar.
Isso não é o ideal. Você não quer enviar muitas notificações para seus usuários. Você pode remover a primeira notificação enviada quando o usuário inicia o timer.
- Abra
EggTimerFragment.kt
e remova o código da 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ê verá uma notificação. Essa é uma notificação muito mais útil.
Etapa 4: adicionar uma intent de conteúdo
- Execute o app novamente, caso ele ainda não esteja em execução.
- Clique na notificação. Nada acontecerá.
É ótimo mostrar a notificação e informar o usuário, mas quando ele clica em uma, ele volta para o app correspondente. Nesta parte do codelab, você adicionará uma intent à notificação para redirecioná-lo à tela do timer.
Um Intent
é um objeto de mensagem que pode ser usado para solicitar uma ação de outro componente do app. Intents podem ser usadas para iniciar atividades, serviços ou transmissões. Nesse caso, você usa essa intent para instruir o sistema a abrir o app MainActivity
quando o usuário tocar na notificação. Como seu app consiste em apenas uma visualização, não há muitas opções. No entanto, em um app maior, a notificação deve criar uma experiência perfeita, levando o usuário a uma tela que faz sentido quando ele interage com ela.
- Abra
NotificationUtils.kt
e localize a função de extensãosendNotification()
. - Crie uma
Intent
com seuapplicationContext
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 é exibida fora do app. Para que uma intent funcione fora do app, crie uma nova PendingIntent
.
PendingIntent
concede direitos a outro aplicativo ou ao sistema para realizar uma operação em nome do seu app. Uma PendingIntent
em si é simplesmente uma referência a um token mantido pelo sistema, descrevendo os dados originais usados para recuperá-los. Isso significa que, mesmo que o processo do aplicativo proprietário seja eliminado, o próprio PendingIntent
permanecerá utilizável em relação a outros processos a que foi fornecido. Nesse caso, o sistema usará a intent pendente para abrir o app em seu nome, independentemente de ele estar ou não em execução.
- Crie um
PendingIntent
comapplicationContext
,NOTIFICATION_ID
, ocontentIntent
que você criou na etapa anterior e a sinalizaçãoPendingIntent
. A sinalizaçãoPendingIntent
especifica a opção de criar um novoPendingIntent
ou usar um existente. Você precisa definirPendingIntent.FLAG_UPDATE_CURRENT
como a sinalização, porque não quer criar uma nova notificação se já houver uma. Dessa forma, você modificará oPendingIntent
atual associado à intent que 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 fazer isso, chamesetContentIntent()
naNotificationBuilder
. Agora, quando você clicar na notificação, oPendingIntent
será acionado, abrindo seuMainActivity
. - Defina também
setAutoCancel()
comotrue
, para que, quando o usuário tocar na notificação, ela seja dispensada enquanto a leve ao 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 ser exibida.
- Depois de ver a notificação, clique nela para ver a barra de status e observe como o app é colocado em primeiro plano.
Etapa 5: cancelar a notificação
Você tem um timer de ovo funcional com notificações, mas há um pequeno problema. Se você definir o timer, receber uma notificação e defini-lo novamente, a notificação anterior 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, é necessário limpar a notificação anterior ao iniciar um novo timer. Para começar, crie outra função de extensão no NotificationUtils.kt
. NotificationManager
tem uma API para cancelar todas as notificações ativas chamadas cancelAll
()
.
- Abra o
NotificationsUtil.kt
- Adicione uma função de extensão em
NotificationManager
que chamecancelAll()
.
// 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()
. - No método
startTimer()
, acesse 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 estilizem as notificações conforme necessário. Nesta tarefa, você aprenderá a personalizar as notificações do timer do ovo.
Etapa 1: definir o estilo da notificação
A estilização da notificação de acordo com suas necessidades e o conteúdo dela fará com que as notificações se destaquem e se pareçam com uma extensão do seu aplicativo. O framework de notificação vem com vários estilos integrados para ajudar. Você também pode criar seus próprios estilos.
NotificationCompat
oferece estilos integrados para:
BigTextStyle
, que pode exibir um grande bloco de texto, como mostrar o conteúdo de um e-mail quando expandido.BigPictureStyle
, que mostra notificações em formato grande que incluem um anexo de imagem grande.InboxStyle
, que mostra um conteúdo de texto em estilo de conversa.MediaStyle
, que mostra controles para a reprodução de mídia.MessagingStyle
, que mostra notificações em formato grande que incluem várias mensagens entre diversas pessoas.
Veja mais informações sobre outros estilos na documentação Criar uma notificação expansível. Nesta etapa, você usará o NotificationCompat.BigPictureStyle
para criar uma notificação expansível que mostra uma imagem de ovo grande quando expandida.
- Abra
NotificationUtils.kt
e localize a funçãosendNotification()
. - Comece carregando uma imagem de
resources
usando aBitmapFactory
.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
- Crie uma nova
BigPictureStyle
e defina sua imagem. - Defina o
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
. Assim, a imagem será 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 está no estado recolhido na gaveta de notificações. Se você expandir a notificação, uma imagem grande será exibida na área de notificação estendida.
Etapa 2: ações da notificação
As ações de notificação são outra personalização que pode ser adicionada às suas notificações. No momento, as notificações são redirecionadas para seu app quando os usuários clicam nelas. Além dessa ação padrão de notificação, é possível adicionar botões de ação que concluam 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 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()
. A diferença é que, em vez de iniciar uma atividade, você pode fazer várias outras ações, 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á recebeu um BoadcastReceiver
chamado SnoozeReceiver
. Você usará o SnoozeReceiver
para receber o clique do usuário na ação de notificação. Nas etapas a seguir, você 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 soneca. Quando a ação de soneca for clicada, o SnoozeReceiver
receberá uma intent e criará um novo alarme para enviar uma nova notificação após 60 segundos.
- Abra o
SnoozeReceiver.kt
Essa classe é semelhante àAlarmReceiver
que você usou anteriormente. Nas etapas a seguir, você adicionará um código que acionará a funçãoonReceive()
doSnoozeReceiver
. Em resumo, o código emSnoozeReceiver
criará um novo alarme para enviar uma nova notificação um minuto depois. Role a tela até a parte inferior 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 aSnoozeReceiver
logo após o estilo na funçãosendNotification()
. - Crie uma intent pendente chamando o método
getBroadcast()
naPendingIntent
, que espera os parâmetros nas etapas a seguir. EstePendingIntent
será usado pelo sistema para configurar um novo alarme para postar uma nova notificação após 60 segundos quando o botão de soneca for tocado pelo usuário. - O primeiro parâmetro é o contexto do aplicativo em que o
PendingIntent
precisa iniciar a atividade. - O segundo parâmetro é o código da solicitação da intent pendente. Se você precisar atualizar ou cancelar essa intent pendente, será necessário usar este código para acessá-la.
- Em seguida, adicione o objeto
snoozeIntent
, que é a intent da atividade que será iniciada. - Por fim, adicione o valor da sinalização
#FLAG_ONE_SHOT
, porque a intent será usada apenas uma vez. A ação rápida e a notificação desaparecerão após o primeiro toque. É por isso que 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 precisa de um ícone e um texto para descrever a ação para o usuário. Você também precisa adicionar osnoozeIntent
. Essa intent será usada para acionar oboadcastReceiver
correto quando sua ação receber um clique.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
R.drawable.egg_icon,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
- Execute o app timer do ovo para testar a ação de soneca.
- Execute o timer e coloque o app em segundo plano. Quando o timer acabar, expanda a notificação para mostrar que o botão de soneca está suspenso por mais um minuto.
Etapa 3: importância das notificações
A importância determina o quanto a notificação deve interromper o usuário visual e audível. As notificações com maior importância serão mais interruptivas para os usuários.
Especifique o nível de importância no construtor do NotificationChannel
. Originalmente, você definiu uma importância baixa para o app de timer do ovo. É possível usar um dos cinco níveis de importância, variando de IMPORTANCE_NONE(0)
a IMPORTANCE_HIGH(4)
. O nível de importância atribuído a um canal se aplica a todas as mensagens de notificação que você posta 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 informações básicas (exibida na parte superior da tela). | ||
Emite um som | ||
Sem som | IMPORTANCE_LOW (em inglês) | |
Não emite som e não aparece na barra de status | IMPORTANCE_MIN (em inglês) | PRIORITY_MIN (em inglês) |
Para mais informações sobre como escolher um nível adequado de prioridade, consulte "Índices de prioridade" no guia de design para notificações. Tenha cuidado ao selecionar um nível de importância para as notificações no seu app. A importância do canal precisa 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 produzir um alarme desnecessário e causar distração. Os usuários têm controle total sobre a importância das notificações. Portanto, se você criar uma notificação irritante, ele poderá desativar completamente seu canal de notificações.
Quando você criou a notificação na Etapa 1.6, o timer do ovo foi definido para enviar notificações com baixa prioridade, já que ele foi projetado para não incomodar o usuário com notificações. No entanto, talvez seja uma boa ideia chamar a atenção do usuário antes do cozimento do ovo. Para mudar o nível de importância da notificação, acesse as configurações do canal. A importância do canal afeta o nível de interrupção de todas as notificações postadas no canal, e precisa ser especificada no construtor NotificationChannel
.
- Para mudar o nível de importância do canal de notificações do app, abra
EggTimerFragment.kt
e navegue atécreateChannel()
. 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 (nível 25 da API) ou versões anteriores, você também precisa chamar setPriority()
para cada notificação usando uma constante de prioridade da classe NotificationCompat
.
- Abra
NotificationUtils.kt
e adicione o código a seguir ao objeto do builder 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, clique 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 serão alteradas, e isso não resultará em nenhuma mudança de comportamento quando a notificação for postada.
- Execute o app novamente e inicie o timer. Desta vez, quando a notificação for enviada, você verá um pop-up na parte superior da tela, independente do app estar sendo executado em primeiro ou segundo plano.
Etapa 4: selos de notificação
Os selos de notificação são pequenos pontos que aparecem no ícone na tela de início do app associado quando o app tem uma notificação ativa. Os usuários podem tocar no ícone do app e mantê-lo pressionado para ver as notificações.
Esses pontos, chamados de selos, são exibidos por padrão e não há nada que seu app precise fazer. No entanto, pode haver situações em que os selos não façam sentido para suas notificações, portanto, você pode desativá-los por canal chamando setShowBadge(false)
no seu objeto NotificationChannel
. Como o timer do ovo tem apenas uma notificação ativa por vez, o ícone no ícone do app não oferece muito benefícios aos usuários. Nas etapas a seguir, você desativará o ícone e mostrará uma notificação apenas para o timer de ovo.
- Adicione
setShowBadge(false)
ao código de criação do canal para que o timer de ovo desative os selos.
// EggTimerFragment.kt
).apply {
// TODO: Step 2.6 disable badges for this channel
setShowBadge(false)
}
- Execute o app novamente, inicie o timer e veja o ícone dele. Você não verá nenhum ícone no ícone do app.
O código da solução está na ramificação mestre do código transferido por download.
- Use a classe NotificationManager para criar, enviar, atualizar e cancelar uma notificação usando.
- 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 selos.
- Estilizar suas notificações usando estilos que se estendem de Notification.Style
- Definir o nível de importância com NotificationChannel.setImportance()
Curso da Udacity:
- Como desenvolver apps Android com Kotlin (link em inglês)
Documentação do desenvolvedor Android:
Para ver links de outros codelabs neste curso, consulte a página de destino dos codelabs avançados no Android.