Este tutorial faz parte do curso Android avançado em Kotlin. Você obterá o máximo valor deste curso se trabalhar com os tutoriais em sequência, mas isso não é obrigatório. Todos os tutoriais do curso estão listados na página de destino Android avançado em Kotlin.

Introdução

Notificações são mensagens mostradas ao usuário fora da IU do seu aplicativo. As notificações são mostradas 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 entregar material oportuno e podem ter botões para permitir que o usuário execute ações rápidas, como enviar uma resposta ou adiar um alarme. Clicar em uma notificação leva o usuário a uma vista em seu aplicativo relacionada ao conteúdo da notificação.

As notificações são uma forma útil de lembrar os usuários de uma tarefa importante, informá-los de que algo aconteceu ou comunicar informações importantes de que precisam imediatamente enquanto o aplicativo está em segundo plano. Use as notificações com moderação. Isso não apenas respeita os usuários, mas também torna mais provável que a notificação do seu aplicativo receba a atenção que merece.

Neste tutorial, você aprenderá como criar e usar notificações em um aplicativo Android.

O que você já deveria saber

Você deve estar familiarizado com:

O que você aprenderá

O que você vai fazer

Cozinhar ovos é simples, mas pode ser uma tarefa desafiadora se você não conseguir controlar o tempo. Neste tutorial, você trabalhará em um aplicativo de cronômetro de ovo e o tornará perfeito, assim como seus futuros ovos. Você começará com um aplicativo de cronômetro de ovo que permite ao usuário definir diferentes configurações de tempo de cozimento para diferentes estilos de ovo. O cronômetro faz a contagem regressiva a partir do intervalo de tempo selecionado e exibe uma mensagem de torrada quando os ovos estão prontos.

Isso pode parecer funcional, mas está longe de ser perfeito e não é muito amigável. Para começar, a mensagem brinde é exibida apenas por um breve período de tempo e, portanto, é fácil de perder. Além disso, se o aplicativo não estiver em primeiro plano ou o dispositivo estiver bloqueado, não haverá nenhum indicador visual para o status do temporizador depois que a mensagem do sistema desaparecer.

Idealmente, o cronômetro deve usar notificações para avisar aos usuários quando o tempo acabar. O usuário realmente precisa saber que os ovos estão prontos imediatamente, caso contrário, eles ficarão cozidos demais! As notificações são visuais, podem incluir sons e podem fazer o dispositivo vibrar - todas as formas de chamar a atenção do usuário! Desta forma, você pode obter ovos perfeitos e usuários felizes e bem alimentados.

Para obter o aplicativo de amostra, você pode:

Clone o repositório do GitHub e mude para o branch starter.

$ git clone https://github.com/googletutoriais/android-kotlin-notifications


Alternativamente, você pode baixar o repositório como um arquivo Zip, descompactá-lo e abri-lo no Android Studio.

Baixe o Zip

  1. Abra e execute o aplicativo 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 para o menu suspenso Soft Boiled. A primeira opção na lista é fornecida para fins de teste e define o alarme para apenas 10 segundos. Ao lado da lista há um interruptor que liga o cronômetro. Você pode usar essa opção para iniciar e parar o cronômetro de ovo a qualquer momento que quiser. O código inicial é totalmente funcional, o que significa que você pode configurar o cronômetro de ovo e vê-lo fazer a contagem regressiva até 0. Quando o cronômetro termina, uma mensagem de brinde é exibida, conforme mostrado abaixo.

  1. Inspecione o código-fonte. O aplicativo inicial consiste em uma única atividade chamada MainActivity. Existem três subpacotes chamados receiver, ui e util.

Usar notificações é uma ótima maneira de chamar a atenção dos usuários para o seu aplicativo. Esteja seu aplicativo não 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, você precisa usar um construtor de notificação e fornecer um texto de título, um texto de conteúdo e um ícone. Uma vez que o construtor tenha todos os campos necessários, NotificationManager, que é um serviço do sistema, ajuda você a exibir esse conteúdo como uma notificação. NotificationManager é responsável por enviar uma notificação, atualizar seu conteúdo e cancelar a notificação. Nas etapas a seguir, você adicionará métodos de extensão ao NotificationManager. Dessa forma, toda vez que você precisar usar o NotificationManager, poderá usar essas funções de extensão para obter a funcionalidade que precisa usar.

Etapa 1: criar uma notificação básica

