Criar uma notificação

As notificações fornecem informações curtas e oportunas sobre eventos no seu app enquanto ele não está em uso. Esta página ensina como criar uma notificação com vários recursos do Android 4.0 (API de nível 14) e versões posteriores. Para ver uma introdução de como as notificações aparecem no Android, consulte Visão geral de notificações. Para ver o código de exemplo que usa notificações, consulte a amostra de notificações do Android (link em inglês).

Observe que o código dessa página usa as APIs NotificationCompat da Biblioteca de Suporte do Android. Essas APIs permitem que você adicione recursos disponíveis apenas em versões mais recentes do Android e também oferecem compatibilidade com o Android 4.0 (API de nível 14). No entanto, alguns recursos novos, por exemplo, a ação de respostas in-line, resultam em um ambiente autônomo em versões mais antigas.

Adicionar a Biblioteca de Suporte

Embora a maioria dos projetos criados com o Android Studio inclua as dependências necessárias para usar NotificationCompat, verifique se seu arquivo build.gradle no nível do módulo inclui a seguinte dependência:

dependencies {
        implementation "com.android.support:support-compat:28.0.0"
    }
    

Criar uma notificação básica

Uma notificação na forma mais básica e compacta (também conhecida como "forma recolhida") exibe um ícone, um título e uma pequena quantidade de texto do conteúdo. Nesta seção, você aprenderá como criar uma notificação em que o usuário pode clicar para iniciar uma atividade no seu app.

Figura 1. Uma notificação com título e texto.

Para ver mais detalhes sobre cada parte de uma notificação, leia sobre a anatomia da notificação.

Definir o conteúdo das notificações

Para começar, você precisa configurar o conteúdo e o canal da notificação usando um objeto NotificationCompat.Builder. O exemplo a seguir mostra como criar uma notificação com o seguinte:

  • Um pequeno ícone, definido por setSmallIcon(). Esse é o único conteúdo visível ao usuário necessário.
  • Um título, definido por setContentTitle().
  • O texto do corpo, definido por setContentText().
  • A prioridade da notificação, definida por setPriority(). A prioridade determina se a notificação deve ser intrusiva ou não no Android 7.1 e versões anteriores. Para o Android 8.0 e versões posteriores, você precisa definir a importância do canal, mostrada na próxima seção.

Kotlin

    var builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle(textTitle)
            .setContentText(textContent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    

Java

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle(textTitle)
            .setContentText(textContent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    

Observe que o construtor NotificationCompat.Builder requer que você forneça um ID do canal. Isso é necessário para que haja compatibilidade com o Android 8.0 (API de nível 26) e versões posteriores, mas é ignorado pelas versões mais antigas.

Por padrão, o conteúdo do texto da notificação é truncado para caber em uma única linha. Para que sua notificação seja mais longa, é possível ativar uma notificação expansível adicionando um modelo de estilo com setStyle(). Por exemplo, o código a seguir cria uma área de texto maior:

Kotlin

    var builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Much longer text that cannot fit one line...")
            .setStyle(NotificationCompat.BigTextStyle()
                    .bigText("Much longer text that cannot fit one line..."))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    

Java

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Much longer text that cannot fit one line...")
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText("Much longer text that cannot fit one line..."))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    

Para saber mais sobre outros estilos de notificação grandes, incluindo como adicionar uma imagem e controles de reprodução de mídia, consulte Criar uma notificação com detalhes expansíveis.

Criar um canal e definir a importância

Antes de entregar a notificação no Android 8.0 e versões posteriores, você precisa registrar o canal de notificação do seu app no sistema, passando uma instância de NotificationChannel para createNotificationChannel(). Portanto, o código a seguir é bloqueado por uma condição na versão SDK_INT:

Kotlin

    private fun createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = getString(R.string.channel_name)
            val descriptionText = getString(R.string.channel_description)
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
            }
            // Register the channel with the system
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
    

Java

    private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
    

Como você precisa criar o canal de notificação antes de postar notificações no Android 8.0 e versões posteriores, execute esse código assim que o app for iniciado. Não há problemas em chamar isso repetidamente, porque a criação de um canal de notificação já existente não realiza uma operação.

