📍 Cap 17: PokeMap: Onde estão os Treinadores?

🎯 Objetivo da Aula: Ao final desta aula, você entenderá como o GPS do celular funciona. Você aprenderá a capturar sua localização atual (Latitude e Longitude) e mostrar um mapa interativo do Google no seu aplicativo.


🏢 O Cenário Prático (Seu Desafio): Você está criando o PokeMap. O desafio é mostrar no mapa onde existem “Ginásios Pokémon” na sua cidade. Para isso, o app precisa saber onde você está agora para calcular a distância até o ginásio mais próximo.


🧠 Fundamentos: A Teoria Traduzida

📖 Dicionário do Programador

🎨 Padrão de Mapas

No Compose, usamos o componente GoogleMap. Para marcar um lugar específico, usamos um Marker (Pino).

graph LR
    A[Satélite] --> B[Celular: Lat -23, Long -46]
    B --> C{Mapa Google}
    C --> D["Você está aqui!"]

🏗️ Construindo o Projeto (Checklist Studio)

Para o mapa funcionar, você precisará de duas coisas:

  1. Permissão de Localização: Adicione ACCESS_FINE_LOCATION no seu Manifesto.
  2. API Key: Uma chave secreta que você gera no Google Cloud para o mapa abrir.

📦 Dependência Gradle

Para usar GoogleMap, Marker e LatLng no Compose, e para ler a localização real do GPS com FusedLocationProviderClient, adicione no build.gradle (Module: app), dentro de dependencies { }:

implementation 'com.google.maps.android:maps-compose:4.3.3'
implementation 'com.google.android.gms:play-services-maps:18.2.0'
implementation 'com.google.android.gms:play-services-location:21.2.0'

📦 Imports Necessários

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

import android.content.Context
import android.location.Location
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.compose.GoogleMap
import com.google.maps.android.compose.Marker
import com.google.maps.android.compose.MarkerState

📖 Exemplo Passo a Passo: Colocando o Marcador

Parte 1 — O Mapa:

@Composable
fun MapaGinasio() {
    val localGinasio = LatLng(-23.5505, -46.6333) // Coordenadas de exemplo
    
    GoogleMap(modifier = Modifier.fillMaxSize()) {
        // Colocando o pino no mapa
        Marker(
            state = MarkerState(position = localGinasio),
            title = "Ginásio Master",
            snippet = "Batalha de Nível 20"
        )
    }
}

Parte 2 — O GPS Real: o FusedLocationProviderClient é o “satélite” do Android. Ele entrega a última localização conhecida do celular via lastLocation, de forma assíncrona (addOnSuccessListener):

fun obterLocalizacaoAtual(context: Context) {
    val cliente: FusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(context)

    cliente.lastLocation.addOnSuccessListener { localizacao: Location? ->
        if (localizacao != null) {
            val minhaLat = localizacao.latitude
            val minhaLong = localizacao.longitude
            println("Você está em: $minhaLat, $minhaLong")
        } else {
            println("❌ Localização indisponível. O GPS está ativado?")
        }
    }
}

💡 Antes de chamar obterLocalizacaoAtual, o app precisa que o usuário tenha aceitado a permissão ACCESS_FINE_LOCATION (Checklist Studio acima).


🛠️ Prática Obrigatória 1: Pesquise e anote as coordenadas de Latitude e Longitude de um lugar famoso na sua cidade ou no mundo (ex: Estátua da Liberdade).


🛠️ Prática Obrigatória 2: Crie uma função chamada checarProximidade. Ela recebe a sua Latitude (Double) e a Latitude do Ginásio (Double). Se a diferença for menor que 0.001, o retorno deve ser "Você chegou ao Ginásio!".


🛠️ Prática Obrigatória 3: Usando obterLocalizacaoAtual como referência, crie a função verificarChegada(context: Context, latGinasio: Double). Dentro do addOnSuccessListener, se localizacao não for nulo, chame checarProximidade(localizacao.latitude, latGinasio) e mostre o resultado com println.


🔑 Gabarito Passo a Passo:

Exercício 2:

fun checarProximidade(minhaLat: Double, ginasioLat: Double): String {
    val diferenca = Math.abs(minhaLat - ginasioLat)
    return if (diferenca < 0.001) {
        "Você chegou ao Ginásio!"
    } else {
        "Continue andando..."
    }
}

Exercício 3:

fun verificarChegada(context: Context, latGinasio: Double) {
    val cliente: FusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(context)

    cliente.lastLocation.addOnSuccessListener { localizacao: Location? ->
        if (localizacao != null) {
            val resultado = checarProximidade(localizacao.latitude, latGinasio)
            println(resultado)
        }
    }
}

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

  1. Envie as coordenadas que você pesquisou.
  2. Envie o código das funções checarProximidade e verificarChegada.
  3. Submeta no canal de tarefas.

⬅️ Voltar para a Home