Nesta tarefa, você está criando uma nova notificação, definindo uma mensagem para o seu usuário e enviando a notificação.

  1. Abra a classe NotificationUtils.kt e encontre TODO: Step 1.1. Você encontrará todos correspondentes neste tutorial e no código do aplicativo.
  2. Examine a função sendNotification() fornecida. Você estará estendendo esta função de extensão para NotificationManager 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) {
  1. Obtenha uma instância do construtor de notificação, passe no contexto do aplicativo e um ID de canal. O ID do canal é um valor de string para o canal.

Notification Channels 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 que um canal é criado, ele pode ser usado para entregar 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)
)
  1. Defina o ícone de notificação para representar seu aplicativo, um título e o texto do conteúdo para a mensagem que você deseja enviar ao usuário. Você verá mais opções para personalizar ainda mais sua notificação no tutorial, mas esta é a quantidade mínima de dados que você precisa definir 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)
  1. Em seguida, você precisa chamar notify() com um ID exclusivo para sua notificação e com o objeto Notification de seu construtor.

Este ID representa a instância de notificação atual e é necessário para atualizar ou cancelar esta notificação. Como seu aplicativo terá apenas uma notificação ativa por vez, você pode usar o mesmo ID para todas as suas notificações. Você já recebeu uma constante para este propósito chamada NOTIFICATION_ID em NotificationUtils.kt. Observe que você pode chamar diretamente notify(), pois está executando 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())
  1. Abra ui/EggTimerViewModel.kt e encontre a função startTimer(). Esta função cria um alarme com o intervalo de tempo selecionado quando o usuário ativa o cronômetro.
  2. Você irá disparar uma notificação nesta função quando o usuário iniciar o cronômetro. Para chamar a função sendNotification() que você implementou anteriormente, você precisa de uma instância de NotificationManager. NotificationManager é um serviço do sistema que fornece todas as funções expostas para a API de notificações, incluindo a função de extensão que você adicionou. Sempre que desejar enviar, cancelar ou atualizar uma notificação, você precisará solicitar uma instância do NotificationManager do sistema. Chame a função sendNotification()| com a mensagem de notificação e com 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)

Você está quase lá. No entanto, se você executar seu aplicativo agora e definir o cronômetro, não receberá uma notificação.

  1. Abra logcat e pesquise por "No Channel found". Você deverá ver uma mensagem de erro informando que o egg_channel não existe. Nas etapas a seguir, você aprenderá mais sobre os canais de notificação e corrigirá isso.

Etapa 2: Canais de Notificação

A partir da API de nível 26, todas as notificações devem ser atribuídas a um canal. Se você tocar e segurar o ícone do iniciador do aplicativo, selecionar informações do aplicativo e tocar em notificações, você verá uma lista de canais de notificação associados ao aplicativo. No momento, a lista está vazia porque seu aplicativo não criou nenhum canal.

Os canais representam um "tipo" de notificação - por exemplo, o cronômetro pode enviar uma notificação quando o ovo estiver cozido e também usar outro canal para enviar notificações diárias para lembrá-lo de comer ovos no café da manhã. Todas as notificações em 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 suas configurações de notificação com base no tipo de notificação em que estão interessados. Por exemplo, seus usuários podem desativar as notificações de café da manhã, mas ainda assim escolher ver as notificações do cronômetro.

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 seu canal de notificação, então agora você precisa realmente criar e personalizar as configurações de notificação e comportamento deste canal.

  1. Abra EggTimerFragment.kt e encontre a função createChannel().
  2. Passe o ID exclusivo do canal para o construtor de NotificationChannel.
  3. Passe o nome do canal de notificação, que os usuários também verão em suas telas Settings.
  4. Como último parâmetro, passe o nível de importância para o canal de notificação. Os níveis de importância serão cobertos mais tarde neste tutorial, então por enquanto você pode usar NotificationManager.IMPORTANCE_LOW.
  5. No objeto notificationChannel, defina enableLights como verdadeiro. Esta configuração ativará as luzes quando uma notificação for exibida.
  6. No objeto notificationChannel, defina lightColor como vermelho para exibir uma luz vermelha quando uma notificação for mostrada.
  7. No objeto notificationChannel, defina enableVibration como verdadeiro para habilitar a vibração.
  8. No objeto notificationChannel, defina a descrição do canal como ‘Time for breakf ast '.
  9. Obtenha uma instância de NotificationManager chamando getSystemService().
  10. Chame createNotificationChannel() em NotificationManager e passe o objeto notificationChannel 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
}
  1. Em seguida, para criar um canal, você precisa chamar a função createChannel() que você acabou de escrever (Etapa 1.7). Esta função tem dois parâmetros, o ID do canal e o nome do canal. Você precisa pesquisar o ID e o nome do canal nos recursos de string que já foram fornecidos em seu projeto.