Observe que o construtor NotificationChannel exige uma importance, usando uma das constantes da classe NotificationManager. Esse parâmetro determina como interromper o usuário para mostrar uma notificação que pertença a esse canal, embora você também precise definir a prioridade com setPriority() para oferecer compatibilidade ao Android 7.1 e versões anteriores (como mostrado acima).

Embora você precise definir a importância/prioridade da notificação, como mostrado aqui, o sistema não garante o comportamento do alerta que você receberá. Em alguns casos, o sistema pode alterar o nível de importância com base em outros fatores, e o usuário pode sempre redefinir o nível de importância para determinado canal.

Para saber mais sobre o significado dos diferentes níveis, leia sobre os níveis de importância da notificação.

Definir a ação de toque da notificação

Toda notificação precisa responder a um toque, geralmente para abrir uma atividade no seu app que corresponda à notificação. Para fazer isso, especifique um intent de conteúdo definido com um objeto PendingIntent e passe-o para setContentIntent().

O seguinte snippet mostra como criar um intent básico para abrir uma atividade quando o usuário toca na notificação:

Kotlin

    // Create an explicit intent for an Activity in your app
    val intent = Intent(this, AlertDetails::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

    val builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
    

Java

    // Create an explicit intent for an Activity in your app
    Intent intent = new Intent(this, AlertDetails.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);
    

Observe que esse código chama setAutoCancel(), que remove automaticamente a notificação quando o usuário toca nela.

O método setFlags() mostrado acima ajuda a manter a experiência de navegação esperada pelo usuário depois que ele abre o app por meio da notificação Mas o uso desse método depende do tipo de atividade você está iniciando, que pode ser uma das seguintes:

  • Uma atividade que existe exclusivamente para respostas à notificação. Não há motivo para o usuário navegar para essa atividade durante o uso normal do app. Portanto, a atividade inicia uma nova tarefa, em vez de ser adicionada à tarefa e à pilha traseira existentes no seu app. Esse é o tipo de intent criado no exemplo acima.
  • Uma atividade que existe no fluxo regular do seu app. Nesse caso, o início da atividade precisa criar uma pilha inversa para que as expectativas do usuário para os botões Voltar e Para cima sejam preservadas.

Para saber mais sobre as diferentes maneiras de configurar o intent da sua notificação, leia Iniciar uma atividade a partir de uma notificação.

Mostrar a notificação

Para fazer a notificação aparecer, chame NotificationManagerCompat.notify(), transmitindo a ela um código exclusivo para a notificação e o resultado de NotificationCompat.Builder.build(). Por exemplo:

Kotlin

    with(NotificationManagerCompat.from(this)) {
        // notificationId is a unique int for each notification that you must define
        notify(notificationId, builder.build())
    }
    

Java

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

    // notificationId is a unique int for each notification that you must define
    notificationManager.notify(notificationId, builder.build());
    

Lembre-se de salvar o código da notificação que você transmitir para NotificationManagerCompat.notify(), porque você precisará dele mais tarde para atualizar ou remover a notificação.

Adicionar botões de açã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 até mesmo responder a uma mensagem de texto. Mas esses botões de ação não devem duplicar a ação executada quando o usuário toca na notificação.

Figura 2. Uma notificação com um botão de ação.

Para adicionar um botão de ação, passe um PendingIntent para o método addAction(). Esse processo é parecido com configurar a ação de toque padrão da notificação, exceto que, em vez de iniciar uma atividade, você pode fazer várias outras coisas, como iniciar um BroadcastReceiver que execute um job em segundo plano para que a ação não interrompa o app que já está aberto.

Por exemplo, o seguinte código mostra como enviar uma transmissão a um receptor específico:

Kotlin

    val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
        action = ACTION_SNOOZE
        putExtra(EXTRA_NOTIFICATION_ID, 0)
    }
    val snoozePendingIntent: PendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)
    val builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                    snoozePendingIntent)
    

Java

    Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
    snoozeIntent.setAction(ACTION_SNOOZE);
    snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
    PendingIntent snoozePendingIntent =
            PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                    snoozePendingIntent);
    

Para saber mais sobre como criar um BroadcastReceiver para executar um trabalho em segundo plano, consulte o Guia de transmissões.

