🔔 Cap 18: Alertas de Batalha: Notificações

🎯 Objetivo da Aula: Ao final desta aula, você entenderá como funcionam as Notificações Push. Você aprenderá a configurar o Firebase (FCM) para que seu app receba avisos mesmo quando estiver fechado, informando o jogador sobre novos desafios ou itens.


🏢 O Cenário Prático (Seu Desafio): Seu jogo é divertido, mas os jogadores esquecem de entrar! O desafio é criar o Sistema de Alerta: sempre que um novo evento começar, o celular do jogador deve vibrar e mostrar a mensagem: “⚔️ Nova Batalha na Arena! Clique para participar”.


🧠 Fundamentos: A Teoria Traduzida

📖 Dicionário do Programador

🎨 Padrão de Serviço

No Android, as notificações são processadas por um Service (um código que roda escondido, sem tela). Ele deve morar na pasta data/network/ ou em uma pasta services/.

graph TD
    A["Servidor do Game"] -->|Envia Alerta| B["Firebase Cloud Messaging"]
    B -->|Localiza Celular| C["App do Jogador"]
    C -->|Gera Popup| D["Aviso na Tela"]

🏗️ Construindo o Projeto (Checklist Studio)

Para usar notificações, você deve:

  1. Criar um projeto no Firebase Console.
  2. Baixar o arquivo google-services.json e colocar na pasta app/ do seu projeto.
  3. Declarar o serviço de mensagem no seu AndroidManifest.xml.

📦 Dependência Gradle

Para usar FirebaseMessagingService, configure o Firebase no projeto:

  1. No build.gradle do projeto (raiz), adicione o plugin:
    plugins {
        id 'com.google.gms.google-services' version '4.4.1' apply false
    }
    
  2. No build.gradle do app, aplique o plugin e adicione a dependência:
    plugins {
        id 'com.google.gms.google-services'
    }
    
    dependencies {
        implementation platform('com.google.firebase:firebase-bom:32.7.2')
        implementation 'com.google.firebase:firebase-messaging-ktx'
    }
    

💡 NotificationChannel, NotificationCompat e NotificationManagerCompat (usados abaixo para mostrar a notificação na tela) já vêm da dependência androidx.core:core-ktx, presente desde a criação do projeto no Cap 07 — não é necessário adicionar nada novo no Gradle para elas.

📦 Imports Necessários

Antes de copiar o código abaixo, adicione estes imports no topo do seu arquivo .kt:

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

📖 Exemplo Passo a Passo: O Recebedor de Alertas

Parte 1 — Criando o Canal e a Notificação: toda notificação precisa de um “Canal” (obrigatório a partir do Android 8) e de um NotificationCompat.Builder, que monta o aviso e o envia para a tela:

fun criarCanalNotificacao(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val canal = NotificationChannel(
            "canal_batalha",
            "Alertas de Batalha",
            NotificationManager.IMPORTANCE_HIGH
        )
        val manager = context.getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(canal)
    }
}

fun mostrarNotificacao(context: Context, titulo: String, mensagem: String) {
    val notificacao = NotificationCompat.Builder(context, "canal_batalha")
        .setContentTitle(titulo)
        .setContentText(mensagem)
        .setSmallIcon(android.R.drawable.ic_dialog_info)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .build()

    NotificationManagerCompat.from(context).notify(1, notificacao)
}

💡 O Canal de Notificação (NotificationChannel) existe porque, a partir do Android 8 (API 26), todo app precisa organizar seus alertas em grupos — o usuário pode silenciar o canal “Alertas de Marketing” mas manter ativo o canal “Alertas de Batalha”, por exemplo.

Parte 2 — O Recebedor de Alertas: crie a classe que fica “vigiando” a chegada de mensagens e usa as funções acima para avisar o jogador:

package br.com.curso.pokedex.services

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class AlertaService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        criarCanalNotificacao(this)

        val titulo = remoteMessage.notification?.title ?: "Novo Alerta"
        val mensagem = remoteMessage.notification?.body ?: "Algo novo aconteceu no jogo!"
        mostrarNotificacao(this, titulo, mensagem)
    }
}

🛠️ Prática Obrigatória 1: No seu AndroidManifest.xml, adicione a declaração do serviço AlertaService. Certifique-se de usar o caminho completo do pacote: br.com.curso.pokedex.services.AlertaService.


🛠️ Prática Obrigatória 2: Crie a função criarCanalItens(context: Context), parecida com criarCanalNotificacao, mas que cria um segundo canal com id "canal_itens", nome "Itens e Recompensas" e importância NotificationManager.IMPORTANCE_DEFAULT.


🛠️ Prática Obrigatória 3: Usando mostrarNotificacao como referência, crie a função mostrarNotificacaoItem(context: Context, nomeItem: String). Ela deve chamar criarCanalItens(context) e depois mostrar uma notificação no canal "canal_itens", com o título "🎒 Novo Item!" e a mensagem "Você recebeu: $nomeItem" (use o id 2 no notify, para não sobrescrever o alerta de batalha).


🔑 Gabarito Passo a Passo:

Exercício 1 (XML):

<service
    android:name="br.com.curso.pokedex.services.AlertaService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Exercício 2:

fun criarCanalItens(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val canal = NotificationChannel(
            "canal_itens",
            "Itens e Recompensas",
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val manager = context.getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(canal)
    }
}

Exercício 3:

fun mostrarNotificacaoItem(context: Context, nomeItem: String) {
    criarCanalItens(context)

    val notificacao = NotificationCompat.Builder(context, "canal_itens")
        .setContentTitle("🎒 Novo Item!")
        .setContentText("Você recebeu: $nomeItem")
        .setSmallIcon(android.R.drawable.ic_dialog_info)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .build()

    NotificationManagerCompat.from(context).notify(2, notificacao)
}

📤 Instruções de Entrega (Microsoft Teams):

  1. Envie o print do seu Manifesto configurado.
  2. Envie o código das funções criarCanalItens e mostrarNotificacaoItem.
  3. Submeta no canal de tarefas.

⬅️ Voltar para a Home