// EggTimerFragment.kt
    // TODO: Step 1.7 call createChannel
    createChannel(
          getString(R.string.egg_notification_channel_id),
          getString(R.string.egg_notification_channel_name)
    )
  1. Você precisa passar o ID do canal para o construtor de notificação. Você já fez isso na Etapa 1.2. Definir um valor incorreto como o ID do canal fará 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)
)
  1. Execute o aplicativo e você verá que ele enviará uma notificação sempre que você iniciar o cronômetro.
  2. Puxe a barra de status e observe se o título, o conteúdo e o ícone da notificação são como você os definiu nas etapas anteriores.
  3. Para verificar o canal recém-criado, feche o aplicativo e encontre o ícone do aplicativo. Dê um toque longo no ícone do aplicativo e selecione App info.

  1. Selecione Notifications na lista de configurações. Você deve ver um novo canal chamado Egg, logo abaixo da configuração Show notifications.

Quando você executa o aplicativo, a notificação agora é exibida. Você, como desenvolvedor do aplicativo, 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 seu aplicativo

Até agora, isso mostra o uso básico da API de notificações, mas enviar uma notificação logo após iniciar o cronômetro não faz muito sentido. Os usuários provavelmente preferem ser notificados quando o ovo estiver pronto. Na parte seguinte do tutorial, você corrigirá isso e alterará a mensagem do sistema 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 ótimas notificações. Nesta etapa, você alterará sua notificação para que seja enviada em um momento mais apropriado.

Seu aplicativo usa AlarmManager para configurar um alarme. O código relacionado ao AlarmManager já está fornecido no código inicial e é usado para mostrar a mensagem do sistema. AlarmManager mantém registro da seleção de tempo desejada e acionará a função onReceive() de AlarmReceiver.kt quando o tempo acabar. Se você abrir AlarmReceiver.kt e navegar até onReceive(), deverá ver a mensagem torrada que é exibida toda vez que você configura um cronômetro de ovo.

  1. Abra AlarmReceiver.kt, uma instância de NotificationManager, e chame a função sendNotification() 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
   )
  1. Opcionalmente, remova a notificação do sistema, pois seu aplicativo enviará uma notificação quando o cronômetro terminar.
// AlarmReceiver.kt
     // TODO: Step 1.10 [Optional] remove toast
//   Toast.makeText(
//       context, 
//       context.getText(R.string.eggs_ready),
//       Toast.LENGTH_SHORT
//   ).show()
  1. Execute seu aplicativo. Deverá ver uma notificação sempre que iniciar o cronómetro e sempre que o cronómetro acabar.

Isso não é o ideal. Você não deseja enviar muitas notificações aos seus usuários. Você pode remover a primeira notificação enviada quando o usuário inicia o cronômetro.

  1. 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)
  1. Execute seu aplicativo novamente.
  2. Defina um cronômetro, coloque-o em segundo plano e espere o tempo terminar. Você verá uma notificação. Esta é uma notificação muito mais útil.

Etapa 4: adicione uma intenção de conteúdo

  1. Execute o aplicativo novamente, se ainda não estiver em execução.
  2. Clique na notificação. Nada acontece!

Mostrar a notificação e informar o usuário é ótimo, mas quando um usuário clica em uma notificação, ele espera voltar ao aplicativo correspondente. Nesta parte do tutorial, você adicionará uma intenção à sua notificação para trazer o usuário de volta à tela do cronômetro.

Um Intent é um objeto de mensagem que você pode usar para solicitar uma ação de outro componente do aplicativo. Os intents podem ser usados ​​para iniciar uma atividade, um serviço ou entregar uma transmissão. Nesse caso, você usa essa intenção para dizer ao sistema para abrir MainActivity quando o usuário tocar na notificação. Como seu aplicativo consiste em apenas uma única vista, você não tem muitas opções aqui. No entanto, em um aplicativo maior, a notificação deve criar uma experiência contínua, levando o usuário a uma tela que faça sentido para quando ele interagir com a notificação.

  1. Abra NotificationUtils.kt e encontre a função de extensão sendNotification().
  2. Crie um Intent com seu applicationContext 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 o intent, mas a notificação é exibida fora do seu aplicativo. Para fazer uma intenção funcionar fora do seu aplicativo, você precisa criar um novo PendingIntent.