Se você estiver tentando criar uma notificação com os botões de reprodução de mídia (por exemplo, pausar e pular faixas), veja como criar uma notificação com controles de mídia.

Adicionar uma ação de resposta direta

A ação de resposta direta, introduzida no Android 7.0 (API de nível 24), permite aos usuários inserir texto diretamente na notificação, que é entregue ao seu app sem abrir uma atividade. Por exemplo, você pode usar uma ação de resposta direta para permitir que os usuários respondam a mensagens de texto ou atualizem listas de tarefas na notificação.

Figura 3. Tocar no botão "Responder" abre a entrada de texto.

A ação de resposta direta aparece como um botão adicional na notificação que abre uma entrada de texto. Quando um usuário termina de digitar, o sistema anexa a resposta de texto ao intent especificado para a ação de notificação e a envia ao seu app.

Adicionar o botão de resposta

Para criar uma ação de notificação compatível com a resposta direta:

  1. Crie uma instância de RemoteInput.Builder que possa ser adicionada à sua ação de notificação. O construtor dessa classe aceita uma string, usada pelo sistema como chave da entrada de texto. Posteriormente, o app para dispositivos portáteis usará essa chave para recuperar o texto da entrada.

    Kotlin

        // Key for the string that's delivered in the action's intent.
        private val KEY_TEXT_REPLY = "key_text_reply"
        var replyLabel: String = resources.getString(R.string.reply_label)
        var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run {
            setLabel(replyLabel)
            build()
        }
        

    Java

        // Key for the string that's delivered in the action's intent.
        private static final String KEY_TEXT_REPLY = "key_text_reply";
    
        String replyLabel = getResources().getString(R.string.reply_label);
        RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
                .setLabel(replyLabel)
                .build();
        
  2. Crie um PendingIntent para a ação de resposta.

    Kotlin

        // Build a PendingIntent for the reply action to trigger.
        var replyPendingIntent: PendingIntent =
            PendingIntent.getBroadcast(applicationContext,
                conversation.getConversationId(),
                getMessageReplyIntent(conversation.getConversationId()),
                PendingIntent.FLAG_UPDATE_CURRENT)
        

    Java

        // Build a PendingIntent for the reply action to trigger.
        PendingIntent replyPendingIntent =
                PendingIntent.getBroadcast(getApplicationContext(),
                        conversation.getConversationId(),
                        getMessageReplyIntent(conversation.getConversationId()),
                        PendingIntent.FLAG_UPDATE_CURRENT);
        

    Cuidado: se você reutilizar um PendingIntent, um usuário poderá responder a uma conversa diferente daquela que imaginava. Forneça um código de solicitação que seja diferente para cada conversa ou um intent que não retorne true quando você chama equals() no intent de resposta de qualquer outra conversa. O código da conversa é frequentemente transmitido como parte do pacote extra do intent, mas é ignorado quando você chama equals().

  3. Anexe o objeto RemoteInput a uma ação usando addRemoteInput().

    Kotlin

        // Create the reply action and add the remote input.
        var action: NotificationCompat.Action =
            NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                getString(R.string.label), replyPendingIntent)
                .addRemoteInput(remoteInput)
                .build()
        

    Java

        // Create the reply action and add the remote input.
        NotificationCompat.Action action =
                new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                        getString(R.string.label), replyPendingIntent)
                        .addRemoteInput(remoteInput)
                        .build();
        
  4. Aplique a ação a uma notificação e emita a notificação.

    Kotlin

        // Build the notification and add the action.
        val newMessageNotification = Notification.Builder(context, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_message)
                .setContentTitle(getString(R.string.title))
                .setContentText(getString(R.string.content))
                .addAction(action)
                .build()
    
        // Issue the notification.
        with(NotificationManagerCompat.from(this)) {
            notificationManager.notify(notificationId, newMessageNotification)
        }
        

    Java

        // Build the notification and add the action.
        Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_message)
                .setContentTitle(getString(R.string.title))
                .setContentText(getString(R.string.content))
                .addAction(action)
                .build();
    
        // Issue the notification.
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(notificationId, newMessageNotification);
        

O sistema solicita que o usuário informe uma resposta quando a ação de notificação é acionada, conforme mostrado na figura 3.

Recuperar entrada do usuário na resposta