PendingIntent concede direitos a outro aplicativo ou sistema para realizar uma operação em nome do seu aplicativo. O próprio PendingIntent é simplesmente uma referência a um token mantido pelo sistema que descreve os dados originais usados ​​para recuperá-lo. Isso significa que, mesmo se o processo do aplicativo proprietário for eliminado, o próprio PendingIntent permanecerá utilizável de outros processos aos quais foi fornecido. Nesse caso, o sistema usará a intenção pendente para abrir o aplicativo em seu nome, independentemente de o aplicativo temporizador estar ou não em execução.

  1. Crie um PendingIntent com applicationContext, NOTIFICATION_ID, o contentIntent criado na etapa anterior e o PendingIntent. O sinalizador PendingIntent especifica a opção de criar um novo PendingIntent ou usar um existente. Você precisa definir PendingIntent.FLAG_UPDATE_CURRENT como o sinalizador, pois você não deseja criar uma nova notificação se houver uma existente. Desta forma, você estará modificando o PendingIntent atual, que está associado ao 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
    )
  1. Passe o PendingIntent para sua notificação. Você pode fazer isso chamando setContentIntent() no NotificationBuilder. Agora, ao clicar na notificação, o PendingIntent será acionado, abrindo sua MainActivity.
  2. Defina também setAutoCancel() como true, de modo que, quando o usuário tocar na notificação, a notificação seja descartada automaticamente ao levá-lo para o aplicativo.
// NotificationUtils.kt
    // TODO: Step 1.13 set content intent
    .setContentIntent(contentPendingIntent)
    .setAutoCancel(true)
  1. Execute o aplicativo novamente.
  2. Defina um cronômetro, coloque o aplicativo em segundo plano e aguarde o aparecimento da notificação.
  3. Depois de ver a notificação, clique na notificação puxando para baixo a barra de status e observe como o aplicativo é colocado em primeiro plano.

Etapa 5: cancelar a notificação

Você tem um cronômetro de ovo funcional com notificações, mas há um pequeno problema. Se você definir o cronômetro, obter uma notificação e configurá-lo novamente, a notificação anterior permanecerá na barra de status enquanto o novo cronômetro estiver em execução. Isso pode confundir o usuário se o aplicativo estiver em segundo plano e resultar em ovos mal cozidos.

Para corrigir isso, você precisa limpar a notificação anterior ao iniciar um novo cronômetro. Comece criando outra função de extensão em seu NotificationUtils.kt. NotificationManager tem uma API para cancelar todas as notificações ativas chamada cancelAll().

  1. Abra NotificationsUtil.kt.
  2. Adicione uma função de extensão em NotificationManager que chama cancelAll().
// NotificationUtils.kt

// TODO: Step 1.14 Cancel all notifications
/**
 * Cancels all notifications.
 *
 */
fun NotificationManager.cancelNotifications() {
    cancelAll()
}
  1. Abra EggTimerViewModel.kt e navegue até a função startTimer().
  2. Dentro de startTimer(), obtenha uma instância do NotificationManager do sistema e chame cancelNotifications().
//  EggTimerViewModel.kt
   //TODO Step 1.15 call cancel notification
    val notificationManager =
       ContextCompat.getSystemService(
            app,
            NotificationManager::class.java
        ) as NotificationManager
    notificationManager.cancelNotifications()       
  1. Execute o aplicativo e inicie o cronômetro.
  2. Depois de ver a notificação, inicie o cronômetro novamente e observe como nosso aplicativo exclui automaticamente a notificação anterior da barra de status.

A estrutura de notificação oferece uma variedade de opções de customização para os desenvolvedores definirem ações customizadas e estilizar suas notificações conforme necessário. Durante esta tarefa, você aprenderá como personalizar as notificações do cronômetro de ovo.

Etapa 1: defina o estilo de sua notificação

Definir o estilo de sua notificação de acordo com suas necessidades e o conteúdo da notificação fará com que suas notificações se destaquem e se pareçam mais com uma extensão de seu aplicativo. A estrutura de notificação vem com vários estilos integrados para ajudar e você sempre pode criar o seu próprio.

NotificationCompat oferece estilos integrados para:

Você pode encontrar mais informações sobre outros estilos na documentação para Criar uma notificação expansível. Nesta etapa, você usará NotificationCompat.BigPictureStyle para criar uma notificação expansível que mostra uma grande imagem de ovo quando expandida.

  1. Abra NotificationUtils.kt e encontre a função sendNotification().
  2. Comece carregando uma imagem de resources usando a BitmapFactory.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
  1. Crie um novo BigPictureStyle e defina sua imagem.
  2. Defina bigLargeIcon() como null 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)
  1. Defina o estilo com setStyle() para bigPicStyle.
  2. Defina o ícone grande com setLargeIcon() para eggImage, 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)
  1. Execute o aplicativo e defina um cronômetro. Quando a notificação é exibida pela primeira vez, ela está no estado recolhido na gaveta de notificação. Se você expandir a notificação, uma imagem grande será exibida 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 suas notificações. Suas notificações atualmente redirecionam para seu aplicativo 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 concluem uma tarefa relacionada ao aplicativo 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 devem duplicar a ação realizada quando o usuário toca na notificação.

Para adicionar um botão de ação, passe um PendingIntent para a função addAction() no construtor. 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 uma variedade de outras coisas, por exemplo, iniciar um BroadcastReceiver que executa um trabalho em segundo plano para que a ação não interrompa o aplicativo que já está aberto.

Neste tutorial, você já recebeu um BoadcastReceiver denominado SnoozeReceiver. Você usará 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 cronômetro de ovo por 60 segundos quando o usuário clicar no botão de ação de adiar. Quando a ação de soneca é clicada, o SnoozeReceiver receberá uma intenção e criará um novo alarme para enviar uma nova notificação após 60 segundos.

  1. Abra SnoozeReceiver.kt. Esta classe é semelhante ao AlarmReceiver que você usou antes. Nas etapas a seguir, você adicionará o código que acionará a função onReceive() do SnoozeReceiver. Resumindo, o código em SnoozeReceiver criará um novo alarme para enviar uma nova notificação um minuto depois. Role até a parte inferior da função onReceive, obtenha uma instância de notificationManager do sistema e chame cancelAll.
// SnoozeReceiver.kt
        val notificationManager = ContextCompat.getSystemService(
            context,
            NotificationManager::class.java
        ) as NotificationManager
        notificationManager.cancelAll()
  1. Para usar o SnoozeReceiver, abra NotificationUtils.kt.
  2. Crie um novo Intent snoozeIntent para o SnoozeReceiver logo após o estilo na função sendNotification().
  3. Crie uma intenção pendente chamando o método getBroadcast() em PendingIntent que espera os parâmetros nas etapas a seguir. Este PendingIntent será usado pelo sistema para configurar um novo alarme para postar uma nova notificação após 60 segundos quando o botão soneca for tocado pelo usuário.
  4. O primeiro parâmetro é o contexto do aplicativo no qual este PendingIntent deve iniciar a atividade.
  5. O segundo parâmetro é o código da solicitação, que é o código da solicitação para este intent pendente. Se você precisar atualizar ou cancelar este intent pendente, você precisará usar este código para acessar o intent pendente.
  6. Em seguida, adicione o objeto snoozeIntent, que é a intenção da atividade a ser iniciada.
  7. Por último, adicione o valor do sinalizador de #FLAG_ONE_SHOT, pois o intent será usado apenas uma vez. A ação rápida e a notificação desaparecerão após o primeiro toque, por isso a intenção somente 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
)
  1. Em seguida, chame a função addAction() no notificationBuilder. Esta função espera um ícone e um texto para descrever sua ação para o usuário. Você também precisa adicionar o snoozeIntent. Este intent será usado para acionar o boadcastReceiver correto quando sua ação for clicada.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
    R.drawable.egg_icon, 
    applicationContext.getString(R.string.snooze),
    snoozePendingIntent
)
  1. Execute o aplicativo cronômetro de ovo para testar a ação de soneca.
  2. Execute o cronômetro e coloque o aplicativo em segundo plano. Assim que o cronômetro estiver ativado, expanda a notificação e você verá que a notificação agora tem um botão de ação de soneca que adia o cronômetro por mais um minuto.

Etapa 3: importância da notificação

A importância determina o quanto a notificação deve interromper o usuário visual e audivelmente. Notificações com maior importância serão mais interruptivas para os usuários.