Para receber a entrada do usuário da IU de resposta da notificação, chame RemoteInput.getResultsFromIntent(), transmitindo-a para o Intent recebido pelo seu BroadcastReceiver:

Kotlin

    private fun getMessageText(intent: Intent): CharSequence? {
        return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
    }
    

Java

    private CharSequence getMessageText(Intent intent) {
        Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
        if (remoteInput != null) {
            return remoteInput.getCharSequence(KEY_TEXT_REPLY);
        }
        return null;
     }
    

Depois de processar o texto, você precisa atualizar a notificação chamando NotificationManagerCompat.notify() com o mesmo código e tag (se usados). Isso é necessário para ocultar a IU de resposta direta e confirmar ao usuário que a resposta foi recebida e processada corretamente.

Kotlin

    // Build a new notification, which informs the user that the system
    // handled their interaction with the previous notification.
    val repliedNotification = Notification.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_message)
            .setContentText(getString(R.string.replied))
            .build()

    // Issue the new notification.
    NotificationManagerCompat.from(this).apply {
        notificationManager.notify(notificationId, repliedNotification)
    }
    

Java

    // Build a new notification, which informs the user that the system
    // handled their interaction with the previous notification.
    Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_message)
            .setContentText(getString(R.string.replied))
            .build();

    // Issue the new notification.
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(notificationId, repliedNotification);
    

Ao trabalhar com essa nova notificação, use o contexto que é transmitido para o método onReceive() do receptor.

Você também precisa anexar a resposta à parte inferior da notificação chamando setRemoteInputHistory(). No entanto, se você estiver criando um app de mensagens, crie uma notificação em estilo de mensagem e anexe a nova mensagem à conversa.

Para saber mais dicas sobre notificações a partir de apps de mensagens, consulte as práticas recomendadas para apps de mensagens.

Adicionar uma barra de progresso

As notificações podem incluir um indicador de progresso animado que mostra aos usuários o status de uma operação em andamento.

Figura 4. A barra de progresso durante e após a operação.

Se for possível estimar a quantidade da operação concluída em determinado momento, use a forma "determinada" do indicador (conforme mostrado na figura 4), chamando setProgress(max, progress, false). O primeiro parâmetro é o valor "completo" (por exemplo, 100), o segundo é a quantidade que está concluída no momento e o último indica que se trata de uma barra de progresso determinada.

À medida que sua operação prossegue, chame continuamente setProgress(max, progress, false) com um valor atualizado para progress e emita novamente a notificação.

Kotlin

    val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
        setContentTitle("Picture Download")
        setContentText("Download in progress")
        setSmallIcon(R.drawable.ic_notification)
        setPriority(NotificationCompat.PRIORITY_LOW
    }
    val PROGRESS_MAX = 100
    val PROGRESS_CURRENT = 0
    NotificationManagerCompat.from(this).apply {
        // Issue the initial notification with zero progress
        builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false)
        notify(notificationId, builder.build())

        // Do the job here that tracks the progress.
        // Usually, this should be in a
        // worker thread
        // To show progress, update PROGRESS_CURRENT and update the notification with:
        // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
        // notificationManager.notify(notificationId, builder.build());

        // When done, update the notification one more time to remove the progress bar
        builder.setContentText("Download complete")
                .setProgress(0, 0, false)
        notify(notificationId, builder.build())
    }
    

Java

    ...
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
    builder.setContentTitle("Picture Download")
            .setContentText("Download in progress")
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_LOW);

    // Issue the initial notification with zero progress
    int PROGRESS_MAX = 100;
    int PROGRESS_CURRENT = 0;
    builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    notificationManager.notify(notificationId, builder.build());

    // Do the job here that tracks the progress.
    // Usually, this should be in a
    // worker thread
    // To show progress, update PROGRESS_CURRENT and update the notification with:
    // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    // notificationManager.notify(notificationId, builder.build());

    // When done, update the notification one more time to remove the progress bar
    builder.setContentText("Download complete")
            .setProgress(0,0,false);
    notificationManager.notify(notificationId, builder.build());
    

No término da operação, progress precisa ser igual a max. É possível deixar a barra de progresso em exibição ou removê-la quando a operação for concluída. Em ambos os casos, lembre-se de atualizar o texto da notificação para mostrar que a operação foi concluída. Para remover a barra de progresso, chame setProgress(0, 0, false).