Você deve especificar o nível de importância no construtor NotificationChannel. Você originalmente definiu baixa importância para o aplicativo cronômetro de ovo. Você pode usar um dos cinco níveis de importância, variando de IMPORTANCE_NONE(0) a IMPORTANCE_HIGH(4). O nível de importância que você atribui 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 superior)

Prioridade (Android 7.1 e inferior)

Emite um som e aparece como uma notificação de alerta (aparece na parte superior da tela)

IMPORTANCE_HIGH

PRIORITY_HIGH / PRIORITY_MAX

Faz um som

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

Sem som

IMPORTANCE_LOW

PRIORITY_LOW

Sem som e não aparece na barra de status

IMPORTANCE_MIN

PRIORITY_MIN

Para obter informações sobre como escolher um nível de prioridade apropriado, consulte "Níveis de prioridade" no Guia de design de notificações. Você deve ter cuidado ao selecionar um nível de importância para as notificações em seu aplicativo. A importância do canal deve ser escolhida levando em consideração o tempo e a atenção do usuário. Quando uma notificação sem importância é disfarçada como urgente, pode produzir um alarme desnecessário e distrair. Os usuários têm controle total sobre o nível de importância de suas notificações, portanto, se você criar uma notificação irritante, eles podem desligar o canal de notificação completamente.

Quando você criou a notificação na Etapa 1.6, o cronômetro de ovo foi configurado para enviar notificações com uma prioridade baixa, pois foi projetado para não incomodar o usuário com notificações. No entanto, pode ser uma boa ideia chamar a atenção do usuário antes que o ovo cozinhe demais. Para alterar o nível de importância da notificação, comece com 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 deve ser especificada no construtor NotificationChannel.

  1. Para alterar o nível de importância do canal de notificação de seu aplicativo, abra EggTimerFragment.kt e navegue até createChannel(). Altere o nível de importância de IMPORTANCE_LOW para IMPORTANCE_HIGH.
// EggTimerFragment.kt
    val notificationChannel = NotificationChannel(
        channelId,
        channelName,
        // TODO: Step 2.4 change importance
        NotificationManager.IMPORTANCE_HIGH
    )

Para dar suporte a dispositivos que executam Android 7.1 (API de nível 25) ou inferior, você também deve chamar setPriority() para cada notificação, usando uma constante de prioridade da classe NotificationCompat.

  1. Abra NotificationUtils.kt e adicione o seguinte ao objeto do construtor de notificação.
// 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)
  1. Antes de executar o aplicativo, clique longamente no ícone do aplicativo em seu dispositivo ou emulador e selecione desinstalar para limpar as configurações anteriores do canal. Se você não desinstalar o aplicativo, 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.
  2. Agora execute o aplicativo novamente e inicie o cronômetro. Desta vez, quando a notificação for entregue, você deverá ver um pop-up aparecer na parte superior da tela, independentemente de seu aplicativo estar sendo executado em primeiro ou segundo plano.

Etapa 4: emblemas de notificação

Os emblemas de notificação são pequenos pontos que aparecem no ícone do iniciador do aplicativo associado quando o aplicativo tem uma notificação ativa. Os usuários podem manter pressionado o ícone do aplicativo para revelar as notificações.

Esses pontos, chamados de emblemas, aparecem por padrão e não há nada que seu aplicativo precise fazer. No entanto, pode haver situações em que os selos não façam sentido para suas notificações, então você pode desativá-los por canal chamando setShowBadge(false) em seu NotificationChannel objeto. Como o cronômetro de ovo tem apenas uma notificação ativa por vez, o emblema no ícone do aplicativo não oferece muitos benefícios para os usuários. Nas etapas a seguir, você desativará o emblema e mostrará apenas uma notificação para o cronômetro.

  1. Adicione setShowBadge(false) ao código de criação de canal para o cronômetro de ovo para desabilitar emblemas.
// EggTimerFragment.kt

    ).apply {
        // TODO: Step 2.6 disable badges for this channel
        setShowBadge(false)
    }
  1. Execute o aplicativo novamente, inicie o cronômetro e observe o ícone do aplicativo. Você não deve ver nenhum emblema no ícone do aplicativo.

O código da solução está no branch master do seu código baixado.

Documentação do desenvolvedor Android:

Para obter links para outros tutoriais neste curso, consulte a página inicial de tutoriais do Android avançado em Kotlin.