Para exibir uma barra de progresso indeterminada (uma barra que não indique a porcentagem concluída), chame setProgress(0, 0, true). O resultado é um indicador com o mesmo estilo que a barra de progresso acima, com a diferença de que a animação dele é contínua e não indica o término. A animação do progresso é executada até que você chame setProgress(0, 0, false) e atualize a notificação para remover o indicador de atividade.

Lembre-se de alterar o texto da notificação para indicar que a operação foi concluída.

Definir uma categoria para todo o sistema

O Android usa algumas categorias predefinidas do sistema para determinar se incomodará o usuário com determinada notificação quando o usuário ativar o modo "Não perturbe".

Se a notificação se enquadra em uma das categorias predefinidas de notificação definidas em NotificationCompat, como CATEGORY_ALARM, CATEGORY_REMINDER, CATEGORY_EVENT ou CATEGORY_CALL, declare-a dessa forma, transmitindo a categoria adequada a setCategory().

Kotlin

    var builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setCategory(NotificationCompat.CATEGORY_MESSAGE)
    

Java

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setCategory(NotificationCompat.CATEGORY_MESSAGE);
    

Essas informações sobre a categoria da notificação são usadas pelo sistema para tomar decisões sobre a exibição da notificação quando o dispositivo está no modo "Não perturbe".

No entanto, você não precisa definir uma categoria para todo o sistema. É necessário fazer isso apenas se suas notificações corresponderem a uma das categorias definidas em NotificationCompat.

Mostrar uma mensagem urgente

Seu app pode precisar exibir uma mensagem urgente e com limite de tempo, por exemplo, uma chamada telefônica recebida ou um alarme tocando. Nessas situações, você pode associar um intent de tela cheia à sua notificação. Quando a notificação é invocada, os usuários veem um dos seguintes itens, dependendo do status de bloqueio do dispositivo:

  • se o dispositivo do usuário estiver bloqueado, uma atividade de tela cheia será exibida, cobrindo a tela de bloqueio;
  • se o dispositivo do usuário estiver desbloqueado, a notificação aparecerá de forma estendida, incluindo opções para manipular ou descartar a notificação.

O snippet de código a seguir demonstra como associar sua notificação a um intent de tela cheia:

Kotlin

    val fullScreenIntent = Intent(this, ImportantActivity::class.java)
    val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

    var builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setFullScreenIntent(fullScreenPendingIntent, true)
    

Java

    Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
    PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
            fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setFullScreenIntent(fullScreenPendingIntent, true);
    

Definir a visibilidade da tela de bloqueio

Para controlar o nível de detalhes visível na notificação na tela de bloqueio, chame setVisibility() e especifique um dos seguintes valores:

  • VISIBILITY_PUBLIC: mostra todo o conteúdo da notificação;
  • VISIBILITY_SECRET: não mostra nenhuma parte da notificação na tela de bloqueio;
  • VISIBILITY_PRIVATE: exibe informações básicas, como o ícone e o título do conteúdo da notificação, mas oculta o conteúdo completo.

Quando VISIBILITY_PRIVATE é definido, é possível fornecer também uma versão alternativa do conteúdo da notificação que oculta determinados detalhes. Por exemplo, um app de SMS pode exibir uma notificação que mostre Você tem três novas mensagens de texto, mas ocultar o conteúdo e o remetente das mensagens. Para fornecer essa notificação alternativa, primeiro crie a notificação alternativa com NotificationCompat.Builder, como de costume. Depois, anexe a notificação alternativa à notificação normal com setPublicVersion().

No entanto, o usuário sempre tem o controle final sobre a exibição de notificações na tela de bloqueio e pode controlar isso com base nos canais de notificação do seu app.

Atualizar uma notificação

Para atualizar essa notificação após emiti-la, chame NotificationManagerCompat.notify() novamente, passando a ela uma notificação com o mesmo código usado anteriormente. Se a notificação anterior for dispensada, uma nova notificação será criada.

Você também pode chamar setOnlyAlertOnce() para que a notificação interrompa o usuário (com som, vibração ou dicas visuais) apenas na primeira vez que a notificação aparecer, e não nas atualizações posteriores.

Remover uma notificação

As notificações permanecem visíveis até que um dos seguintes casos aconteça:

  • o usuário dispense a notificação;
  • o usuário clique na notificação, e você chame setAutoCancel() quando a notificação é criada;
  • você chame cancel() para um código de notificação específico (esse método também exclui notificações contínuas);
  • você chame cancelAll(), que remove todas as notificações emitidas anteriormente;
  • o sistema cancela a notificação após um tempo específico que você define ao criá-la usando setTimeoutAfter() Se necessário, você pode cancelar uma notificação antes do término do tempo limite especificado.

Práticas recomendadas para apps de mensagens

Use as práticas recomendadas listadas aqui como uma referência rápida ao criar notificações para seus apps de mensagens e bate-papo.

Usar MessagingStyle

A partir do Android 7.0 (API de nível 24), o Android fornece um modelo de estilo de notificação especificamente para o conteúdo de mensagens. Usando a classe NotificationCompat.MessagingStyle, você pode alterar vários rótulos exibidos na notificação, incluindo o título da conversa, mensagens adicionais e a visualização de conteúdo para a notificação.

O snippet de código a seguir demonstra como personalizar o estilo de uma notificação usando a classe MessagingStyle.

Kotlin

    var notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setStyle(NotificationCompat.MessagingStyle("Me")
                    .setConversationTitle("Team lunch")
                    .addMessage("Hi", timestamp1, null) // Pass in null for user.
                    .addMessage("What's up?", timestamp2, "Coworker")
                    .addMessage("Not much", timestamp3, null)
                    .addMessage("How about lunch?", timestamp4, "Coworker"))
            .build()
    

Java

    Notification notification = new Notification.Builder(this, CHANNEL_ID)
            .setStyle(new NotificationCompat.MessagingStyle("Me")
                    .setConversationTitle("Team lunch")
                    .addMessage("Hi", timestamp1, null) // Pass in null for user.
                    .addMessage("What's up?", timestamp2, "Coworker")
                    .addMessage("Not much", timestamp3, null)
                    .addMessage("How about lunch?", timestamp4, "Coworker"))
            .build();
    

A partir do Android 8.0 (API de nível 26), as notificações que usam a classe NotificationCompat.MessagingStyle exibem mais conteúdo na forma recolhida. Você também pode usar o método addHistoricMessage() para fornecer contexto a uma conversa, adicionando mensagens históricas a notificações relacionadas a mensagens.

Quando usar NotificationCompat.MessagingStyle:

  • Chame MessagingStyle.setConversationTitle() para definir um título para bate-papos em grupo (com mais de duas pessoas). Um bom título para uma conversa pode ser o nome do bate-papo em grupo ou, se ele não tiver um nome específico, uma lista dos participantes da conversa. Sem isso, a mensagem pode ser entendida como uma conversa individual com o remetente da mensagem mais recente da conversa.
  • Use o método MessagingStyle.setData() para incluir mensagens de mídia, como imagens. Os tipos MIME do padrão image/* são aceitos no momento.

Usar resposta direta

O recurso "Resposta direta" permite que um usuário responda in-line a uma mensagem.

  • Depois que um usuário responder com uma ação de resposta in-line, use MessagingStyle.addMessage() para atualizar a notificação MessagingStyle e não retire nem cancele a notificação. O não cancelamento da notificação permite que um usuário envie várias respostas a partir da notificação.
  • Para tornar a ação de resposta in-line compatível com o Wear OS, chame Action.WearableExtender.setHintDisplayInlineAction(true).
  • Use o método addHistoricMessage() para fornecer contexto a uma conversa de resposta direta, adicionando mensagens históricas à notificação.

Ativar "Resposta inteligente"

  • Para ativar o recurso "Resposta inteligente", chame setAllowGeneratedResponses(true) na ação de resposta. Isso faz com que as respostas do recurso "Resposta inteligente" estejam disponíveis aos usuários quando a notificação é conectada a um dispositivo Wear OS. As respostas do recurso "Resposta inteligente" são geradas por um modelo de aprendizado de máquina no próprio relógio, usando o contexto fornecido pela notificação NotificationCompat.MessagingStyle, e nenhum dado é enviado para a Internet para gerar as respostas.

Adicionar metadados de notificação