Table of Contents
🤖 Spec Mobile Nativo Ios
"A educação é a arma mais poderosa que você pode usar para mudar o mundo." — Nelson Mandela (Adaptado para Tecnologia)
🧭 Atalhos Rápidos
-
Trilha de Aprendizagem --- Veja o Mapa da Jornada.
-
Slides Interativos --- Acesse as Apreasentações.
-
Quizzes de Revisão --- Teste seus Conhecimentos.
-
Projetos Práticos --- Mão na massa nos Projetos.
-
Exercícios --- Pratique com Desafios.
-
Setups --- Configure seu Ambiente.
🗺️ Mapa da Jornada
O curso está dividido em 4 Módulos Estratégicos projetados para uma progressão cognitiva sólida.
- Módulo 1: Fundamentos e Conceitos Iniciais.
- Módulo 2: Aprofundamento Técnico.
- Módulo 3: Prática e Consolidação.
- Módulo 4: Especialização e Projeto Final.
Aulas
Aulas do Curso 📚
Acesse aqui todo o conteúdo teórico dividido em trilhas de conhecimento.
-
Módulo 1: Fundamentos e UI --- A base do desenvolvimento mobile e interfaces modernas.
-
Módulo 2: Arquitetura e Dados --- Organização de código profissional e persistência.
-
Módulo 3: Listas e APIs --- Consumo de dados e performance.
-
Módulo 4: Qualidade e Hardware --- Recursos nativos e publicação.
Aula 01 - Introdução ao Desenvolvimento Mobile 📱
Objetivo
Objetivo: Compreender o panorama do desenvolvimento mobile, diferenciar tecnologias (Nativo, Híbrido, Web) e preparar o terreno para o desenvolvimento Android com comparações ao iOS.
1. Panorama do Mercado Mobile 🌍
O mundo hoje é mobile-first. Antes de codificarmos, precisamos entender onde estamos pisando. Existem basicamente três caminhos para criar um app:
📱 Nativo
- O que é: Apps desenvolvidos na linguagem oficial da plataforma.
- Android: Java ou Kotlin (usando Android Studio).
- iOS: Objective-C ou Swift (usando Xcode).
- Vantagens: Performance máxima, acesso total ao hardware, melhor experiência de usuário (UX).
- Desvantagens: Custo mais alto (duas bases de código).
🌐 Web (PWA)
- O que é: Sites que parecem apps. Rodam no navegador.
- Tecnologias: HTML, CSS, JavaScript.
- Vantagens: Rápido de fazer, funciona em tudo.
- Desvantagens: Sem acesso a muitos recursos nativos, performance limitada.
🧩 Híbrido / Cross-Platform
- O que é: Uma base de código que gera apps para ambas as plataformas.
- Tecnologias: Flutter (Dart), React Native (JS), KMP (Kotlin).
- Vantagens: Custo reduzido.
- Desvantagens: Performance pode não ser igual à nativa em casos complexos.
Nossa Escolha
Neste curso, focaremos no Nativo (Android), pois é a base de tudo. Quem sabe nativo entende como os frameworks híbridos funcionam por baixo dos panos.
2. Ecossistema: Android vs iOS 🤖🍎
Vamos comparar os dois gigantes:
| Característica | 🤖 Android (Google) | 🍎 iOS (Apple) |
|---|---|---|
| Linguagem Principal | Kotlin (Java legado) | Swift (Obj-C legado) |
| IDE (Ferramenta) | Android Studio | Xcode |
| Sistema Operacional | Linux (Kernel modificado) | Darwin (Unix-like) |
| Loja de Apps | Google Play Store | Apple App Store |
| Arquivos de App | .apk / .aab | .ipa |
| Publicação | Mais flexível, taxa única ($25) | Mais rígida, taxa anual ($99) |
Comparativo Visual (Mermaid)
graph LR
subgraph Android
A[Linux Kernel] --> B[HAL]
B --> C[Runtime ART]
C --> D[Framework Java/Kotlin]
D --> E[Apps]
end
subgraph iOS
F[Core OS] --> G[Core Services]
G --> H[Media]
H --> I[Cocoa Touch]
I --> J[Apps]
end
3. Ferramentas de Desenvolvimento 🛠️
Android Studio
É a IDE oficial, baseada no IntelliJ IDEA (JetBrains). Poderosa, cheia de recursos, mas... pesada.
Requisitos Mínimos
Para rodar o Android Studio confortavelmente, recomenda-se pelo menos 8GB de RAM (ideal 16GB) e SSD. Sem SSD, a dor é real. 😢
Xcode
É a IDE oficial da Apple. Só roda em macOS. É conhecida por ser um pouco mais visual no design de telas (Storyboards), embora o Android Studio tenha evoluído muito com o Layout Editor.
4. Estrutura Básica de um Projeto 📂
Quando criamos um "Hello World", o que realmente é criado?
No Android (Gradle Project)
Use o terminal abaixo para explorar a estrutura típica:
$ tree MyFirstApp
MyFirstApp
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/ (Código Kotlin/Java)
│ │ │ ├── res/ (Recursos: Imagens, XMLs)
│ │ │ │ ├── layout/ (Telas)
│ │ │ │ ├── values/ (Cores, Textos)
│ │ │ └── AndroidManifest.xml
│ └── build.gradle (Configurações do App)
├── build.gradle (Configurações do Projeto)
└── settings.gradle
🆚 Comparação com iOS (Xcode Project)
AndroidManifest.xml≈Info.plist(Configurações essenciais e permissões).res/layout/*.xml≈.storyboardou.xib(Arquivos de interface).build.gradle≈project.pbxproj(mas muito mais legível e editável!).
5. Por que Kotlin? E o Java? 🤔
O Android nasceu com Java. É uma linguagem robusta, mas verbosa. Em 2017, o Google anunciou Kotlin como linguagem oficial.
- Java:
- Verbo:
System.out.println("Olá"); - NullpointerException: O pesadelo dos devs. 👻
- Verbo:
- Kotlin:
- Conciso:
println("Olá") - Null Safety: O compilador te protege de valores nulos! 🛡️
- Conciso:
Dica de Mestre
Aprenderemos Java nas próximas aulas para ter base sólida, e depois migraremos para Kotlin, que é o padrão moderno. Isso te tornará um desenvolvedor completo, capaz de manter sistemas legados e criar novos.
6. Mini-Projeto: Configurando o Ambiente 🚀
Sua missão para a próxima aula não é codar, é preparar o terreno.
- Baixar e instalar o Android Studio (Ladybug ou versão mais recente).
- Baixar e instalar o JDK 17 ou 21 (Java Development Kit).
- Configurar as Variáveis de Ambiente (JAVA_HOME).
Veja o passo a passo detalhado na seção Configuração > Setup Android.
7. Exercício de Fixação 🧠
Para fixar os conceitos de hoje, responda:
- Qual a principal diferença de custo de publicação entre Google Play e App Store?
- Se eu quiser um app que acesse o Bluetooth de forma extremamente performática, devo escolher Nativo ou Web? Por que?
- O que é o
AndroidManifest.xmle qual seu equivalente no iOS?
Próxima Aula: Vamos colocar a mão na massa com Fundamentos de Java para Android! ☕
Aula 02 - Fundamentos de Java para Android ☕
Objetivo
Objetivo: Dominar a sintaxe do Java, focando nos conceitos essenciais para o desenvolvimento Android (POO) e comparando com a rigidez do Swift/iOS.
1. Por que estudar Java em 202X? 🦖
Java é a base do Android. Mesmo que você use Kotlin (o que faremos a partir da Aula 03), todo o sistema operacional Android e suas bibliotecas antigas foram escritos em Java.
- Entender Java = Entender como o Android funciona "por baixo do capô".
- Muitos projetos legados ainda usam Java.
2. A Estrutura de uma Classe 🏗️
Em Java, tudo é um objeto (ou quase tudo).
// Nome da classe deve começar com Maiúscula (PascalCase)
public class Pessoa {
// Atributos (Variáveis de Classe)
String nome;
int idade;
// Construtor
public Pessoa(String nome, int idade) {
this.nome = nome;
this.idade = idade;
}
// Método (Função)
public void apresentar() {
System.out.println("Olá, eu sou " + nome);
}
}
🆚 Comparação com Swift (iOS)
| Característica | ☕ Java | 🐦 Swift |
|---|---|---|
| Pontos e vírgulas | Obrigatórios ; |
Opcionais (e não usados) |
| Tipagem | Estática e Explícita (geralmente) | Estática e Inferida (muito forte) |
| Variáveis | String nome = "Ana"; |
var nome = "Ana" |
| Constantes | final String NOME = "Ana"; |
let nome = "Ana" |
3. Tipos Primitivos e Wrappers 📦
Java tem uma peculiaridade: tipos primitivos (leves) e objetos (pesados/wrappers).
int(primitivo) vsInteger(classe/wrapper).double(primitivo) vsDouble(classe/wrapper).boolean(primitivo) vsBoolean(classe/wrapper).
Atenção ao Null
Um int nunca pode ser null (padrão é 0).
Um Integer pode ser null.
Isso causa o temido NullPointerException se você tentar somar um Integer que está nulo! 💥
4. Orientação a Objetos (POO) no Android 🧬
O Android usa POO o tempo todo.
🧩 Herança (extends)
A base de tudo. Uma Activity (tela) é filha da classe AppCompatActivity.
🆚 Comparação: Herança
classDiagram
class Animal {
+respirar()
}
class Cachorro {
+latir()
}
class Gato {
+miar()
}
Animal <|-- Cachorro : extends
Animal <|-- Gato : extends
No iOS (Swift), a herança funciona igual, mas a sintaxe é class Cachorro: Animal.
5. Estruturas de Controle e Coleções control
ArrayList vs Array
No Android, raramente usamos arrays fixos (String[]). Usamos listas dinâmicas:
// Java - Verboso
ArrayList<String> lista = new ArrayList<>();
lista.add("Item 1");
lista.add("Item 2");
// Swift - Conciso
var lista = ["Item 1", "Item 2"]
Loops (For-Each)
6. Null Safety (O problema de 1 bilhão de dólares) 💸
Em Java, qualquer objeto pode ser nulo. Você deve verificar manualmente:
Em Swift (e Kotlin), o sistema de tipos impede isso por padrão.
7. Exercício Prático (Mental) 🧠
Imagine que você está migrando um código iOS para Android.
Código Swift:
Como ficaria em Java?
8. Desafio: A Classe 'Carro' 🚗
- Crie uma classe
Carroem Java. - Adicione atributos
modelo(String) eano(int). - Crie um método
ligarMotor()que imprime "Vrum!". - No método
main, instancie 2 carros diferentes.
Próxima Aula: Chega de verbosidade! Vamos conhecer o Kotlin, a linguagem moderna do Android e prima do Swift. Introdução ao Kotlin 🚀
Aula 03 - Introdução ao Kotlin 💜
Objetivo
Objetivo: Aprender Kotlin, a linguagem oficial do Android, e perceber como ela resolve os problemas do Java e se assemelha incrivelmente ao Swift.
1. Por que Kotlin? 🚀
Em 2017, o Google tornou o Kotlin oficial. Por quê? * Conciso: Menos código para fazer a mesma coisa. * Seguro: Null Safety integrado. * Interoperável: Funciona 100% com código Java existente.
"Kotlin é o que o Java seria se tivesse sido criado hoje."
2. Sintaxe Básica: var vs val 📦
Esqueça o String nome = .... O Kotlin infere os tipos!
var: Variável (pode mudar).val: Valor (imutável - constante). Use sempre que possível!
var idade = 25
idade = 26 // OK
val nome = "Ricardo"
// nome = "João" // ERRO! Val cannot be reassigned
🆚 Comparação com Swift (iOS)
É idêntico! 😱
| Recurso | 💜 Kotlin | 🐦 Swift |
|---|---|---|
| Variável | var x = 10 |
var x = 10 |
| Constante | val y = 20 |
let y = 20 |
| Função | fun somar() {} |
func somar() {} |
println("Oi") |
print("Oi") |
3. Null Safety: Adeus NullPointerException 👋
No Kotlin, você precisa dizer explicitamente se uma variável aceita nulo.
var texto: String = "Não pode ser nulo"
// texto = null // Erro de compilação!
var textoNulo: String? = "Pode ser nulo"
textoNulo = null // OK
Operadores Seguros
-
Safe Call (
?.): Só chama se não for nulo. -
Elvis Operator (
?:): Valor padrão se for nulo.
4. Funções e Expressões 𝑓(𝑥)
// Forma tradicional
fun somar(a: Int, b: Int): Int {
return a + b
}
// Single-Expression (One-liner)
fun somarCurto(a: Int, b: Int) = a + b
Use e abuse de Single-Expression functions para deixar o código limpo.
5. Classes de Dados (Data Classes) 💾
Lembra da classe Pessoa da aula passada? Em Kotlin é uma linha:
O data class já gera automaticamente: toString(), equals(), hashCode() e copy().
🆚 Comparação: Structs (Swift)
No iOS, usamos struct para dados leves, que é muito similar ao data class, mas passado por valor.
6. Exercício Interativo (Termynal) 💻
Vamos testar o REPL do Kotlin (ambiente de teste rápido). Imagine digitando isso no terminal:
$ kotlinc
Welcome to Kotlin version 1.9.0 (JRE 17.0.8)
>>> val lista = listOf("Android", "iOS", "Web")
>>> lista.filter { it.length > 3 }
[Android, Web]
>>> quit
7. Extensions: O Poder do Kotlin 💪
Você pode adicionar funções a classes que você não criou (como String ou Int).
No Swift, isso se chama extension e funciona exatamente igual.
8. Desafio: Tradutor Java -> Kotlin 🔄
Converta este código Java mentalmente:
String texto = null;
if (texto != null) {
System.out.println(texto.toUpperCase());
} else {
System.out.println("Vazio");
}
Próxima Aula: Agora que sabemos a linguagem, vamos entender o Android! Estrutura de um App Android 📱
Aula 04 - Estrutura de um App Android 🏗️
Objetivo
Objetivo: Entender a anatomia de um projeto Android, o ciclo de vida de uma Activity e como o XML desenha a tela.
1. O Manifesto (AndroidManifest.xml) 📜
É a certidão de nascimento do App. * Define o nome e ícone do app. * Lista as Activities (Telas). * Pede Permissões (Internet, Câmera, GPS).
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application ...>
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
🆚 Comparação: Info.plist (iOS)
No iOS, o Info.plist tem função similar, definindo permissões e configurações de inicialização.
2. Activity: A Tela de Verdade 🖼️
Uma Activity é uma classe que controla uma tela. Ela não é a tela (visual), ela controla a tela.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) // Liga o XML da tela
}
}
🆚 Comparação: UIViewController (iOS)
Activity ≈ UIViewController. Ambos gerenciam o ciclo de vida da tela e a interação com o usuário.
3. O Ciclo de Vida (Lifecycle) 🔄
Uma Activity nasce, vive e morre. O Android avisa a Activity quando isso acontece.
onCreate(): Nasceu. Configure a tela aqui. (Só roda 1 vez).onStart(): Ficou visível.onResume(): Usuário pode interagir.onPause(): Perdeu o foco (ex: um diálogo abriu).onStop(): Não está mais visível (ex: usuário foi pra Home).onDestroy(): Morreu. Libere memória.
graph TD
Start((Início)) --> OnCreate[onCreate]
OnCreate --> OnStart[onStart]
OnStart --> OnResume[onResume]
OnResume --> User{Interagindo}
User -- Saiu --> OnPause[onPause]
OnPause --> OnStop[onStop]
OnStop -- Voltou --> OnRestart[onRestart]
OnRestart --> OnStart
OnStop -- Fechou --> OnDestroy[onDestroy]
OnDestroy --> End((Fim))
🆚 Comparação: iOS Lifecycle
onCreate≈viewDidLoadonStart≈viewWillAppearonResume≈viewDidAppear
4. Layouts XML: Desenhando a UI 🎨
O Android separa a Lógica (Kotlin) do Layout (XML).
Arquivos ficam em res/layout/.
<!-- LinearLayout: Organiza itens em fila (Vertical ou Horizontal) -->
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Olá, Android!"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="Clique aqui"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
🆚 Comparação: XIBs e Storyboards
No iOS, usamos arquivos .xib ou .storyboard, mas o XML interno é ilegível para humanos. No Android, editar o XML na mão é comum e poderoso!
5. ViewBinding: Chega de findViewById 🔗
Antigamente, para pegar um botão no código:
Hoje, usamos ViewBinding:
O ViewBinding gera uma classe que conecta o XML ao Kotlin automaticamente.
6. Resources (R.) 📦
Tudo que não é código fica na pasta res:
No Android (Gradle Project)
Explore a estrutura típica de um projeto Android:
Regra de Ouro: Nunca coloque texto fixo ("Hardcoded") no código ou XML. Use
@string/meu_texto.
7. Desafio: O Ciclo da Vida Real 🧬
Cenário: O usuário está preenchendo um formulário no seu app. Ele recebe uma ligação. 1. Qual método do ciclo de vida é chamado quando a ligação toca (e cobre a tela)? 2. O que acontece se o Android estiver sem memória enquanto ele atende a ligação?
Resposta
onPause()e depoisonStop().- O Android pode matar o processo da Activity (
onDestroy()pode nem ser chamado!). Por isso devemos salvar os dados noonSaveInstanceState()ou ViewModel.
Próxima Aula: Vamos deixar o app bonito! Interface Gráfica (Layouts e Views) 🖌️
Aula 05 - Interface Gráfica (UI) 🎨
Objetivo
Objetivo: Entender o sistema de Layouts do Android, diferenciar ViewGroups de Views e criar telas complexas usando ConstraintLayout e LinearLayout.
1. Views e ViewGroups 🧱
No Android, tudo que você vê é uma View (Botão, Texto, Imagem).
Tudo que organiza as Views é um ViewGroup (Layout).
graph TD
VG[ViewGroup / Layout] --> V1[View: TextView]
VG --> V2[View: Button]
VG --> VG2[ViewGroup: LinearLayout]
VG2 --> V3[View: ImageView]
Principais Componentes (Views)
TextView: Exibe texto (Label).EditText: Entrada de texto (Input).Button: Botão clicável.ImageView: Exibe imagens.CheckBox/RadioButton: Seleção.
2. Layouts Fundamentais 📐
A. LinearLayout (Simples e Rápido)
Organiza itens em uma única direção: Vertical ou Horizontal.
<LinearLayout
android:orientation="vertical" ...>
<Button android:text="Botão 1" />
<Button android:text="Botão 2" />
</LinearLayout>
layout_weight): Define quanto espaço o componente ocupa proporcionalmente.
B. FrameLayout (Empilhamento)
Coloca uma View em cima da outra (estilo "sanduíche"). Usado para overlays.
C. ConstraintLayout (O Poderoso) 💪
O padrão moderno. Permite criar layouts complexos e responsivos sem aninhamento excessivo ("flat hierarchy"). Funciona com "amarras" (constraints): * O botão A fica à direita do botão B e abaixo do Texto C.
<Button
app:layout_constraintTop_toBottomOf="@+id/textoTitulo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
🆚 Comparação: Auto Layout (iOS)
ConstraintLayout é muito similar ao Auto Layout no iOS. Ambos usam âncoras e restrições para definir posição e tamanho relativo.
3. Unidades de Medida: dp e sp 📏
Nunca use px (pixels)! O Android roda em milhares de telas diferentes.
- dp (Density-independent Pixels): Para tamanho de componentes e margens. 1dp é aproximadamente 1/160 polegada.
- sp (Scale-independent Pixels): Para tamanho de fonte. Respeita a configuração de acessibilidade do usuário (se ele aumentou a fonte do sistema).
Regra: Largura/Altura/Margem =
dp. Texto =sp.
4. Estilos e Temas (Themes) 💅
Para não repetir código (ex: todo botão ser azul), usamos estilos.
Arquivo: res/values/themes.xml (ou styles.xml).
<style name="BotaoPadrao" parent="Widget.MaterialComponents.Button">
<item name="android:backgroundTint">@color/purple_500</item>
<item name="android:textSize">16sp</item>
</style>
No layout: style="@style/BotaoPadrao"
5. ViewBinding na Prática 🔗
Vamos ligar o XML ao Kotlin.
Suponha um activity_login.xml com um EditText (edtEmail) e um Button (btnLogin).
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnLogin.setOnClickListener {
val email = binding.edtEmail.text.toString()
if (email.isNotBlank()) {
// Fazer login
} else {
binding.edtEmail.error = "Digite o e-mail!"
}
}
}
}
6. Eventos de Clique (Listeners) 🖱️
O jeito clássico de detectar toque: OnClickListener.
Em Swift (iOS), usamos @IBAction arrastando do Storyboard ou addTarget via código. O conceito é o mesmo: uma função que reage a um evento.
7. Exercício Prático: Tela de Login 📝
Crie uma tela de login simples:
1. ConstraintLayout como raiz.
2. ImageView (Logo) no topo, centralizado.
3. TextInputLayout + TextInputEditText para E-mail (Abaixo da logo).
4. TextInputLayout + TextInputEditText para Senha (Abaixo do e-mail).
5. Button "Entrar" (Largo, match_parent ou preenchendo largura com margens).
6. TextView "Esqueci a senha" (Abaixo do botão).
Dica: Use o Design Editor do Android Studio para arrastar e soltar as constraints!
Próxima Aula: Como sair dessa tela e ir para outra? Navegação entre Telas 🗺️
Aula 06 - Navegação entre Telas 🗺️
Objetivo
Objetivo: Aprender a navegar entre Activities usando Intents, passar dados entre telas e entender a pilha de navegação (Back Stack).
1. O que é uma Intent? 📨
Uma Intent (Intenção) é uma mensagem que o Android usa para pedir uma ação.
* "Quero abrir a tela de Login".
* "Quero abrir a Câmera".
* "Quero compartilhar esse texto".
Tipos de Intent
- Explícita: Você diz exatamente qual classe abrir. (Navegação interna).
- Ex: Ir da Home para Detalhes.
- Implícita: Você diz o que quer fazer, e o Android procura quem resolva.
- Ex: Abrir um site (Navegador), Tirar foto (App de Câmera).
2. Navegando para outra Activity 🚀
🆚 Comparação: Segues e NavigationController (iOS)
No iOS, usamos performSegue ou navigationController?.pushViewController(...).
A Intent do Android funciona como o "empurrão" para a próxima tela.
3. Passando Dados (Extras) 📦
Como enviar o nome do usuário para a próxima tela?
Activity A (Origem):
val intent = Intent(this, HomeActivity::class.java)
intent.putExtra("NOME_USUARIO", "Ricardo")
intent.putExtra("ID_USUARIO", 123)
startActivity(intent)
Activity B (Destino):
val nome = intent.getStringExtra("NOME_USUARIO")
val id = intent.getIntExtra("ID_USUARIO", -1) // -1 é valor padrão
🆚 Comparação: Prepare for Segue (iOS)
No iOS, interceptamos a navegação no método prepare(for:sender:) para configurar as propriedades da próxima ViewController. No Android, os dados vão "empacotados" na Intent.
4. A Pilha de Voltar (Back Stack) 📚
O Android gerencia as telas como uma pilha de cartas.
1. Abre A. (Pilha: [A])
2. A chama B. (Pilha: [A, B])
3. B chama C. (Pilha: [A, B, C])
4. Usuário aperta Voltar (Back).
* C é destruída (onDestroy).
* Voltamos para B (onResume). (Pilha: [A, B])
Finalizando uma Activity
Se você chamar finish() na Activity A, ela sai da pilha.
* Útil para tela de Login (após logar, não queremos voltar para o login).
5. Navigation Component (Moderno) 🧭
Existe uma forma mais moderna de navegar usando Fragments e um gráfico visual (Navigation Graph). * Single Activity Architecture: Uma única Activity hospeda vários Fragments (telas). * XML de Navegação: Define visualmente as setas de uma tela pra outra.
Neste curso focaremos em Intents pois é a base fundamental. O Navigation Component abstrai as Intents por baixo.
6. Intents Implícitas (Abrindo outros apps) 🌍
Quer abrir um site?
val siteIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com"))
startActivity(siteIntent)
Discar um número?
val discarIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:123456789"))
startActivity(discarIntent)
7. Desafio: O Fluxo de Login 🔐
Desenhe o fluxo (no papel ou Mermaid) e implemente o código:
1. Tela Splash: Exibe logo por 2 segundos e vai pra Login. (Usa Handler ou Coroutines para esperar, depois finish()).
2. Tela Login: Digita dados -> Botão Entrar -> Vai pra Home e mata Login.
3. Tela Home: Tem botão "Perfil" -> Vai pra Perfil (sem matar Home).
4. Tela Perfil: Botão "Sair" -> Limpa tudo e volta pra Login.
Dica: Para "limpar tudo" no Logout, use flags na Intent:
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
Próxima Aula: Chega de jogar código na Activity! Vamos organizar a casa com Arquitetura MVVM 🏗️
Aula 07 - Arquitetura Moderna (MVVM) 🏗️
Objetivo
Objetivo: Entender por que não devemos colocar toda a lógica na Activity (God Class) e aprender o padrão MVVM (Model-View-ViewModel), recomendado pelo Google.
1. O Problema da "God Activity" 🦸♂️
Se você colocar lógica de banco de dados, validação, chamadas de API e controle de UI tudo na MainActivity, ela vai virar um monstro de 2.000 linhas.
* Dificil de testar.
* Dificil de manter.
* Perde dados ao girar a tela (rotação destrói a Activity).
2. O Padrão MVVM 📐
Separamos as responsabilidades em 3 camadas:
- Model: Dados e Lógica de Negócio (Banco, API, Classes de Dados).
- View: UI (Activity/Fragment/XML). Só exibe dados e captura cliques. Não pensa!
- ViewModel: O cérebro da tela. Guarda o estado (dados) e sobrevive à rotação de tela.
graph LR
View["View (Activity/XML)"] <-->|Observa| VM[ViewModel]
VM -->|Pede Dados| Model["Model (Repository)"]
Model -->|Retorna Dados| VM
🆚 Comparação: MVC (iOS Clássico) vs MVVM
No iOS antigo (MVC), a ViewController fazia o papel de View e Controller, sofrendo do mesmo problema ("Massive View Controller"). Hoje, iOS também usa muito MVVM (com SwiftUI ou UIKit).
3. ViewModel e LiveData 📡
ViewModel
Classe que herda de androidx.lifecycle.ViewModel.
class MainViewModel : ViewModel() {
// LiveData: Um dado observável
val textoBemVindo = MutableLiveData<String>()
fun carregarDados() {
// Simula busca de dados
textoBemVindo.value = "Olá, Aluno!"
}
}
LiveData
É um container de dados que respeita o ciclo de vida. A View "observa" o LiveData. Se a View morrer (onDestroy), ela para de observar automaticamente.
4. Conectando na Activity (View) 🔌
class MainActivity : AppCompatActivity() {
// 1. Instanciar o ViewModel (forma moderna)
private val viewModel: MainViewModel by viewModels()
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 2. Observar o LiveData
viewModel.textoBemVindo.observe(this) { novoTexto ->
// Toda vez que o valor mudar, isso roda automaticamente!
binding.txtTitulo.text = novoTexto
}
binding.btnCarregar.setOnClickListener {
viewModel.carregarDados()
}
}
}
5. Vantagens do MVVM
- Rotação de Tela: Se girar o celular, a Activity morre e recria. O ViewModel NÃO morre. Os dados continuam lá (
novoTextojá estará carregado). - Testabilidade: É fácil testar o ViewModel sem precisar de emulador Android.
- Separação: O designer mexe no XML, o dev mexe no ViewModel.
6. Data Binding (O próximo nível) 🧬
Podemos ligar o XML direto no ViewModel, sem nem precisar de código na Activity para atualizar textos.
XML:
(Não aprofundaremos Data Binding agora, focaremos no ViewBinding + LiveData/Flow).7. Desafio: Contador MVVM 🔢
Crie um app "Contador de Cliques".
1. Sem MVVM: Variável count na Activity. Gire a tela. O contador zera? (Sim).
2. Com MVVM: Mova a variável count para um ViewModel (MutableLiveData<Int>).
* Botão chama viewModel.incrementar().
* Activity observa e atualiza o TextView.
* Gire a tela. O contador zera? (Não! 🤩).
Próxima Aula: Onde guardar esses dados para sempre? Persistência de Dados 💾
Aula 08 - Persistência de Dados 💾
Objetivo
Objetivo: Aprender a salvar dados localmente no dispositivo, desde preferências simples (SharedPreferences) até banco de dados estruturado (Room/SQLite).
1. Tipos de Armazenamento Local
- SharedPreferences: Chave-Valor. Para configurações simples (Ex: "Modo Escuro ativado", "Nome do Usuário").
- Banco de Dados (SQLite/Room): Dados estruturados, relacionais. (Ex: Lista de tarefas, cache de produtos offline).
- Arquivos: Fotos, PDF, áudios.
2. SharedPreferences 🔑
Simples, rápido, mas limitado.
// Gravar
val prefs = getSharedPreferences("minhas_config", Context.MODE_PRIVATE)
prefs.edit().putString("username", "Ricardo").apply()
// Ler
val usuario = prefs.getString("username", "Visitante") // Valor padrão
🆚 Comparação: UserDefaults (iOS)
No iOS, o equivalente exato é o UserDefaults.standard. Mesma lógica de chave-valor para configurações leves.
3. Banco de Dados: SQLite e Room 🏛️
O Android vem com SQLite embutido. Mas usar SQLite puro (SQL cru) é verboso e propenso a erros. O Google criou o Room, uma biblioteca que facilita o uso do SQLite (faz parte do Jetpack).
Arquitetura do Room
- Entity: A tabela (Classe de dados).
- DAO (Data Access Object): Os comandos (Insert, Select, Delete).
- Database: O ponto de acesso principal.
classDiagram
class User {
+id: Int
+nome: String
}
class UserDao {
+insert(user)
+getAll()
}
class AppDatabase {
+userDao()
}
AppDatabase --> UserDao : Contém
UserDao --> User : Manipula
4. Implementando o Room 🔨
Passo 1: Entity (Tabela)
@Entity(tableName = "tarefas")
data class Tarefa(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val titulo: String,
val concluida: Boolean
)
Passo 2: DAO (comandos)
@Dao
interface TarefaDao {
@Insert
suspend fun inserir(tarefa: Tarefa)
@Query("SELECT * FROM tarefas")
fun listarTodas(): LiveData<List<Tarefa>>
}
Passo 3: Database
@Database(entities = [Tarefa::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun tarefaDao(): TarefaDao
}
5. Threads e Room: OBRIGATÓRIO 🧵
O Room proíbe acesso ao banco na Thread Principal (UI Thread). Se você tentar ler/gravar na thread principal, o app trava a tela.
Por isso usamos suspend fun (Coroutines) ou LiveData (Async).
(Veremos Coroutines a fundo na Aula 11, mas o Room já nos força a usar ou aceitar o padrão assíncrono).
6. Comparação: Core Data / SwiftData (iOS)
- SQLite/Room (Android): Mais próximo do SQL tradicional. Você cria as queries.
- Core Data (iOS): Um framework de grafo de objetos, muito poderoso mas complexo. Abstrai totalmente o banco.
- SwiftData (iOS Novo): Mais parecido com o Room, usa macros e é bem simples.
7. Desafio: Lista de Compras Persistente 🛒
Crie um app simples com:
1. Um EditText e um Button "Adicionar".
2. Ao clicar, salva o item no Room.
3. (Bônus) Exiba a quantidade de itens salvos em um TextView.
4. Feche o app e abra de novo. Os itens devem continuar lá!
Próxima Aula: Como exibir essa lista de compras de forma eficiente? Listas e RecyclerView 📋
Aula 09 - Listas Eficientes (RecyclerView) 📋
Objetivo
Objetivo: Dominar a criação de listas de alta performance com RecyclerView, entender o padrão Adapter/ViewHolder e lidar com cliques em itens.
1. O Problema da ListView Antiga 🐢
Antigamente, usávamos ListView. Ela criava uma View para cada item da lista.
Se você tivesse 1.000 contatos, ela tentava criar 1.000 layouts. Resultado: travamentos e consumo absurdo de memória.
2. A Solução: Reciclagem de Views ♻️
O RecyclerView nasceu para ser inteligente. Se cabem 10 itens na tela, ele cria ~12 Views. Quando você rola para baixo, o item que saiu do topo (Item 1) é reciclado e volta para baixo para exibir o Item 13. Apenas o conteúdo (texto/imagem) muda, a View é reaproveitada.
graph TD
A[Item 1 sai da tela] --> B(Piscina de Reciclagem)
B --> C[Item 13 entra na tela]
C --> D{Reusa Layout do Item 1?}
D -- Sim --> E[Apenas troca o texto]
🆚 Comparação: UITableView (iOS)
O mecanismo é idêntico ao dequeueReusableCell do UITableView no iOS.
* Android: RecyclerView + Adapter + ViewHolder
* iOS: UITableView + DataSource + UITableViewCell
3. Os 3 Mosqueteiros do RecyclerView ⚔️
Para fazer funcionar, precisamos de 3 peças:
- LayoutManager: Define como organizar (Lista vertical? Grade? Carrossel?).
- Adapter: O cérebro. Pega os dados e coloca nas Views.
- ViewHolder: A gaveta. Guarda as referências dos componentes (
findViewById) para não buscar toda hora.
Implementação do Adapter
class ContatoAdapter(private val lista: List<Contato>) :
RecyclerView.Adapter<ContatoAdapter.ViewHolder>() {
// 1. Cria a gaveta (Layout)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_contato, parent, false)
return ViewHolder(view)
}
// 2. Preenche a gaveta com dados (Reciclagem)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(lista[position])
}
// 3. Quantos itens tem?
override fun getItemCount() = lista.size
// A Gaveta
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(contato: Contato) {
itemView.findViewById<TextView>(R.id.txtNome).text = contato.nome
}
}
}
4. LayoutManagers: Flexibilidade Total 🤸
Apenas trocando uma linha, você muda a cara da lista:
- LinearLayoutManager: Lista padrão (Vertical ou Horizontal).
- GridLayoutManager: Grade (Ex: Galeria de fotos).
- StaggeredGridLayoutManager: Grade assimétrica (Ex: Pinterest).
5. Lidando com Cliques 👆
O RecyclerView não tem OnItemClickListener nativo fácil como a ListView.
Geralmente passamos uma função (lambda) para o Adapter.
No Adapter:
class ContatoAdapter(
private val lista: List<Contato>,
private val onClick: (Contato) -> Unit // Callback
) ... {
override fun onBindViewHolder(...) {
holder.itemView.setOnClickListener {
onClick(lista[position])
}
}
}
Na Activity:
val adapter = ContatoAdapter(meusContatos) { contatoClicado ->
Toast.makeText(this, "Cliquei em ${contatoClicado.nome}", Toast.LENGTH_SHORT).show()
}
6. ListAdapter e DiffUtil (Otimização Máxima) 🚀
Se você alterar um item da lista e chamar notifyDataSetChanged(), ele redesinha TUDO. Isso é lento.
O DiffUtil compara a lista velha com a nova e atualiza só o que mudou (animação bonita de inserção/remoção).
O ListAdapter é uma classe do Jetpack que já implementa DiffUtil pra você de graça. Sempre prefira usar ListAdapter em vez de RecyclerView.Adapter puro em projetos reais.
7. Desafio: Catálogo de Filmes 🎬
- Crie um layout
item_filme.xmlcom Imagem (Cartaz) e Texto (Título). - Crie um Adapter para exibir uma lista de 10 filmes falsos.
- Use
GridLayoutManagercom 2 colunas. - Ao clicar no filme, abra uma
DetalhesActivitypassando o título do filme.
Próxima Aula: Vamos preencher essa lista com dados reais da internet? Consumo de API REST 🌍
Aula 10 - Consumindo API REST (Retrofit) 🌍
Objetivo
Objetivo: Conectar o aplicativo à internet, baixar dados JSON de uma API REST e convertê-los em objetos Kotlin usando a biblioteca Retrofit.
1. O que é uma API REST? 🔌
É como um garçom. 1. Client (Você): Faz um pedido (Request). "Quero a lista de usuários". 2. API (Garçom): Leva o pedido à cozinha (Servidor). 3. Response: Traz a comida (Dados JSON).
Trabalharemos com JSON JavaScript Object Notation):
2. A Biblioteca Retrofit 🚀
No Android, ninguém faz requisições HTTP "na mão" (abrindo Socket). Usamos o Retrofit (da Square). Ele é o padrão de mercado.
Ele faz 3 mágicas: 1. Conecta na internet. 2. Converte JSON para Objetos Kotlin (usando Gson ou Moshi). 3. Gerencia Threads (com Coroutines).
🆚 Comparação: URLSession / Alamofire (iOS)
- Nativo: No Android tínhamos
HttpUrlConnection(horrível), no iOS temURLSession(muito bom). - Bibliotecas: Android usa Retrofit. iOS usa muito Alamofire (embora o nativo hoje seja suficiente).
3. Implementando em 3 Passos 👣
Passo 1: O Modelo (Data Class)
Deve bater com o JSON.
data class Usuario(
val id: Int,
val name: String, // O nome do campo deve ser IGUAL ao do JSON
val email: String
)
Passo 2: A Interface (Contrato)
Definimos as rotas da API.
interface ApiService {
@GET("users") // Endpoint: https://api.site.com/users
suspend fun listarUsuarios(): List<Usuario>
@GET("users/{id}")
suspend fun obterUsuario(@Path("id") id: Int): Usuario
}
suspend: indica que é assíncrono (Coroutines).
Passo 3: O Cliente (Instância)
val retrofit = Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create()) // Conversor JSON
.build()
val servico = retrofit.create(ApiService::class.java)
4. Chamando na ViewModel 🧠
Nunca chame a API direto na Activity!
class UserViewModel : ViewModel() {
val usuarios = MutableLiveData<List<Usuario>>()
fun buscarDados() {
viewModelScope.launch { // Coroutine
try {
val lista = servico.listarUsuarios()
usuarios.value = lista
} catch (e: Exception) {
// Tratar erro (falta de net, 404, etc)
}
}
}
}
5. Permissão de Internet 🌐
Não esqueça! No AndroidManifest.xml:
SecurityException.
6. Autenticação e Segurança 🔐
Apps reais quase sempre precisam de login. Os padrões mais comuns são:
- Basic Auth: Envia usuário e senha em cada pedido (Inseguro sozinho).
- Bearer Token (JWT): Após o login, o servidor devolve um "Token". Você envia esse token no cabeçalho (Header) de todas as próximas chamadas.
- OAuth2: Padrão para "Login com Google/Facebook".
Adicionando Token no Retrofit (Interceptor)
Não precisamos colocar o token manualmente em cada função. Usamos um Interceptor do OkHttp:
val client = OkHttpClient.Builder().addInterceptor { chain ->
val novoRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $MEU_TOKEN")
.build()
chain.proceed(novoRequest)
}.build()
val retrofit = Retrofit.Builder()
.client(client) // Vincula o cliente customizado
.baseUrl(...)
.build()
7. Ferramentas Úteis 🛠️
- Postman / Insomnia: Para testar a API antes de codar.
- Mocky.io: Para criar APIs falsas (Mock) para teste.
- QuickType.io: Cola o JSON lá, ele gera a Data Class Kotlin pronta! (Dica de ouro ✨).
7. Desafio: Consumindo o GitHub 🐙
- Crie uma data class
Repo(nome, stars, url). - Use a API pública do GitHub:
https://api.github.com/users/{SEU_USER}/repos. - Exiba o nome dos seus repositórios no Logcat (
Log.d).
Próxima Aula: O que é esse suspend e launch? Vamos entender o mundo Assíncrono. Threads e Coroutines 🧵
Aula 11 - Threads e Assincronismo (Coroutines) 🧵
Objetivo
Objetivo: Entender o conceito de Main Thread vs Background Thread, o erro ANR, e como programar de forma assíncrona simples e poderosa usando Kotlin Coroutines.
1. O Bloqueio da UI (ANR) 🛑
O Android desenha a tela a cada 16ms (60fps). Tudo isso acontece na Main Thread (Thread Principal). Se você colocar um código que demora 5 segundos na Main Thread (ex: baixar imagem, ler banco pesado): 1. A tela congela. 2. O usuário clica e nada acontece. 3. O Android exibe o ANR (Application Not Responding) e fecha seu app.
Regra Suprema: Operações pesadas (IO, Rede, Banco) SEMPRE em Background.
2. O Passado: Callbacks Hell e Asynctask 🕸️
Antigamente, usávamos AsyncTask ou Callbacks aninhados.
// Código Java antigo (Pesadelo)
api.getUser(new Callback() {
onSuccess(user) {
api.getPosts(user.id, new Callback() {
onSuccess(posts) {
// ... pirâmide de chaves ...
}
})
}
})
3. O Futuro: Kotlin Coroutines ⚡
Coroutines permitem escrever código assíncrono como se fosse sequencial. É mágica pura.
- suspend fun: Uma função que pode ser "pausada" e retomada depois, sem bloquear a thread.
- Scope: O escopo de vida da coroutine (ex: morreu a tela, cancela o download).
- Dispatcher: Define em qual thread vai rodar.
Dispatchers (Os entregadores)
Dispatchers.Main: Thread Principal (Atualizar UI).Dispatchers.IO: Input/Output (Rede, Banco, Arquivos).Dispatchers.Default: Processamento pesado de CPU (Cálculos, Listas gigantes).
4. Na Prática 👩💻
// ViewModelScope: Já vem pronto no ViewModel
fun realizarLogin() {
viewModelScope.launch { // Inicia a coroutine na Main Thread
exibirLoading(true) // UI: Main
// withContext: Troca para thread de IO e PAUSA a execução aqui (sem travar)
val resultado = withContext(Dispatchers.IO) {
api.fazerLoginDemorado() // Roda em background
}
// Quando voltar, já estamos na Main de novo automaticamente!
exibirLoading(false)
tratarResultado(resultado)
}
}
Olhe como a leitura é linear! Não tem onSuccess, não tem callback.
🆚 Comparação: Swift Concurrency (Async/Await)
O iOS adotou recentemente o async / await, que é muito parecido com Coroutines.
* Kotlin: suspend fun / viewModelScope.launch
* Swift: async func / Task { await ... }
5. Jobs e Cancelamento 🚫
Uma das maiores vantagens. Se o usuário sair da tela no meio do download:
1. O ViewModel morre (onCleared).
2. O viewModelScope é cancelado automaticamente.
3. A requisição de rede é abortada.
4. Nenhum crash acontece por tentar atualizar uma tela que não existe mais.
6. Comunicação em Tempo Real (Sockets) 🔌
Enquanto o REST (Aula 10) é como um "pedido e resposta", o Socket (TCP) é como uma ligação telefônica: o canal fica aberto.
- Full-Duplex: Tanto o servidor quanto o app podem enviar dados a qualquer momento.
- Casos de Uso: Chats, Jogos Online, Cotações de Bolsa em tempo real.
- Biblioteca Recomendada:
Socket.ioouWebSocketsnativo.
[!NOTE] Trabalhar com Sockets exige cuidado redobrado com o ciclo de vida. Se o app for para o background, você deve decidir se mantém o socket aberto ou fecha para economizar bateria.
7. Desafio: Simulador de Corrida 🏎️
Crie uma função suspend fun corrida() que:
1. Imprima "Preparar..."
2. Espere 1 segundo (delay(1000) - nota: delay não trava a thread, Thread.sleep trava!).
3. Imprima "Apontar..."
4. Espere 1 segundo.
5. Imprima "JÁ!"
6. Chame essa função a partir de um botão e veja se a UI continua responsiva (se o botão clica) durante a contagem.
Próxima Aula: Agora que o app funciona, vamos deixá-lo incrível? UX, Material Design e Animações 🎨
Aula 12 - UX/UI e Material Design 3 🎨
Objetivo
Objetivo: Elevar a qualidade visual do app seguindo os padrões do Google (Material Design 3), entendendo temas, cores dinâmicas e componentes modernos.
1. O que é Material Design? 💄
É o sistema de design do Google (criado em 2014, agora na versão 3 - "Material You"). Ele imita "papel e tinta" (sombras, elevação) mas com cores vibrantes e adaptáveis.
- Princípio: O design deve se adaptar ao usuário, não o contrário.
- Foco: Legibilidade, Acessibilidade e consistência.
🆚 Comparação: HIG (Human Interface Guidelines)
A Apple tem o HIG. * Material (Android): Mais colorido, elevação (sombras), Botões FAB (flutuantes), interação mais "brincalhona". * HIG (iOS): Mais plano (flat), minimalista, foco no conteúdo, desfoque (blur).
2. Material 3 (Material You) 🌸
A grande novidade é o Dynamic Color. O App pega as cores do papel de parede do usuário e aplica no tema dele. Se meu wallpaper é verde, todos os botões do seu app ficam verdes (se configurado).
Componentes Chave
- FAB (Floating Action Button): Botão flutuante para ação principal.
- Bottom Navigation: Barra inferior para navegação principal.
- Cards: Conteúdo agrupado com bordas arredondadas.
- TopAppBar: Barra superior (antiga Toolbar).
3. Implementando Material no Android 🛠️
Certifique-se de usar a biblioteca correta no build.gradle:
implementation 'com.google.android.material:material:1.x.x'
XML - Botão Material
<com.google.android.material.button.MaterialButton
style="@style/Widget.Material3.Button.Tonal"
android:text="Botão Moderno" ... />
XML - Card
<com.google.android.material.card.MaterialCardView
app:cardCornerRadius="16dp"
app:strokeWidth="1dp"
app:strokeColor="@color/material_dynamic_primary" ... >
<!-- Conteúdo do card aqui -->
</com.google.android.material.card.MaterialCardView>
4. Ícones e Tipografia 🔡
- Ícones: Use Vector Assets (SVG). O Android Studio tem uma biblioteca gigante de ícones embutida. (File > New > Vector Asset).
- Fontes: Use fontes legíveis. Material 3 usa muito a Roboto e variações de peso (Bold, Medium).
5. Dark Mode (Modo Escuro) 🌑
Hoje em dia é obrigatório.
O Android gerencia isso com pastas de recursos:
* values/colors.xml (Cores Dia)
* values-night/colors.xml (Cores Noite)
Defina nomes semânticos, não literais:
* ❌ background_white (Ruim: e se no escuro for preto?)
* ✅ background_color (Bom: no dia é branco, na noite é preto)
6. Feedback Tátil e Visual (Ripples) 🌊
O usuário precisa saber que tocou.
O Android tem o efeito Ripple (onda) nativo em botões. Se criar um componente customizado, adicione:
android:background="?attr/selectableItemBackground"
Se a ação for perigosa (deletar), use cores de erro (vermelho). Se for sucesso, cores de confirmação.
7. Desafio: Redesign do App 💅
Pegue o exercício da Lista de Filmes (Aula 09) ou Tarefas (Aula 08) e aplique Material Design:
1. Use MaterialCardView para os itens da lista.
2. Adicione um FloatingActionButton (+) para incluir novos itens.
3. Crie uma versão de cores para Modo Escuro (teste trocando o tema do celular).
4. Certifique-se que os textos têm contraste suficiente.
Próxima Aula: Sensores, GPS e Câmera! Acessando Hardware 📸
Aula 13 - Sensores e Hardware �
Objetivo
Objetivo: Aprender a acessar os recursos físicos do dispositivo, como Câmera, GPS (Localização) e Sensores de Movimento (Acelerômetro), entendendo o sistema de permissões em tempo de execução.
1. O Mundo do Hardware �
Diferente da Web, o App Nativo tem acesso direto aos sensores do celular. Os principais são: * Movimento: Acelerômetro, Giroscópio. * Posição: GPS, Magnetômetro (Bússola). * Ambiente: Luz, Barômetro (Pressão), Temperatura. * Interface: Câmera, Microfone, Biometria (Digital/Rosto).
2. Permissões (Permissions) 🔑
No Android, as permissões são divididas em duas categorias:
- Normais: Não oferecem risco à privacidade (ex: Bluetooth, Internet). Definidas apenas no
AndroidManifest.xml. - Perigosas: Acessam dados sensíveis (ex: Câmera, GPS, Contatos). Precisam ser pedidas ao usuário em tempo de execução (pop-up).
Solicitando Permissão (Moderno)
val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
// Permissão concedida! Abrir câmera...
} else {
// Permissão negada... explicar por que precisa.
}
}
// Chamar quando precisar
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
3. Localização e GPS 🗺️
Para obter a localização, usamos o Fused Location Provider (parte do Google Play Services). Ele é mais inteligente e economiza bateria.
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
fusedLocationClient.lastLocation.addOnSuccessListener { location : Location? ->
// Got last known location. In some rare situations this can be null.
location?.let {
val lat = it.latitude
val long = it.longitude
}
}
4. Sensores de Movimento 🎢
O Android usa o SensorManager para escutar dados do acelerômetro, por exemplo.
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
val listener = object : SensorEventListener {
override fun onSensorChanged(event: SensorEvent?) {
val x = event?.values?.get(0) // Inclinação X
// ...
}
override fun onAccuracyChanged(s: Sensor?, a: Int) {}
}
sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL)
5. Câmera (CameraX) 📸
O Google criou a biblioteca CameraX para facilitar o uso da câmera, que era muito complexo antigamente. Ela lida com as diferenças entre fabricantes automaticamente.
Principais casos de uso: 1. Preview: Ver a imagem na tela. 2. Image Capture: Tirar foto e salvar. 3. Image Analysis: Ler QR Code ou detectar rostos em tempo real.
6. Bluetooth e Dispositivos Embarcados 🔵
Muitas vezes o app precisa falar com um Arduino, ESP32 ou fone de ouvido. * Bluetooth Classic: Para áudio e transferência de arquivos grande. * BLE (Bluetooth Low Energy): Para sensores e wearables. Economiza muita bateria.
// Exemplo simplificado de scan
val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
bluetoothAdapter?.startDiscovery()
7. Telefonia e SMS 📞
O Android permite que seu app interaja com as funções de telefone.
* Fazer Chamadas: Precisa de permissão CALL_PHONE.
* Enviar SMS: Use SmsManager.
val smsManager: SmsManager = SmsManager.getDefault()
smsManager.sendTextMessage("numero", null, "Olá Mundo!", null, null)
8. Mapas e Orientação 🗺️
Além de saber a latitude, podemos mostrar isso visualmente. * Google Maps SDK: A biblioteca padrão para exibir mapas, desenhar rotas e colocar marcadores. * Geocoding: Transformar coordenadas (lat/long) em endereços reais (Rua X, nº 10).
9. Biometria (Impressão Digital) ☝️
O BiometricPrompt exibe aquela janela padrão do sistema para o usuário colocar o dedo ou olhar para a câmera.
🆚 Comparação: Core Motion e CameraControl (iOS)
No iOS, o framework Core Motion lida com sensores, e a AVFoundation lida com a Câmera. O sistema de permissões do iOS é ainda mais rígido desde o início.
7. Desafio: O Detector de Balanço shake
Crie um app que: 1. Escute o acelerômetro. 2. Se o valor de aceleração passar de um limite (usuário balançou o celular), mude a cor de fundo da tela para uma cor aleatória. 3. Imprima no Logcat: "Balanço detectado!".
Próxima Aula: Como garantir que seu código não quebre? Testes e Debugging 🐞
Aula 14 - Testes, Qualidade e Debugging 🐞
Objetivo
Objetivo: Aprender a encontrar e corrigir erros de forma profissional, utilizar o Logcat e escrever testes automatizados (Unitários e de UI) para garantir a estabilidade do app.
1. O Logcat: Seu melhor amigo 📝
Esqueça o println. No Android, usamos a classe Log para monitorar o que acontece.
Log.v("TAG", "Verbose - Detalhes irrelevantes")
Log.d("TAG", "Debug - Informação para o dev")
Log.i("TAG", "Info - Evento importante (Login, etc)")
Log.w("TAG", "Warning - Algo estranho, mas não quebrou")
Log.e("TAG", "Error - QUEBROU! 💥")
No Android Studio, você pode filtrar logs pela TAG ou pelo nível de erro.
2. Debugging Passo a Passo 🛠️
Quando o app trava ou tem um comportamento estranho: 1. Coloque um Breakpoint (clique na lateral da linha). 2. Rode o app em modo Debug (Ícone do besouro). 3. O app vai "congelar" naquela linha e você poderá ver o valor de todas as variáveis.
3. Pirâmide de Testes 🏔️
- Testes Unitários (70%): Testam pequenas partes (funções) isoladas. São ultra-rápidos. Rodam no computador (JVM).
- Testes de Integração (20%): Testam a conversa entre componentes (ex: ViewModel + Repositório).
- Testes de UI / Instrumentados (10%): Testam o app rodando no emulador. Clicam em botões, abrem telas. (Ex: Espresso).
4. Escrevendo um Teste Unitário 🧪
Pasta: src/test/java
class CalculadoraTest {
@Test
fun soma_estaCorreta() {
val result = Calculadora().somar(2, 2)
assertEquals(4, result)
}
}
🆚 Comparação: XCTest (iOS)
No iOS, usamos o framework XCTest. A lógica é a mesma: Criar uma classe de teste e usar métodos assert para verificar se o resultado bate com o esperado.
5. Testes de UI com Espresso ☕
O Espresso é a biblioteca padrão para testar a interface.
@Test
fun clicarNoBotao_deveMudarTexto() {
onView(withId(R.id.btnEnviar)).perform(click())
onView(withId(R.id.txtResultado)).check(matches(withText("Enviado!")))
}
6. Gerenciamento de Erros (Try/Catch) 🛡️
Nunca deixe o app fechar sozinho na mão do usuário.
try {
val resultado = 10 / 0
} catch (e: ArithmeticException) {
Log.e("AVISO", "Divisão por zero!", e)
exibirMensagemAmigavel("Ops, algo deu errado.")
}
7. Desafio: O Caçador de Bugs 🕵️♂️
Vou te dar um código com 3 erros. Tente identificar quais são (mentalmente ou no AS):
var lista: List<String>? = null
fun main() {
// Erro 1:
println(lista.size)
// Erro 2:
val num = "123a".toInt()
// Erro 3 (UI):
txtView.text = "Olá" // Tentando atualizar UI dentro de uma Thread comum?
}
Respostas
- NullPointerException: A lista é nula. Deveria usar
lista?.size. - NumberFormatException: A string tem um 'a'. Deveria usar
toIntOrNull(). - CalledFromWrongThreadException: UI só pode ser alterada na Main Thread.
Próxima Aula: Hora de mostrar seu app pro mundo! Publicação na Play Store 🚀
Aula 15 - Publicação e Google Play Store 🚀
Objetivo
Objetivo: Conhecer o processo final de transformar seu código em um produto real, gerando o arquivo de produção (.aab), criando artes para a loja e entendendo os critérios de revisão.
1. APK vs AAB 📦
- APK (Android Package): Formato antigo. É um "zip" com tudo dentro.
- AAB (Android App Bundle): Formato moderno (obrigatório para novos apps). O Google Play usa o Bundle para gerar APKs otimizados para cada celular (só envia as imagens daquela densidade de tela, economizando espaço).
2. Preparando o App para Produção ⚙️
- Remover Logs: Limpe os
Log.dou use bibliotecas como o Timber para gerenciar isso. - Ofuscação (ProGuard/R8): Protege seu código contra pirataria e diminui o tamanho do app removendo código não usado.
- Versão: Atualize o
versionCode(número inteiro) eversionName(ex: "1.0.0") nobuild.gradle.
3. Gerando a Chave de Assinatura (Keystore) 🔑
O Android exige que todo app seja assinado digitalmente.
IMPORTANTE: Se você perder o arquivo .jks (keystore), você nunca mais poderá atualizar seu app na loja. Guarde em 3 lugares diferentes! 💾
4. Google Play Console 🎮
É o portal do desenvolvedor Google. * Custo: Taxa única de $25. * Revisão: O app passa por uma análise automatizada e humana (pode levar de 1 a 7 dias).
5. Materiais para a Loja (Marketing) 🎨
Você vai precisar de: 1. Título e Descrição (Curta e Longa). 2. Ícone do App (512x512). 3. Feature Graphic (1024x500 - Arte de destaque). 4. Screenshots (Capturas de tela do app rodando).
6. Testes Rápidos (Canais de Teste) 🧪
Antes de lançar para o público geral, use os canais: * Teste Interno: Para sua equipe (instantâneo). * Teste Fechado (Beta): Para convidados. * Teste Aberto: Qualquer um pode baixar e testar.
🆚 Comparação: App Store Connect e TestFlight (iOS)
No iOS, a taxa é anual ($99). O portal chama-se App Store Connect e o app de testes oficial é o TestFlight. A revisão da Apple é conhecida por ser muito mais rigorosa que a do Google.
7. Desafio: Checklist de Lançamento ✅
Imagine que você terminou seu app de Notas. Marque o que você faria ANTES de clicar em "Gerar AAB":
- [ ] Deixar a senha do banco de dados exposta no código? (Espero que não! 😱)
- [ ] Ativar o minifyEnabled true para encolher o código?
- [ ] Testar em um celular físico real?
- [ ] Verificar se as Strings estão traduzidas para PT-BR?
Próxima Aula: O grande final! Projeto de Conclusão de Curso 🎓
Aula 16 - Projeto Final e Conclusão 🎓
Objetivo
Objetivo: Aplicar TODO o conhecimento adquirido (Layouts, Navegação, MVVM, API, Banco de Dados, Sensores) na criação de um aplicativo completo e funcional de portfólio.
1. O Desafio Final: "My Daily Companion" 🦸♂️
Você deve criar um app que ajude o usuário no seu dia a dia. Escolha UM dos temas abaixo ou crie o seu:
- App de Finanças: Cadastra despesas, salva no Room, exibe lista com RecyclerView e totalizador.
- App de Clima: Consome uma API (OpenWeather) baseada no GPS (Localização) do usuário.
- Catálogo de Livros/Games: Consome uma API ou salva localmente as capas e detalhes, com busca e favoritos.
- App de Fitness: Usa o contador de passos (sensor) e cronômetro para marcar exercícios.
2. Requisitos Obrigatórios 📋
O projeto deve conter obrigatoriamente: - [ ] Arquitetura MVVM (ViewModel + LiveData). - [ ] Interface Material Design 3 (Cards, Botões, Cores consistentes). - [ ] Navegação entre pelo menos 2 telas (Lista e Detalhes). - [ ] Persistência (Room ou SharedPreferences) OU Networking (Retrofit). - [ ] Boas Práticas: Código limpo, strings traduzidas, Logcat para debug.
3. Dicas para um Portfólio de Elite ✨
Para um recrutador olhar seu projeto e dizer "UAU":
1. README.md no GitHub: Explique o que o app faz, coloque prints/GIFs dele rodando e liste as tecnologias usadas.
2. Dark Mode: Suporte total ao modo escuro.
3. Tratamento de Erros: Se a internet cair, mostre uma tela bonita de "Ops!", não deixe o app branco.
4. Animações: Use o MotionLayout ou simples ViewPropertyAnimator para dar vida aos botões.
4. Onde continuar estudando? 📚
O mundo mobile não para. O que aprender agora? 1. Jetpack Compose: A nova forma de criar UI no Android (substituindo o XML). 2. Kotlin Multiplatform (KMP): Use a mesma lógica Kotlin no Android e no iOS. 3. SwiftUI: Se quiser entrar de vez no mundo Apple. 4. Dependency Injection (Hilt/Koin): Para projetos gigantes.
5. Mensagem Final 🌟
Parabéns! Você saiu do ZERO e agora entende como as ferramentas que movem o mundo (apps) são construídas. O caminho é longo, mas a base que você construiu aqui é sólida como o Kernel Linux do Android.
"A melhor maneira de prever o futuro é inventá-lo." - Steve Jobs (e adaptado para os devs Mobile).
FIM DO CURSO 🚀🚀🚀 Desejamos muito sucesso na sua jornada como Desenvolvedor Mobile Nativo!
Exercícios
Listas de Exercícios 🏋️
Pratique o que aprendeu com desafios graduais para cada aula.
-
Trilha 1: Fundamentos ---
-
Trilha 2: Core Android ---
-
Trilha 3: Networking ---
-
Trilha 4: Finalização ---
Exercícios 01 - Introdução ao Mobile 📱
🟢 Fáceis
- Conceitos: Explique com suas palavras a diferença entre um App Nativo e um App Híbrido.
- Ecossistema: Cite 3 diferenças técnicas ou de mercado entre o desenvolvimento Android e iOS.
🟡 Médios
- Cenário: Uma padaria quer um app simples apenas para mostrar o cardápio, sem login ou recursos complexos. O orçamento é curto. Que tecnologia você recomendaria (Nativo, Híbrido ou PWA)? Justifique.
- Hardware: Por que apps Nativos tendem a ter melhor acesso a recursos de hardware (como Bluetooth ou Sensores) do que soluções Web?
🔴 Desafio
- Análise de Caso:
Você foi contratado pelo "Instagram" em 2010. O objetivo é criar a melhor experiência de rolagem de feed possível, com filtros de imagem aplicados em tempo real.
- Escolha a tecnologia (Nativo vs Híbrido da época) e justifique considerando Performance vs Custo.
- Desenhe (mentalmente ou no papel) como seria a arquitetura macro: O app processa o filtro no celular ou no servidor? Por que?
Exercícios 02 - Fundamentos Java ☕
🟢 Fáceis
- Classe Simples: Crie uma classe
Livrocom atributostituloeautor. Adicione um construtor. - Tipos: Qual a diferença entre
inteInteger? Dê um exemplo de quando usar cada um.
🟡 Médios
- Herança:
- Crie uma classe
Animalcom métodoemitirSom(). - Crie classes filhas
CachorroeGatoque sobrescrevem (override) esse método.
- Crie uma classe
- Correção de Código: O código abaixo dá erro. Por que? Corrija. (Dica: Faltou uma palavra mágica no método).
🔴 Desafio
- Polimorfismo e Listas:
- Crie uma
ArrayList<Animal>(da questão 3). - Adicione um cachorro e um gato na lista.
- Use um
forpara percorrer a lista e chamaremitirSom()de cada um. - Explique por que o Java sabe qual som emitir em tempo de execução.
- Crie uma
Exercícios 03 - Introdução ao Kotlin 💜
🟢 Fáceis
- Conversão: Converta o código Java abaixo para Kotlin.
- Inferência: O que acontece se eu tentar fazer isso em Kotlin? Por que?
🟡 Médios
- Null Safety:
Você tem uma variável
var nome: String? = null. Escreva um código que imprime o tamanho do nome SE ele não for nulo, e imprime "0" se for nulo, usando o operador Elvis (?:). - Funções: Reescreva a função abaixo usando a sintaxe Single-Expression (linha única).
🔴 Desafio
- Data Classes e Cópia:
- Crie uma
data class Celular(val marca: String, val modelo: String, val preco: Double). - Instancie um "iPhone 14" de 5000 reais.
- Use o método
.copy()para criar um novo celular igualzinho, mas mudando apenas omodelopara "iPhone 15" e oprecopara 6000. - Imprima os dois objetos.
- Crie uma
Exercícios 04 - Estrutura App Android 🏗️
🟢 Fáceis
- Manifesto: Para que serve o arquivo
AndroidManifest.xml? Cite duas coisas definidas nele. - Recursos: Em qual pasta devemos colocar as imagens do nosso aplicativo? E os textos?
🟡 Médios
- Ciclo de Vida (Ordem):
Coloque os métodos na ordem correta de execução quando o app é aberto pela primeira vez:
onResume,onCreate,onStart. - XML vs Code: Por que o Android separa o Layout (XML) da Lógica (Kotlin)? Cite uma vantagem dessa abordagem (ex: tradução, manutenção, designers).
🔴 Desafio
- Debug de Lifecycle:
Um desenvolvedor novato colocou um código pesado (download de imagem) dentro do método
onResume().- O que acontece com o app se o usuário ficar bloqueando e desbloqueando a tela várias vezes seguidas?
- Qual seria o lugar (ou componente) mais adequado para fazer esse download apenas uma vez? (Pode chutar: ViewModel, onCreate, WorkManager...)
Exercícios 05 - Interface Gráfica 🎨
🟢 Fáceis
- Views vs ViewGroups: Em poucas palavras, qual a função de um
ViewGroup? Dê um exemplo. - Unidades: Por que devemos usar
dppara tamanhos esppara textos, em vez de pixels (px)?
🟡 Médios
- ConstraintLayout:
Explique como você centralizaria um botão na tela usando
ConstraintLayout(quais as "amarras" necessárias). - Weight (Peso):
Em um
LinearLayouthorizontal, se eu tiver dois botões, e quiser que o primeiro ocupe 70% da tela e o segundo 30%, como configuro olayout_weight?
🔴 Desafio
- Hierarquia de Views:
Um erro comum de iniciantes é criar layouts muito aninhados (LinearLayout dentro de LinearLayout, dentro de outro...).
- Por que isso é ruim para a performance do app?
- Como o
ConstraintLayoutajuda a evitar esse problema? - Desenhe a estrutura de árvore do layout da "Tela de Login" proposta na aula.
Exercícios 06 - Navegação 🗺️
🟢 Fáceis
- Conceito: O que é uma
Intentno Android? - Tipos: Qual a diferença entre uma Intent Explícita e uma Implícita?
🟡 Médios
- Passagem de Dados:
Escreva um trecho de código (Kotlin) para enviar o número
42para a ActivityRespostaActivitycom a chave "RESPOSTA_FIXA". - Ciclo de Vida:
Quando abrimos a Activity B a partir da A, o método
onStop()da A é chamado? E oonDestroy()? Justifique.
🔴 Desafio
- Fluxo de Navegação:
Você tem 3 telas: A -> B -> C.
- Na tela C, existe um botão "Home" que deve levar para a tela A, mas limpando a tela B e C da pilha (para que o botão voltar não funcione). Qual flag de Intent você usaria ou qual a lógica para isso?
Exercícios 07 - Arquitetura MVVM 🏗️
🟢 Fáceis
- Responsabilidades: No padrão MVVM, quem é responsável por decidir o que mostrar na tela? (Model, View ou ViewModel?)
- Ciclo de Vida: O que acontece com os dados dentro de um
ViewModelquando a tela gira (rotaciona)?
🟡 Médios
- LiveData: Explique o conceito de "Oberver Pattern" usado no LiveData. Por que a Activity precisa "observar" os dados?
- Separação:
Por que não devemos passar uma referência da
View(ex: umTextView) para dentro doViewModel? (Dica: pense em vazamento de memória e ciclo de vida).
🔴 Desafio
-
Arquitetura Real: Imagine um app de Clima.
- Model: Classe
ClimaRepositoryque pega dados da API. - ViewModel: Chama o repositório e guarda
val temperatura = MutableLiveData<Float>(). - View: Mostra o texto "25°C".
Se a internet cair no meio da requisição, quem deve tratar o erro e onde deve ficar a mensagem de erro (String) para ser exibida? No Model, ViewModel ou View?
- Model: Classe
Exercícios 08 - Persistência de Dados 💾
🟢 Fáceis
- Escolha: Para salvar apenas "Som ligado/desligado", qual a opção mais adequada: SQLite, SharedPreferences ou Arquivo de Texto?
- Room: O que é uma
@Entityno Room?
🟡 Médios
- Threads: Por que o Android proíbe acesso ao banco de dados na Main Thread? O que acontece se tentarmos fazer isso?
- DAO: O que significa a sigla DAO e qual sua função no Room?
🔴 Desafio
- Migração:
Você lançou o app com a tabela
Usuario(id, nome). Na versão 2.0, você precisa adicionar o campoidade.- O que acontece se você rodar o app novo em um celular que tem o banco antigo, sem configurar uma "Migration"?
- Como o Room lida com controle de versão do banco?
Exercícios 09 - Listas Eficientes (RecyclerView) 📋
🟢 Fáceis
- Conceito: Por que o
RecyclerViewé mais eficiente que umListViewantigo ou umLinearLayoutdentro de umScrollView? - Componentes: Qual a função do
LayoutManagerno RecyclerView?
🟡 Médios
- Adapter:
O método
onBindViewHolderé chamado muitas vezes. O que acontece se você colocar uma lógica pesada (ex: baixar uma imagem da internet de forma síncrona) dentro dele? - ViewHolder:
Para que serve a classe
ViewHolder? Por que não devemos fazerfindViewByIddireto noonBindViewHolder?
🔴 Desafio
- Múltiplos Tipos de View:
Imagine um chat (WhatsApp). Mensagens enviadas ficam na direita (verde), recebidas na esquerda (branco).
- Como você implementaria isso no RecyclerView? (Dica: pesquise sobre
getItemViewType).
- Como você implementaria isso no RecyclerView? (Dica: pesquise sobre
Exercícios 10 - Consumo de API REST 🌍
🟢 Fáceis
- Verbos HTTP: Qual verbo HTTP usamos para obter dados e qual usamos para enviar dados novos?
- Permissão: Qual permissão deve ser adicionada no
AndroidManifest.xmlpara que o Retrofit funcione?
🟡 Médios
- Conversão:
O que acontece se o campo no JSON for
"user_name"(snake_case) e na sua data class forval userName: String(camelCase)? Como o Retrofit/Gson sabe mapear isso? (Pesquise sobre anotação@SerializedName). - Threading:
O Retrofit (com Coroutines) precisa que você use
withContext(Dispatchers.IO)manualmente na chamada, ou ele já faz isso por baixo dos panos? - Autenticação:
Se uma API exige um token JWT no cabeçalho
Authorization, como você configuraria o Retrofit para enviar esse token em todas as requisições sem repetir código? (Pesquise sobreOkHttp Interceptors).
🔴 Desafio
- Status Code:
Se a API retornar erro 401 (Não Autorizado) ou 500 (Erro no Servidor), como você capturaria isso no bloco
try/catchdo ViewModel para exibir uma mensagem adequada ao usuário?
Exercícios 11 - Threads e Async 🧵
🟢 Fáceis
- ANR: O que significa a sigla ANR e o que causa esse erro?
- Main Thread: O que deve e o que NÃO deve rodar na Main Thread?
🟡 Médios
- Dispatchers:
Qual
Dispatchervocê usaria para: a) Ordenar uma lista de 10.000 nomes (CPU intensive). b) Salvar um arquivo no disco (IO). c) Atualizar um TextView (UI). - Suspensão:
O que acontece com a Thread Principal quando ela encontra uma função
suspendque chamadelay(5000)? Ela trava por 5 segundos ou continua livre para desenhar a tela? - Sockets vs REST: Explique a principal diferença entre uma comunicação REST e uma comunicação via Sockets (TCP). Quando você escolheria usar Sockets em vez de REST em um aplicativo Android?
🔴 Desafio
- Race Condition (Condição de Corrida):
Duas coroutines tentam alterar a mesma variável
contador = 0ao mesmo tempo. Ambas leem 0, somam 1 e salvam 1. O resultado final é 1, mas deveria ser 2.- Como resolver isso em Kotlin (Mutex, Atomic, ou Single Thread)?
Exercícios 12 - UX/UI e Material Design 🎨
🟢 Fáceis
- Princípio Key: Qual a principal diferença visual (metafórica) entre o Material Design (Google) e o Flat Design original? (Dica: pense em Eixo Z).
- Cores: O que é o "Dynamic Color" (Material You)?
🟡 Médios
- Acessibilidade: Por que não devemos confiar apena na COR para indicar estado (ex: erro ser apenas vermelho)? O que mais devemos adicionar?
- Dark Mode:
Ao criar um ícone preto (
#000000) para um botão, o que acontece quando o usuário ativa o Modo Escuro no celular? Como corrigir?
🔴 Desafio
-
Densidade de Informação: Você tem uma lista de 50 itens para exibir.
- Opção A: Lista densa (apenas texto, linhas finas).
- Opção B: Cards grandes com margens largas e sombras.
Em qual situação você usaria a Opção A e em qual usaria a Opção B? (Considere um app de utilitário vs um app de mídia/notícias).
Exercícios 13 - Sensores e Hardware 📸
🟢 Fáceis
- Permissões: Qual a diferença entre uma permissão "Normal" e uma "Perigosa" no Android?
- GPS: Qual biblioteca do Google Play Services é recomendada para obter a localização?
🟡 Médios
- SensorManager:
Para que serve o método
registerListener? O que acontece se esquecermos de chamar ounregisterListenernoonStop()ouonDestroy()da Activity? - CameraX: Cite os 3 principais casos de uso (Use Cases) da biblioteca CameraX e para que servem.
- Bluetooth e SMS: a) Qual a diferença entre Bluetooth Classic e Bluetooth Low Energy (BLE) em termos de consumo de bateria e casos de uso? b) Quais as classes principais no Android para enviar um SMS e para gerenciar a conexão Bluetooth?
🔴 Desafio
- Geocoding e Mapas: Se você tem a latitude e longitude de um usuário, como você faria para descobrir o nome da rua e o número (endereço completo)? Qual o nome do processo e da classe que faz isso no Android?
Exercícios 14 - Testes e Qualidade 🧪
🟢 Fáceis
- Logcat: Por que usar
Log.d()em vez deprintln()no Android? - Breakpoint: O que acontece com a execução do código quando ele atinge um breakpoint no modo Debug?
🟡 Médios
- Pirâmide de Testes: Por que devemos ter mais Testes Unitários do que Testes de UI? Cite 2 razões.
- Espresso:
Escreva uma linha de código usando Espresso para verificar se um botão com o ID
btn_salvarestá visível na tela.
🔴 Desafio
- TDD (Test Driven Development): Explique brevemente o ciclo "Red-Green-Refactor". Como essa prática ajuda a evitar bugs em aplicativos mobile que crescem muito rápido?
Exercícios 15 - Publicação 🚀
🟢 Fáceis
- Formato: Qual o formato de arquivo obrigatório para enviar novos apps para a Google Play Store? (APK ou AAB?)
- Custo: Qual o valor da taxa para criar uma conta de desenvolvedor no Google Play? Ela é anual ou única?
🟡 Médios
- Keystore: Por que o arquivo de chave (.jks) é tão crítico? O que acontece se você perdê-lo após publicar a versão 1.0 do seu app?
- ProGuard/R8: Explique o que é a ofuscação de código e por que ela é importante para a segurança do app.
🔴 Desafio
- Otimização: Como o Google Play usa o Android App Bundle (AAB) para reduzir o tamanho do download para o usuário final em comparação ao APK tradicional?
Exercícios 16 - Planejamento do Projeto Final 🎓
🟢 Fáceis
- Tema: Escolha o tema do seu projeto final. Será um dos sugeridos (Finanças, Clima, Livros, Fitness) ou um tema autoral?
- Escopo: Liste as 2 principais telas que seu app terá.
🟡 Médios
- Arquitetura:
Desenhe (ou descreva) como será o seu
ViewModel. Quais dados (LiveData) ele vai expor para a View? - Dados: Seu app usará dados da Internet (Retrofit) ou salvará localmente (Room)? Justifique sua escolha baseada na utilidade do app.
🔴 Desafio
- Checklist de Qualidade: Crie um checklist com 5 itens de UX/UI que você vai garantir no seu projeto final (ex: Modo Escuro, Feedback de cliques, Tratamento de erro de rede, etc).
Projetos
Projetos Práticos 🚀
Transforme teoria em prática com desafios progressivos que compõem seu portfólio.
-
Módulo 1: Primeiros Passos ---
-
Módulo 2: Interface e Dados ---
-
Módulo 3: Listas e APIs ---
-
Módulo 4: Avançado e Final ---
Projeto 01 - Meu Primeiro App 📱
Objetivo: Validar a instalação do ambiente e entender a estrutura básica.
O Desafio
- Abra o Android Studio e crie um novo projeto "Empty Views Activity".
- Escolha o nome "MeuPrimeiroApp" e linguagem Kotlin.
- No layout
activity_main.xml, mude o texto "Hello World" para "Olá, Desenvolvedor Mobile! 🚀". - Mude a cor do texto para azul.
- Rode o app no Emulador ou Celular físico.
O que entregar?
- Print da tela do app rodando.
- O arquivo
AndroidManifest.xmlpara conferência.
Projeto 02 - Calculadora de IMC (Java) ☕
Objetivo: Praticar lógica de programação e tipos de dados usando Java no Android.
O Desafio
- Crie um layout simples com dois
EditText(Peso e Altura) e umButton(Calcular). - No código Java, recupere os valores digitados.
- Calcule o IMC (Peso / Altura²).
- Exiba o resultado em um
TextViewe use umToastpara mostrar a classificação (Ex: "Peso Ideal", "Sobrepeso").
Dica
Lembre-se de converter o texto do EditText para Double antes de calcular!
double peso = Double.parseDouble(editPeso.getText().toString());
Projeto 03 - Perfil de Desenvolvedor (Kotlin) ⚡
Objetivo: Praticar a sintaxe concisa do Kotlin e Data Classes.
O Desafio
- Crie uma
data class Dev(val nome: String, val stack: String, val nivel: String). - Na Activity, crie uma instância dessa classe.
- Use String Templates para exibir uma mensagem formatada em um TextView: "Olá, meu nome é ${dev.nome}, sou dev ${dev.stack} e meu nível é ${dev.nivel}."
- Implemente um botão que, ao ser clicado, altera o nível do dev de "Estagiário" para "Júnior".
Dica
Use val para a instância da classe, mas lembre-se que se precisar mudar uma propriedade interna, a classe original deve permitir ou você deve usar o método .copy().
Projeto 04 - Tela de Login Elegante 🧱
Objetivo: Dominar a estrutura de recursos (res/) e ViewBinding.
O Desafio
- Habilite o ViewBinding no seu
build.gradle. - Crie uma tela de login com:
- Logotipo (Imagem em
res/drawable). - Campo de E-mail e Senha (usando
strings.xml). - Botão "Entrar".
- Logotipo (Imagem em
- No código, use o Binding para capturar o clique do botão e validar se os campos não estão vazios.
- Se estiverem vazios, exiba um erro no
EditText(error = "Campo obrigatório").
O que avaliar?
- Organização do arquivo
strings.xml. - Uso correto do ViewBinding (sem
findViewById).
Projeto 05 - Layouts e Unidades 🎨
Objetivo: Praticar a construção de interfaces complexas com diferentes ViewGroups.
O Desafio
Crie uma tela de "Detalhes de Produto" (tipo e-commerce) contendo:
1. LinearLayout (Vertical) para a estrutura principal.
2. ImageView no topo para a foto do produto.
3. ConstraintLayout para a área de informações (nome do produto à esquerda, preço à direita, ambos alinhados).
4. Botão de "Comprar" ocupando a largura total na parte inferior.
5. Use dp para margens (mínimo 16dp) e sp para o título do produto.
Dica
Teste o seu layout em diferentes tamanhos de tela no emulador ou no Preview do Android Studio.
Quizzes
Quizzes Interativos 🧠
Teste seus conhecimentos rapidamente ao final de cada módulo.
-
Fase 1 ---
-
Fase 2 ---
-
Fase 3 ---
-
Fase 4 ---
Quiz 01 - Introdução ao Desenvolvimento Mobile 📱
Quiz 02 - Fundamentos de Java para Android ☕
Quiz 03 - Introdução ao Kotlin Moderno ⚡
Quiz 04 - Estrutura de um Aplicativo Android 🏗️
Quiz 05 - Interface Gráfica (UI) 🎨
Quiz 06 - Navegação e Intents 🗺️
Quiz 07 - Arquitetura MVVM 🏗️
Quiz 08 - Persistência de Dados (Room) 💾
Quiz 09 - Listas Eficientes (RecyclerView) 📋
Quiz 10 - APIs REST & Retrofit 🌍
Quiz 11 - Threads e Coroutines 🧵
Quiz 12 - UX/UI e Material Design 3 🎨
Quiz 13 - Hardware e Sensores 📸
Quiz 14 - Testes, Qualidade e Debugging 🐞
Quiz 15 - Publicação e Google Play Store 🚀
Quiz 16 - Revisão Geral e Próximos Passos 🎓
Slides
Slides 📺
Material visual para acompanhamento das vídeo-aulas.
-
Módulo 1 ---
-
Módulo 2 ---
-
Módulo 3 ---
-
Módulo 4 ---
Aula 01 - Introdução ao Mobile 📱
Bem-vindo ao Mundo Mobile! 🌍
O mundo hoje é mobile-first.
- Mais acesso via smartphone que PC.
- Bilhões de dispositivos ativos.
- Ecossistema dinâmico e lucrativo.
🎯 Nossa Agenda de Hoje
- Panorama do Mercado
- Nativo vs Híbrido vs Web
- Android vs iOS
- Android Studio & Ferramentas
- Por onde começar?
📱 1. Os Três Caminhos
Existem três formas principais de criar um App.
🚀 Nativo
Desenvolvido na linguagem "mãe" da plataforma.
- Android: Kotlin / Java 🤖
- iOS: Swift / Objective-C 🍎
- Vantagem: Performance máxima e acesso total ao hardware.
🌐 Web (PWA)
Basicamente um site que se comporta como App.
- Tecnologias: HTML, CSS, JS.
- Vantagem: Custo baixo, funciona em tudo.
- Desvantagem: Performance limitada e pouco acesso ao hardware.
🧩 Híbrido / Cross-Platform
Usa um framework para gerar ambas as plataformas.
- Exemplos: Flutter, React Native.
- Vantagem: Uma base de código para dois apps.
- Desvantagem: Dependência de terceiros e overhead de performance.
🤖 2. O Gigante Verde: Android
O sistema operacional mais usado do planeta.
- Criado pelo Google.
- Baseado em Linux.
- Aberto e flexível.
Arquitetura Android
graph TD
A[Apps] --> B[Java/Kotlin Framework]
B --> C[ART Runtime]
C --> D[Hardware Abstraction - HAL]
D --> E[Linux Kernel]
🍎 3. O Pomar da Apple: iOS
Foco em luxo, fluidez e segurança.
- Criado pela Apple.
- Sistema Fechado (Darwin/Unix).
- Consumidores com alto poder aquisitivo.
Android vs iOS 🆚
| Recurso | Android | iOS |
|---|---|---|
| Linguagem | Kotlin | Swift |
| IDE | Android Studio | Xcode |
| Loja | Google Play | App Store |
| Taxa | $25 (Única) | $99 (Anual) |
🛠️ 4. Sua Oficina: Android Studio
A ferramenta oficial para criar apps Android.
- Baseada no IntelliJ IDEA.
- Emulador integrado.
- Layout Editor visual.
⚠️ Requisitos de Hardware
Para não passar raiva:
- RAM: 8GB (Mínimo) / 16GB (Sonho).
- Disco: SSD é OBRIGATÓRIO.
- Processador: i5 ou superior.
📂 5. Anatomia de um Projeto
O que tem dentro das pastas?
O Manifesto 📜
O arquivo AndroidManifest.xml é o "RG" do seu App.
- Nome do App.
- Quais telas existem (Activities).
- Quais permissões ele precisa (Internet, Câmera).
🧠 6. Por que Nativo?
Frameworks vêm e vão, mas o Nativo permanece.
"Quem entende a base, não teme a mudança."
🆚 Kotlin vs Swift
São linguagens "irmãs" na sintaxe!
🚀 Desafio de Hoje
- Instalar o Android Studio.
- Criar seu primeiro projeto "Empty Activity".
- Mudar o texto do "Hello World" para seu nome.
🏁 Conclusão
- Mobile é o presente e o futuro.
- Escolher o caminho Nativo te dá superpoderes.
- Próxima aula: Java para Android.
❓ Dúvidas?
Siga para o canal oficial da disciplina no Teams!
Fim da Aula 01 👋
Aula 02 - Java para Android ☕
🎯 Por que aprender Java em 2026?
"O Kotlin não matou o Java?"
- Base Sólida: O Android é feito de Java.
- Legado: Bilhões de linhas de código em produção.
- Mercado: Muitas empresas pedem os dois.
🧱 A Base da Sintaxe
Java é uma linguagem de tipagem estática e explícita.
📦 Variáveis e Tipos
Onde guardamos os dados na memória.
- int: Números inteiros.
- double: Números decimais.
- boolean: true ou false.
- String: Texto (É uma classe!).
Cuidado com o Null! 👻
Em Java, objetos podem ser null.
Isso causa o famoso NullPointerException.
🔀 Estruturas de Decisão
int idade = 20;
if (idade >= 18) {
System.out.println("Pode dirigir");
} else {
System.out.println("Aguarde mais um pouco");
}
🔁 Estruturas de Repetição
🏛️ Orientação a Objetos (POO)
O coração do desenvolvimento nativo.
- Classe: O molde (Planta da casa).
- Objeto: A instância (A casa construída).
Exemplo: Classe Carro 🚗
🧬 Herança: O extends
No Android, usamos herança o tempo todo.
🔒 Encapsulamento
Proteja seus dados!
- public: Todos veem.
- private: Só a classe vê.
Use getters e setters para acessar dados privados.
🗺️ Android Studio: Onde o Java vive
Ao criar um App, o código Java fica na pasta:
app/src/main/java/
Ciclo de Vida: O onCreate
O primeiro contato com o Android.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
🔬 Comparação: Java vs Swift
No iOS (Swift), os conceitos são os mesmos, muda a "roupa".
- Java:
public class - Swift:
class(mais simples)
🛠️ Ferramentas da Aula
- JDK instalado.
- IntelliJ ou Android Studio.
- Treinar lógica básica no console.
🧩 Exercício Rápido
Crie uma classe Usuario com:
* Nome (String)
* Idade (int)
* Método verificarIdade() que diz se é maior de idade.
⚡ De Java para Kotlin
Na aula de hoje vimos Java. Nas próximas, veremos como o Kotlin simplifica TUDO isso.
Mas sem entender o Java, você será apenas um "copiador de código".
🏁 Resumo
- Java é a fundação.
- POO é essencial para Android.
- Classes, Atributos e Métodos são seus novos amigos.
❓ Pergunta do Dia
"Posso criar um app Android sem saber nadinha de Java?"
Pode, mas na primeira biblioteca antiga que você baixar, vai travar!
Próxima Aula: Kotlin Moderno ⚡
Valeu, pessoal! 👋
Aula 03 - Kotlin Moderno ⚡
🚀 O que é Kotlin?
A linguagem que mudou o Android.
- Criada pela JetBrains (2011).
- Oficial no Android (Google I/O 2017).
- Moderna, Segura e Concisa.
🛡️ Null Safety: O Fim dos Crashes
O pesadelo do Java era o null.
O Kotlin resolveu isso na raiz.
Para permitir nulos:
📦 Variáveis: val vs var
No Kotlin, preferimos a imutabilidade.
- val: Imutável (referência não muda). 🔒
- var: Mutável (pode mudar o valor). 🔓
⚡ Inferência de Tipos
O Kotlin é inteligente. Ele sabe o tipo sem você dizer.
💬 Interpolação de Strings
Diga adeus ao + " " +.
🕴️ Operador Elvis ?:
"Se for nulo, faça isso".
🛠️ Funções: Simplicidade
fun somar(a: Int, b: Int): Int {
return a + b
}
// Versão "Single Line"
fun somar(a: Int, b: Int) = a + b
🏗️ Estruturas de Decisão
O if e o when no Kotlin são expressões (retornam valor).
val status = if (nota >= 6) "Aprovado" else "Reprovado"
when (nota) {
10 -> println("Genial!")
in 7..9 -> println("Muito bom")
else -> println("Tente mais")
}
📋 Coleções
Listas que facilitam a vida.
val numeros = listOf(1, 2, 3) // Imutável
val nomes = mutableListOf("Ana", "Bia") // Mutável
nomes.add("Caio")
🏛️ Classes e Objetos
Mais limpo que o Java.
class Carro(val model: String, var ano: Int)
val meuCarro = Carro("Fusca", 1970)
println(meuCarro.model)
📊 Data Classes
Onde o Kotlin brilha de verdade.
data class Usuario(val id: Int, val email: String)
// Gera automaticamente: toString, equals, hashCode, copy...
🧬 Interoperabilidade
Você pode misturar Java e Kotlin no mesmo projeto sem problemas.
graph LR
A[Java Code] <--> B[Kotlin Code]
B --> C[Bytecode JVM]
C --> D[Dalvik/ART Android]
🍎 Comparação: Swift
O Kotlin e o Swift são quase "gêmeos" na sintaxe moderna.
| Recurso | Kotlin | Swift |
|---|---|---|
| Constante | val |
let |
| Variável | var |
var |
| Opcional | String? |
String? |
| Função | fun |
func |
🎮 Playground da Aula
Acesse play.kotlinlang.org e teste:
- Crie uma variável que pode ser nula.
- Use o operador Elvis nela.
- Crie uma data class "Produto".
⚠️ Safe Call ?.
Chama o método apenas se não for nulo.
🏁 Conclusão
- Kotlin economiza tempo e dedos (menos código).
- Segurança contra nulos é o seu maior trunfo.
- É a linguagem do futuro do Android.
🚀 Próxima Aula: Anatomia de um App
Vamos abrir o Android Studio e ver como o Kotlin controla as telas!
Até a próxima! ⚡👋
Aula 04 - Estrutura de um App 🏗️
🧐 O que tem "debaixo do capô"?
Ao abrir um projeto no Android Studio, vemos muitas pastas. Não se desespere! Vamos entender cada uma.
📂 Visão Geral do Projeto
Existem dois modos de visão: Project e Android. Nós usaremos o modo Android (mais organizado).
1. O Manifesto 📜
app/src/main/AndroidManifest.xml
É o contrato do seu app com o sistema operacional.
- Nome e Ícone do App.
- Declaração de todas as Activities.
- Solicitação de Permissões (Câmera, GPS).
2. A Pasta java (ou kotlin) ⌨️
Onde a "mágica" acontece.
- Ficam as classes de lógica.
- Ficam as classes das telas (MainActivity).
- Organizado em pacotes (ex:
com.meuapp.telas).
3. A Pasta res (Resources) 🎨
Tudo o que o usuário vê ou ouve, mas que não é lógica.
- drawable: Imagens e ícones.
- layout: A interface visual (XML).
- mipmap: Ícones que aparecem no menu do celular.
- values: Strings, Cores e Temas.
🎨 Por que centralizar os values?
Evite escrever texto direto no código!
Facilita a tradução para outros idiomas (Internacionalização). 🌍
4. Gradle: O Gerente de Fábrica ⚙️
Não é código do seu app, é a configuração da "fábrica" que constrói ele.
build.gradle (Project): Configurações globais.build.gradle (Module): Configurações específicas do App.
📦 O que tem no Gradle?
- versionCode: Número interno (1, 2, 3...).
- versionName: Nome para o usuário (1.0.1...).
- Dependencies: Bibliotecas externas (Retrofit, Room).
🏗️ O Ciclo de Build
graph LR
A[Código Kotlin/Java] --> B[Compilador]
E[Recursos XML/Img] --> B
B --> C[Arquivo DEX]
C --> D[APK / AAB]
🆚 Estrutura: Android vs iOS
| Android | iOS | Papel |
|---|---|---|
AndroidManifest |
Info.plist |
Metadados |
res/layout |
Storyboard/XIB |
UI Visual |
gradle |
CocoaPods/SwiftPM |
Dependências |
res/values |
Localizable.strings |
Textos |
🔌 ViewBinding: O Link Seguro
Antigamente usava-se o findViewById (lento e perigoso).
Hoje usamos o ViewBinding.
Garante que você não tente acessar um ID que não existe na tela! 🛡️
🛠️ Prática: Explorando o Studio
- Abra o arquivo
Activity_main.xml. - Veja as abas Code, Split e Design.
- Mantenha no Split para aprender rápido!
⚠️ Cuidado com a pasta build
Ela é gerada automaticamente.
Nunca altere nada dentro dela manualmente. Se der erro, use o comando:
Build -> Clean Project.
🧩 Resumo
- Manifesto: Declarativo e essencial.
- Res: Visual e Multimídia.
- Gradle: Configuração e Bibliotecas.
- Java/Kotlin: Comportamento.
🚀 Desafio da Aula
- Adicione uma nova cor em
colors.xml. - Crie uma nova String em
strings.xml. - Use essa cor e essa string em um componente na tela inicial.
🏁 Conclusão
Entender a estrutura é o primeiro passo para não se perder em projetos grandes.
Próxima Aula: Interface Gráfica (Layouts)! 🎨👋
Aula 05 - Interface Gráfica (UI) 🎨
🏗️ A Hierarquia de Views
No Android, tudo o que você vê é baseado em uma árvore de elementos.
graph TD
Root[ViewGroup / Layout] --> Child1[TextView]
Root --> Child2[Button]
Root --> InnerVG[LinearLayout]
InnerVG --> GrandChild[ImageView]
🧱 Views vs ViewGroups
- View: O átomo da interface (Botão, Campo de Texto, Imagem).
- ViewGroup: O esqueleto que organiza os átomos (LinearLayout, ConstraintLayout).
📏 Unidades: dp vs sp
Regra de ouro: NUNCA use px.
- dp (Density-independent Pixels): Para tamanhos e margens.
- sp (Scale-independent Pixels): Para textos.
📐 LinearLayout
O mais simples. Organiza itens em fila.
- Vertical: Um abaixo do outro.
- Horizontal: Um ao lado do outro.
- Peso (layout_weight): Útil para preencher espaço proporcionalmente.
⚓ ConstraintLayout
O padrão da indústria moderna.
- Baseado em restrições (amarras).
- Evita aninhamento de layouts (performance 🚀).
- Flexível e responsivo para qualquer tamanho de tela.
Exemplo: Botão centralizado
<Button
android:id="@+id/btnCentro"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
🖼️ ImageView & Drawable
Como exibir imagens?
- Use vetores (SVG -> Vector Drawable) sempre que possível.
- Formatos bitmap (PNG/JPG) aumentam o tamanho do app.
- Escala:
scaleType="centerCrop"vsfitCenter.
⌨️ Entrada de Dados: EditText
- Use
inputType="textPassword"para senhas. - Use
inputType="emailAddress"para teclados customizados. - Dica:
TextInputLayout(Material Design) dá um visual premium.
💅 Temas e Estilos
Não repita código! Centralize o estilo.
🆚 Android XML vs iOS Auto Layout
| Recurso | Android | iOS |
|---|---|---|
| Pai | ViewGroup | UIView |
| Logic | Layout Params | Constraints |
| Unidade | dp | points |
| Arquivo | .xml | .storyboard / .xib |
🔗 ViewBinding na Prática
Adeus findViewById!
// Inicialização no onCreate
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Uso
binding.btnSalvar.setOnClickListener { ... }
🖱️ Eventos de Clique
♿ Acessibilidade
O Android deve ser para todos.
- contentDescription: OBRIGATÓRIO para imagens (leitores de tela).
- Cores: Contraste adequado.
- Tamanhos: Botões com pelo menos 48dp de área de toque.
🛠️ Desafio da Aula: Tela de Cadastro
Crie uma tela com: 1. Nome (EditText) 2. E-mail (EditText) 3. Senha (Password) 4. Botão "Salvar" 5. Use ConstraintLayout para posicionar tudo.
🧪 Preview de Layout
O Android Studio permite testar seu layout em diferentes dispositivos (Pixel, Tablets, Dobráveis) sem rodar o app.
- Use a aba Design para ajustes rápidos.
- Use a aba Attributes para mudar propriedades sem digitar XML.
🏁 Conclusão
- Design atrativo retém usuários.
- ViewBinding é o padrão moderno de conexão.
- ConstraintLayout é sua ferramenta mais potente.
❓ Dúvidas?
Próxima Aula: Navegação entre Telas! 🗺️👋
Aula 06 - Navegação entre Telas 🗺️
📨 O que é uma Intent?
Seu App é um conjunto de telas. As Intents são as mensagens que conectam essas telas.
- "Quero abrir a tela X".
- "Quero passar este dado para a tela Y".
- "Quero que outro app resolva este link".
🚀 Intent Explícita
Você sabe exatamente para onde quer ir.
Usado para navegação interna do seu aplicativo.
🌍 Intent Implícita
Você diz O QUE quer fazer, não QUEM deve fazer.
- O sistema Android pergunta ao usuário qual navegador ele prefere usar.
Exemplos Implícitos
- ACTION_DIAL: Abrir o discador.
- ACTION_SEND: Compartilhar algo.
- ACTION_IMAGE_CAPTURE: Abrir a câmera.
📦 Passando Dados (Extras)
O "pacote" que viaja com a Intent.
// Tela A (Enviando)
intent.putExtra("NOME", "Android")
intent.putExtra("IDADE", 15)
// Tela B (Recebendo)
val nome = intent.getStringExtra("NOME")
val idade = intent.getIntExtra("IDADE", 0)
📚 A Pilha de Voltar (Back Stack)
O Android gerencia telas como uma pilha de pratos.
startActivitycoloca um prato no topo.- Botão "Back" (Voltar) tira o prato do topo.
- O prato que estava embaixo volta a ser visível.
O Comando finish() 🧹
Encerra a Activity atual e a remove da pilha.
startActivity(Intent(this, HomeActivity::class.java))
finish() // O usuário não consegue voltar para a tela anterior
Ideal para fluxos de Login e Splash Screens.
🆚 Navegação: Android vs iOS
| Conceito | Android | iOS |
|---|---|---|
| Componente | Activity | ViewController |
| Pilha | Back Stack | Navigation Controller |
| Ação | Intent | Segue / Push |
| Dados | Extras | Properties / PrepareForSegue |
🎨 Transições entre Telas
Dê vida ao seu app!
🧭 Navigation Component (Jetpack)
A forma moderna e visual.
- Navigation Graph: Mapa visual das telas.
- Fragments: Telas "leves" dentro de uma única Activity.
- Safe Args: Passagem de dados sem erros de digitação.
🛠️ Prática: Indo para os Detalhes
- Crie uma nova Activity chamada
DetalhesActivity. - No
MainActivity, adicione um botão. - No clique do botão, peça para abrir os Detalhes.
Código da Prática
binding.btnIr.setOnClickListener {
val intent = Intent(this, DetalhesActivity::class.java)
intent.putExtra("INFO", "Vindo da Main!")
startActivity(intent)
}
⚠️ Cuidado com a Memória
Abrir muitas Activities sem dar finish() pode deixar o app pesado e confuso.
Pergunte-se: "O usuário deve conseguir voltar para esta tela?"
🧬 Mermaid: Fluxo de Navegação
graph LR
S[Splash] -->|finish| L[Login]
L -->|finish| H[Home]
H <--> D[Detalhes]
H <--> P[Perfil]
P -->|Logout + clear_task| L
🚀 Desafio da Aula: O Mensageiro
- Crie uma tela com um
EditTexte umButton. - Ao clicar, abra uma segunda tela exibindo o texto que foi digitado.
- Na segunda tela, coloque um botão "Voltar" customizado que dá um
finish().
🏁 Resumo
- Intents: Mensageiros universais.
- Extras: O conteúdo da mensagem.
- Back Stack: A memória de onde viemos.
❓ Perguntas?
Próxima Aula: Listas Dinâmicas (RecyclerView)! 📋👋
Aula 07 - Arquitetura MVVM 🏗️
🦸 O Problema da God Activity
Sua Activity faz tudo? * Chama a internet. * Valida campos. * Salva no banco. * Desenha a tela.
Isso é um pesadelo de manutenção! 😱
📐 O Padrão MVVM
Recomendado pelo Google (Android Jetpack).
- Model: Dados e Lógica de Negócio.
- View: UI (Activity/XML). Burra e Visual.
- ViewModel: O cérebro. Faz a ponte entre os dois.
O Fluxo de Dados
graph LR
V[View] -->|Ações| VM[ViewModel]
VM -->|Observa| V
VM <-->|Dados| M[Model/Repo]
🧠 O ViewModel
Seu maior superpoder: Sobrevivência.
- Quando você gira a tela, a Activity morre e renasce.
- O ViewModel permanece vivo na memória.
- Os dados não são perdidos! 💎
📡 LiveData
O mensageiro que respeita a vida.
- É um container de dados observável.
- A View diz: "Me avise quando o dado mudar".
- Se a View estiver em background, o LiveData espera ela voltar para avisar.
Exemplo de LiveData
🏗️ Camada Model & Repository
Não deixe o ViewModel saber de ONDE vêm os dados.
- O Repository decide: "Vou buscar na Internet ou no Banco local?"
- O ViewModel apenas pede: "Me dê a lista de usuários".
🆚 MVVM vs Outros
| Padrão | Característica |
|---|---|
| MVC | Controller fica sobrecarregado. |
| MVP | Presenter e View muito acoplados. |
| MVVM | View observa o ViewModel (Desacoplado). |
🧪 Benefícios para Testes
Testar UI é lento e caro. Testar lógica no ViewModel é fast & cheap. ⚡
Com MVVM, você testa a lógica sem precisar abrir o emulador.
🧬 Data Binding (Avançado)
Imagine ligar o dado do ViewModel direto no XML.
- Menos
binding.textView.text = ...na Activity. - Código mais limpo.
🛠️ Prática da Aula: Contador MVVM
- Crie uma Activity com um botão e um texto.
- Crie um
MainViewModelcom umcounter: MutableLiveData<Int>. - No clique, chame
counter.value = (counter.value ?: 0) + 1. - Observe o contador na Activity.
O Segredo da Rotação 🔄
Teste seu app: 1. Clique 5 vezes (Contador = 5). 2. Gire o celular. 3. Se o contador continuar em 5, você implementou MVVM corretamente! ✅
🆚 MVVM no iOS
No iOS moderno usamos @StateObject e @Published.
O conceito de "Reatividade" é o mesmo!
📊 Vantagens Reais
- Manutenibilidade: Código organizado por pastas.
- Escalabilidade: Fácil adicionar novas telas.
- Performance: UI Thread fica livre para animações.
🏁 Conclusão
- Não seja um refém da
MainActivity. - Use o ViewModel para guardar o estado.
- Deixe o LiveData atualizar sua tela.
❓ Dúvidas?
Próxima Aula: Persistência de Dados (Room)! 💾👋
Aula 08 - Persistência de Dados 💾
💾 Onde guardamos os dados?
Apps precisam lembrar das coisas quando fechados.
- Configurações simples.
- Listas complexas.
- Arquivos multimídia.
1. SharedPreferences 🔑
A forma mais simples: Chave e Valor.
- "nome" -> "Ricardo"
- "notificacoes_on" -> true
- "tema" -> 1
Usando PreferenceManager
val prefs = getSharedPreferences("config", MODE_PRIVATE)
// Gravar
prefs.edit().putString("USER", "Android").apply()
// Ler
val user = prefs.getString("USER", "Ninguém")
Atenção: Não use para dados grandes ou listas!
🏛️ Banco de Dados: SQLite
O Android tem o SQLite no seu coração.
- Banco Relacional.
- Leve e embutido.
- Mas... o código puro é horrível (SQL strings).
🔨 Conheça o ROOM
A biblioteca do Jetpack que salva vidas.
- Entity: Sua tabela (Classe de dados).
- DAO: Seus comandos (Queries).
- Database: O gerente do banco.
Passo 1: A Entidade (@Entity)
Passo 2: O DAO (@Dao)
@Dao
interface UserDao {
@Insert
void save(User user)
@Query("SELECT * FROM User")
LiveData<List<User>> getAll()
}
🧵 A Regra de Ouro do Banco
NUNCA acesse o banco na Main Thread.
- O Room vai travar seu app (Crash) se você tentar.
- Use Coroutines ou LiveData.
- Por que? Porque ler o disco é lento e trava a tela.
🧬 Ciclo Completo: MVVM + Room
graph TD
UI[Activity/View] -->|Observa| VM[ViewModel]
VM -->|Pede| REPO[Repository]
REPO -->|Query| DB[(Room DB)]
DB -->|Retorna| REPO
REPO -->|State| VM
VM -->|LiveData| UI
📂 Arquivos Externos
Para fotos e vídeos.
- Cache: Temporário.
- Arquivos Privados: Só seu app vê.
- Arquivos Públicos: Galeria, Downloads (Precisa de permissão).
🆚 Persistência: Android vs iOS
| Recurso | Android | iOS |
|---|---|---|
| Simples | SharedPreferences | UserDefaults |
| Banco | Room (SQLite) | Core Data / SwiftData |
| Arquivos | Scoped Storage | Sandbox |
🕵️ Ferramenta: App Inspection
No Android Studio, você pode ver o banco de dados ao vivo.
- Rode o app.
- Aba
App Inspection->Database Inspector. - Você pode editar os dados e ver a tela do celular mudar! 🎩
🛠️ Prática: Lista de Tarefas
Vamos criar um banco para salvar textos.
- Configure o Room no
build.gradle. - Crie a Entity
Task. - Salve um texto vindo de um
EditText.
Dica: O Singleton do Banco
Não crie várias instâncias do banco. Use o padrão Singleton.
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "database-name"
).build()
🏁 Conclusão
- Escolha a ferramenta certa para o dado certo.
- Room é o padrão para dados estruturados.
- Sempre use threads de background (IO).
❓ Dúvidas sobre Dados?
Próxima Aula: Listas com RecyclerView! 📋👋
Aula 09 - Listas Eficientes (RecyclerView) 📋
🐢 O Problema das Listas Gigantes
Imagine uma lista com 10.000 contatos. Criar 10.000 objetos de layout travaria qualquer celular.
- Memória cheia.
- Lag na rolagem.
- App fechando (Crash).
♻️ A Mágica da Reciclagem
O RecyclerView não cria 10.000 itens. Ele cria apenas o que cabe na tela (+ uns 2 ou 3 de reserva).
- Item sai por cima -> Entra na "piscina".
- Item entra por baixo -> Pega um layout da piscina e só troca o texto.
O Mecanismo visual
graph TD
A[Item 1 sai ↑] --> P((Piscina de Views))
P --> B[Item 12 entra ↓]
⚔️ Os 3 Pilares
Para fazer um RecyclerView, você precisa de:
- LayoutManager: Define o formato (Lista, Grade, etc).
- ViewHolder: Guarda as referências dos IDs (Gaveta).
- Adapter: Liga os dados às Views (O Cérebro).
📐 1. LayoutManager
Troque a cara da sua lista com 1 linha:
- LinearLayoutManager: Lista vertical/horizontal.
- GridLayoutManager: Grade (estilo galeria).
- StaggeredGridLayoutManager: Grade tipo Pinterest.
🗄️ 2. ViewHolder
Evita que o Android tenha que procurar o findViewById milhares de vezes.
class MeuViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val nome = view.findViewById<TextView>(R.id.txtNome)
}
🧠 3. Adapter
Onde a lógica acontece.
onCreateViewHolder: Infla o layout do XML.onBindViewHolder: Coloca os dados na tela.getItemCount: Diz quantos itens a lista tem.
👆 Lidando com Cliques
O RecyclerView não tem clique nativo. Nós criamos!
🆚 Android vs iOS
O mecanismo é IGUAL. Só mudam os nomes.
| Conceito | Android | iOS |
|---|---|---|
| Componente | RecyclerView | UITableView |
| Reciclagem | Scrap Heap | Reusable Cell |
| Dados | Adapter | Data Source |
| Gaveta | ViewHolder | UITableViewCell |
🚀 Otimização: ListAdapter & DiffUtil
notifyDataSetChanged() é coisa do passado.
- O DiffUtil calcula o que mudou.
- Animações automáticas de inserção e remoção.
- Muito mais rápido para o processador.
🛠️ Prática: Lista de Compras
- Crie um layout
item_produto.xml. - Crie a lista de objetos
Produto. - Implemente o Adapter e veja a mágica da rolagem fluida.
Dica: CardView 🃏
Use MaterialCardView nos seus itens para ganhar sombras e bordas arredondadas automaticamente!
<com.google.android.material.card.MaterialCardView ...>
<!-- Seus textos/imagens aqui -->
</com.google.android.material.card.MaterialCardView>
⚠️ Erro Comum
Tentar atualizar a lista e esquecer de avisar o Adapter.
Sempre que o dado do banco/internet chegar, use:
adapter.submitList(novaLista) (se usar ListAdapter).
🏁 Conclusão
- RecyclerView é obrigatório em 99% dos apps.
- O foco é performance e economia de memória.
- Masterize o Adapter e você dominará o Android.
❓ Perguntas sobre Listas?
Próxima Aula: Consumo de APIs com Retrofit! 🌍👋
Aula 10 - APIs REST & Retrofit 🌍
📡 O App e a Internet
Raramente um app vive sozinho. Ele precisa de dados externos.
- Previsão do tempo.
- Posts de redes sociais.
- Salvar pedidos em um servidor.
🍕 O Conceito de API REST
Pense em um restaurante (Servidor) e você (Cliente).
- Request: Você pede um prato.
- Endpoint: A mesa do restaurante (
/pedidos). - Response: O prato chega (JSON).
O Formato JSON 📦
É como o mundo troca dados hoje.
🚀 Conheça o Retrofit
A biblioteca da Square que é o padrão absoluto no Android.
- Transforma APIs em interfaces Kotlin.
- Faz o "parse" do JSON automaticamente.
- Suporte nativo a Coroutines.
🔨 Implementação em 3 Passos
1. A Data Class (O Modelo)
Deve ser o espelho do JSON.
2. A Interface (O Contrato)
interface ApiService {
@GET("posts")
suspend fun obterPosts(): List<Post>
@GET("posts/{id}")
suspend fun obterPostUnico(@Path("id") id: Int): Post
}
3. A Instância (O Cliente)
val retrofit = Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val api = retrofit.create(ApiService::class.java)
🧠 Chamando na ViewModel
Nunca trave a UI Thread!
viewModelScope.launch {
try {
val lista = api.obterPosts()
_posts.value = lista
} catch (e: Exception) {
// Tratar erro (falta de internet, 404...)
}
}
🔐 Autenticação (JWT Tokens)
A maioria das APIs exige login.
- Bearer Token: Um código que você envia no Header.
- Interceptor: Adiciona o token em TODAS as chamadas automaticamente.
🆚 Android vs iOS (Rede)
| Recurso | Android (Retrofit) | iOS (URLSession) |
|---|---|---|
| Linguagem | Interface + Annotations | Native Classes / URLRequest |
| Conversão | Gson / Moshi | Codable |
| Async | Coroutines (suspend) | Async / Await |
🌐 Permissão de Internet
No AndroidManifest.xml:
Esqueceu? O App crasha com SecurityException. 💥
🛠️ Ferramentas de Apoio
- Postman / Insomnia: Teste sua API antes de codar.
- JSON Placeholder: APIs falsas gratuitas para teste.
- QuickType.io: Gera a Data Class Kotlin direto do JSON.
🧪 Desafio da Aula: App de Repositórios
- Use a API pública do GitHub:
https://api.github.com/users/{seuUser}/repos. - Crie a Data Class e a Interface.
- Exiba o nome dos seus repositórios em uma
RecyclerView.
⚠️ Cuidado com o Main Thread
O Android não permite rede na Main Thread.
Sempre use viewModelScope.launch ou troque o Dispatcher para Dispatchers.IO.
🏁 Conclusão
- APIs conectam seu app ao mundo.
- Retrofit + Gson = Produtividade máxima.
- Atenção às permissões e erros de rede.
❓ Perguntas sobre Internet?
Próxima Aula: Threads e Coroutines! 🧵👋
Aula 11 - Threads e Coroutines 🧵
🛑 O Bloqueio da UI
O Android é um sistema exigente: ele redesenha a tela a cada 16ms (60fps).
- Main Thread: Onde tudo o que é visual acontece.
- Regra de Ouro: Nunca coloque código pesado na Main Thread.
O Erro ANR 💀
Se a Main Thread parar por +5 segundos... Application Not Responding. O sistema mata seu app.
- Download de arquivos.
- Leitura de banco de dados pesada.
- Processamento de imagens.
⚡ Kotlin Coroutines
"Threads leves".
- Você pode rodar milhões sem travar o celular.
- Código assíncrono que parece sequencial.
- Criado pela JetBrains para facilitar sua vida.
🏛️ Os 3 Pilares da Coroutine
- Job: A tarefa em si (o trabalho).
- Scope: Onde ela vive (morreu a tela, morre a tarefa).
- Dispatcher: Em qual pista ela corre (Threads).
🚦 Conheça os Dispatchers
- Main: Só para interface (UI).
- IO: Rede, Banco, Arquivos (Espera).
- Default: Cálculos pesados de CPU.
🛌 A palavra-chave suspend
"Esta função pode demorar, mas não vai travar o celular".
🧠 Coroutines na ViewModel
class MeuViewModel : ViewModel() {
fun carregar() {
viewModelScope.launch { // Inicia no Scope seguro
val dados = withContext(Dispatchers.IO) {
api.getDados() // Roda em background
}
binding.txt.text = dados // Volta pra Main e atualiza
}
}
}
🔌 Sockets (Tempo Real)
REST é: "Eu peço, você responde". Socket é: "Canal aberto, qualquer um fala".
- Full-Duplex: Envio e Recebimento simultâneo.
- Casos: Chat, GPS em tempo real, Bolsa de Valores.
Socket vs REST
sequenceDiagram
participant App
participant Server
Note over App,Server: REST (Request/Response)
App->>Server: Me dá os dados?
Server->>App: Aqui estão. (Fecha)
Note over App,Server: Socket (Persistent)
App->>Server: Abre conexão
Server->>App: Conectado!
Server->>App: Mensagem nova!
App->>Server: Valeu!
🆚 Android vs iOS (Async)
| Recurso | Android (Kotlin) | iOS (Swift) |
|---|---|---|
| Padrão | Coroutines | Async / Await |
| Palavra | suspend |
async |
| Chamada | launch |
Task |
| Espera | delay |
try await Task.sleep |
🚫 Cancelamento Automático
O viewModelScope é fantástico.
- Usuário abre a tela e começa o download.
- Usuário fecha o app ou muda de tela.
- O download é cancelado na hora. Economia de bateria e dados!
🛠️ Prática: O Simulador de Corrida
suspend fun corrida() {
println("3...")
delay(1000)
println("2...")
delay(1000)
println("1...")
delay(1000)
println("JÁ!")
}
- Chame isso num clique de botão e tente clicar em outro botão enquanto a contagem ocorre. Se funcionar, você venceu o ANR! 🏆
🏁 Conclusão
- Main Thread é sagrada.
- Coroutines trazem ordem ao caos assíncrono.
- Sempre use
viewModelScopepara segurança.
❓ Perguntas sobre Threads?
Próxima Aula: UX e Material Design 3! 🎨👋
Aula 12 - UX e Material Design 3 🎨
💄 O que é Material Design?
O sistema de design do Google.
- Criado em 2014.
- Inspirado em papel e tinta.
- Agora na versão 3: Material You.
🌸 Material You (M3)
A personalização elevada ao máximo.
- Cores Dinâmicas: O app suga as cores do papel de parede do usuário.
- Acessibilidade: Foco em contraste e tamanhos de toque.
- Expressividade: Formas orgânicas e arredondadas.
📐 O Grid de 8dp
No Android, medimos tudo em múltiplos de 8.
- 8, 16, 24, 32, 40...
- Isso garante alinhamento harmônico em qualquer tela.
- Regras de margem e padding seguem esse padrão.
🔘 Componentes Modernos
1. FAB (Floating Action Button)
O botão que "flutua" sobre o conteúdo.
- Representa a ação principal.
- Ex: Criar novo e-mail, Adicionar tarefa.
2. Cards 🃏
Agrupam informações relacionadas.
- Elevação (sombras).
- Bordas arredondadas (12dp a 28dp).
3. Bottom Navigation 🧭
Navegação principal ao alcance do polegar.
- Entre 3 e 5 destinos.
- Ideal para uso com uma mão só.
🌑 Dark Mode: Não é opcional!
O usuário ama o tema escuro.
- Economia de bateria (telas OLED).
- Descanso visual à noite.
- Como fazer: Pasta
values-night/colors.xml.
🆚 Material (Android) vs HIG (iOS)
| Característica | Android (Material) | iOS (HIG) |
|---|---|---|
| Foco | Elevação / Camadas | Transparência / Blur |
| Botões | FAB / Sombreados | Flat / Bordas finas |
| Navegação | Drawer / Bottom Nav | Tab Bar Superior/Inferior |
| Espírito | Papel e Tinta | Vidro e Minimalismo |
🔡 Tipografia: Roboto e Além
A fonte oficial do Android.
- Use pesos variados para criar hierarquia.
- Título: Bold / Grande.
- Corpo: Regular / 14sp ou 16sp.
🌊 Feedback Visual (Ripples)
"O app está me ouvindo?"
- Sempre que o usuário tocar, algo deve acontecer.
- Efeito Ripple (Onda) é o padrão.
🛠️ Prática: Estilizando com M3
- No
build.gradle, use Material 1.9.0+. - No XML, troque
ButtonporMaterialButton. - Teste o atributo
app:cornerRadiuse veja a mudança.
🧬 Mermaid: Camadas UI
graph TD
A[Barra de Status]
B[Barra de App - TopAppBar]
C[Conteúdo - RecyclerView]
D[Botão Flutuante - FAB]
E[Barra Inferior - BottomNav]
A --> B
B --> C
C --> D
D --> E
🧠 UX: Experiência do Usuário
UX não é só "bonito", é "funcional".
- Velocidade: Carregamento rápido.
- Clareza: Icons autoexplicativos.
- Prevenção: Não deixe o usuário errar (validações).
🏁 Conclusão
- Design ruim mata apps bons.
- Siga o grid de 8dp.
- Pense sempre na acessibilidade (Content Description!).
❓ Perguntas sobre Visual?
Próxima Aula: Sensores e Hardware! 📸👋
Aula 13 - Sensores e Hardware 📸
📱 Além da Tela
O smartphone é um laboratório de sensores. Apps nativos têm "superpoderes" para sentir o mundo físico.
- Onde eu estou? (GPS)
- O que eu estou vendo? (Câmera)
- Estou me movendo? (Acelerômetro)
🔑 O Porteiro: Permissões
No Android 6.0+, as permissões são dinâmicas.
- Normais: Declaradas no Manifest (Internet, BT).
- Perigosas: Pop-up em tempo de execução (GPS, Câmera, Microfone).
Sempre verifique se tem a permissão antes de usar o hardware! 🛡️
Pedindo Permissão (Moderno)
val launcher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { concedida ->
if (concedida) { /* Use o hardware */ }
}
launcher.launch(Manifest.permission.CAMERA)
🗺️ Localização e GPS
Use o Fused Location Provider.
- Por que? Ele mistura GPS, Wi-Fi e Células de rede.
- Vantagem: Menos gasto de bateria e maior precisão.
- Maps SDK: Exiba a localização visualmente.
📸 A Câmera com CameraX
Esqueça a dor de cabeça da Camera2 API.
- Preview: Imagem em tempo real.
- Capture: Tirar e salvar foto.
- Analysis: Analisar frames (QR Code, IA).
🎢 Sensores de Movimento
Acelerômetro e Giroscópio.
- Detectar o "Shake" (Balançar).
- Rodar a tela automaticamente.
- Realidade Aumentada (AR).
🔵 Bluetooth (Classic e BLE)
Conecte-se a tudo.
- Classic: Som, Arquivos grandes.
- BLE (Low Energy): Sensores, IoT, Smartwatches.
- Eddystone/iBeacons: Localização interna por proximidade.
📞 Telefonia e SMS
Sim, ainda é um telefone!
- SmsManager: Envie e receba mensagens programaticamente.
- TelephonyManager: Saiba a operadora e o estado da rede.
Cuidado: O Google Play é muito rígido com permissões de SMS. ⚠️
🔐 Biometria Segura
Impressão digital e Rosto.
- Use o
BiometricPrompt. - Nunca guarde a digital do usuário! O sistema apenas diz "Confere" ou "Não Confere".
🆚 Android vs iOS (Hardware)
| Recurso | Android | iOS |
|---|---|---|
| GPS | Fused Location | Core Location |
| Câmera | CameraX | AVFoundation |
| Sensores | SensorManager | Core Motion |
| Bluetooth | BluetoothAdapter | Core Bluetooth |
🧬 Mermaid: Ciclo de Hardware
graph TD
A[Usuário quer Foto] --> B{Tem Permissão?}
B -- Não --> C[Pedir Permissão]
C --> D{Aceitou?}
D -- Não --> E[Mostrar Aviso]
B -- Sim --> F[Abrir CameraX]
D -- Sim --> F
F --> G[Salvar Imagem]
🛠️ Prática: O Sensor de Luz
- Obtenha o
SensorManager. - Escolha o
Sensor.TYPE_LIGHT. - Se a luz baixar (colocar a mão sobre o sensor), mostre um aviso "Está escuro!".
🏁 Conclusão
- Hardware exige permissão e cuidado.
- CameraX e Fused Location são seus melhores amigos.
- Respeite a bateria do usuário! Pare de ouvir sensores no
onPause.
❓ Perguntas sobre Hardware?
Próxima Aula: Testes e Qualidade! 🐞👋
Aula 14 - Testes e Qualidade 🐞
🔍 Por que testar?
Erros custam caro.
- Perda de usuários.
- Má fama na loja (1 estrela).
- Prejuízo financeiro.
"Testar é o ato de provar que seu código faz o que você diz que ele faz."
📝 O Logcat Profissional
Pare de usar println. Use etiquetas!
- Log.d: Debug (lógica).
- Log.i: Informação (eventos).
- Log.w: Aviso (algo estranho).
- Log.e: Erro grave.
🛠️ O Modo Debug (Besouro)
Seu superpoder de investigação.
- Breakpoint: "Congele" o tempo naquela linha.
- Variables Panel: Veja o que tem dentro de cada objeto.
- Evaluate Expression: Execute código no meio da pausa! 🎩
🏔️ A Pirâmide de Testes
Não teste tudo da mesma forma.
- Unitários (70%): Lógica pura, rápidos.
- Integração (20%): Peças conversando.
- UI / Espresso (10%): O robô clica na tela.
Teste Unitário (JUnit) 🧪
@Test
fun login_comSenhaVazia_deveRetornarErro() {
val result = validador.verificar("", "123")
assertFalse(result)
}
- Roda no seu PC (JVM).
- Leva milissegundos.
Teste de UI (Espresso) ☕
O robô que simula o usuário.
onView(withId(R.id.btnEnter)).perform(click())
onView(withId(R.id.txtWelcome)).check(matches(isDisplayed()))
- Roda no Emulador/Celular.
- Lento, mas testa a experiência real.
🛡️ Tratamento de Exceções
Previna o "O App parou".
🆚 Android vs iOS (Qualidade)
| Ferramenta | Android | iOS |
|---|---|---|
| Unit Testing | JUnit / Mockito | XCTest |
| UI Testing | Espresso / Barista | XCUITest |
| Logs | Logcat | Console (os_log) |
| Profiler | Android Profiler | Xcode Instruments |
🏃 CI/CD: Automação
Nunca envie código quebrado para o GitHub.
- GitHub Actions: Roda seus testes a cada "Push".
- Lint: Analisa se o seu código está limpo e segue padrões.
🛠️ Prática: Meu Primeiro Teste
- Vá na pasta
src/test/java. - Crie uma função que soma dois números.
- Escreva um
@Testque useassertEquals. - Clique no "Play" verde ao lado da função.
🏁 Conclusão
- Programador bom é o que testa.
- Use logs com sabedoria.
- Aprenda a ler o Stack Trace (o relatório de erros).
❓ Perguntas sobre Qualidade?
Próxima Aula: Publicação na Google Play! 🚀👋
Aula 15 - Publicação na Google Play 🚀
🏁 A Reta Final
Seu app está pronto e testado. Agora, como o mundo vai baixá-lo?
- Google Play (Android).
- App Store (iOS).
- Distribuição Direta (APK/Enterprise).
📦 APK vs AAB
O passado e o futuro dos pacotes.
- APK: Um arquivo gigante para todos os celulares.
- AAB (App Bundle): O Google gera o APK sob medida para cada usuário.
- Resultado: Downloads até 50% menores! 💎
🔑 A Chave da Vida (Keystore)
Todo app de produção deve ser assinado.
- O arquivo
.jksé o seu RG. - AVISO CRÍTICO: Se perder a senha ou o arquivo, você nunca mais poderá atualizar o app. Guarde na nuvem, no HD e no papel! 💾
🎮 Google Play Console
O portal dos campeões.
- Taxa: $25 (Única e vitalícia).
- Análise: O Google revisa seu app (1 a 7 dias).
- Políticas: Cuidado com direitos autorais e privacidade.
🛡️ Ofuscação (R8 / ProGuard)
Proteja seu código original.
- Transforma
MinhaClasseDeLoginema.b.c. - Remove código morto.
- Dificulta a pirataria e engenharia reversa.
📈 Versão e Build
No build.gradle:
- versionCode: 1, 2, 3... (Sempre sobe).
- versionName: "1.0.0", "1.1.2" (O que o usuário vê).
🎨 Marketing na Loja (ASO)
Não basta ser bom, tem que parecer bom.
- Ícone: A cara do seu app (512px).
- Feature Graphic: O banner de impacto.
- Screenshots: Mostre as melhores telas!
🆚 Android vs iOS (Loja)
| Característica | Google Play | App Store |
|---|---|---|
| Custo | $25 (Única) | $99 (Anual) |
| Revisão | Média de 2 dias | Média de 24h a 48h |
| Rigidez | Moderada | Alta / Rigorosa |
| Formato | AAB / APK | IPA |
🧪 Canais de Teste
Teste com pessoas reais antes do lançamento.
- Teste Interno: Amigos e equipe.
- Teste Fechado (Beta): Grupo seleto.
- Produção: O mundo todo!
🏆 Checklist de Lançamento
- [ ] Removi todos os
Log.d? - [ ] O nome do app está correto?
- [ ] O ícone é o de produção (não o padrão)?
- [ ] Tenho os links de Política de Privacidade?
🏁 Conclusão
- Publicar é um processo burocrático mas gratificante.
- A segurança da Keystore é sua prioridade #1.
- Marketing (ASO) é o que traz downloads.
❓ Perguntas sobre Lançamento?
Próxima Aula: Projeto Final e Portfólio! 🎓👋
Aula 16 - A Grande Conclusão 🎓
🏆 Você Conseguiu!
De "Zero" a Desenvolvedor Mobile Nativo.
- Entendeu a base (Java/Kotlin).
- Dominou a estrutura (Manifest/Gradle/Res).
- Construiu interfaces (XML/Material).
- Conectou com o mundo (API/Rede).
🧠 Recapitulação: O Arsenal do Dev
- Linguagem: Kotlin Moderno.
- Arquitetura: MVVM (ViewModel + LiveData).
- Persistência: Room (Bancos Locais).
- Rede: Retrofit (Internet).
- UI: RecyclerView & ConstraintLayout.
🚀 O Próximo Nível
O aprendizado nunca termina.
- Jetpack Compose: UI Declarativa (O futuro).
- KMP (Kotlin Multiplatform): Compartilhe lógica com iOS.
- Hilt/Koin: Injeção de Dependências.
- Coroutines Avançado: Flow e StateFlow.
💼 Carreira e Portfólio
Como conseguir a primeira vaga?
- GitHub Ativo: Commits frequentes.
- README Impecável: Explique SEU projeto.
- Publicação: Ter um app na Play Store vale ouro.
📱 iOS: A Outra Metade
Agora que você sabe Android, aprender iOS será MUITO mais fácil.
- Swift ≈ Kotlin.
- SwiftUI ≈ Jetpack Compose.
- Lógica de negócio é a mesma!
⚔️ Nativo vs Híbrido
Você escolheu o caminho da performance e do controle total.
"Aplicações nativas entregam a melhor experiência possível que o hardware pode oferecer."
🎓 O Projeto Final
Sua obra-prima.
- Aplique tudo o que vimos.
- Resolva um problema real.
- Capriche no visual (UX/UI).
✨ Mensagem de Despedida
O mundo está no bolso das pessoas. Você agora tem a chave para entrar lá.
"A tecnologia move o mundo, mas são as pessoas que movem a tecnologia."
🏁 Fim da Jornada
Obrigado por nos acompanhar nesta trilha. Nos vemos na Play Store! 🚀
Ricardo TecPro & Equipe 👋
Configuração
Ambientes de Desenvolvimento 🛠️
Guias para configurar seu computador para o desenvolvimento mobile e entender o ecossistema de computação.
-
Core Android --- Instalação do Android Studio, SDK e emuladores.
-
Core iOS --- Configuração básica de Xcode e ferramentas Mac.
-
Ferramentas --- Git, Terminais e Postman para testes de API.
-
Linguagem & Ambiente --- Configuração para Java, JDK e Kotlin Multiplataforma.
-
Ecossistema Hardware --- Do Silício ao Software e o Caso Apple.
-
Abstração e Sistemas --- Virtualização, Baixo Nível e Ecossistemas Modernos.
Setup 01: Android Studio 🤖
O Android Studio é a IDE oficial para o desenvolvimento Android.
1. Requisitos de Sistema
- RAM: Mínimo 8GB (Sugerido 16GB+).
- Espaço: Mínimo 10GB para IDE + SDKs.
- Processador: Intel Core i5 ou equivalente.
2. Instalação
- Acesse o site oficial: developer.android.com/studio.
- Baixe a versão mais recente para o seu Sistema Operacional.
- Execute o instalador e escolha a opção "Standard" na configuração inicial.
3. Configurando o SDK
- Após a instalação, vá em Settings > Languages & Frameworks > Android SDK.
- Certifique-se de que a versão mais recente do Android (estável) esteja instalada.
- Na aba SDK Tools, instale o "Android Emulator" e o "Intel x86 Emulator Accelerator (HAXM)" se estiver no Windows com Intel.
4. Criando um Emulador (AVD)
- Abra o Device Manager.
- Clique em Create Device.
- Escolha um dispositivo (ex: Pixel 7).
- Selecione uma imagem de sistema (ex: Level 34 - Android 14).
- Finalize e clique no "Play" para iniciar o celular virtual.
5. Solução de Problemas ⚠️
- VT-x is disabled: Você precisa habilitar a virtualização na BIOS do seu computador.
- Studio muito lento: Adicione a pasta do projeto e as pastas do Android SDK nas exclusões do seu Antivírus.
Setup 02: Xcode (iOS Foundation) 🍎
O Xcode é a ferramenta necessária para compilar e testar apps iOS.
[!IMPORTANT] O Xcode requer um computador Mac (macOS).
1. Instalação
- Abra a App Store no seu Mac.
- Pesquise por Xcode.
- Clique em Obter/Instalar.
- Após o download, abra o Xcode para carregar os componentes adicionais do macOS.
2. Configurando Simuladores
- Vá em Settings > Platforms.
- Verifique se o componente "iOS" está baixado.
- Se não estiver, clique em "GET" para baixar a versão mais estável.
3. Comandos de Linha (CLI)
Para que ferramentas de automação funcionem, você precisa instalar os Command Line Tools:
4. Opcional: CocoaPods
Muitos projetos iOS antigos ainda usam CocoaPods para dependências:
5. Solução de Problemas ⚠️
- Espaço em Disco: O Xcode é muito grande. Garanta pelo menos 40GB de espaço livre para ele e os simuladores.
- Build Lento: Use simuladores de modelos mais simples (ex: iPhone SE) para poupar memória RAM se necessário.
Setup 03: Ferramentas de Apoio 🛠️
Além da IDE, você precisará de ferramentas para gerenciar código e testar dados.
1. Git e GitHub
Essencial para versionamento. * Download: git-scm.com. * Configuração Inicial:
2. Postman ou Insomnia
Para testar as APIs REST antes de escrever código Kotlin/Swift. * Postman: postman.com. * Insomnia: insomnia.rest.
3. Vysor (Opcional)
Para espelhar a tela do seu celular real no computador (via cabo USB). * Acesso: vysor.io.
4. ADB (Android Debug Bridge)
Já vem com o Android Studio, mas é útil no PATH do sistema.
* Permite instalar APKs via terminal: adb install app.apk.
* Permite ver logs detalhados: adb logcat.
5. Flipper (Meta)
Uma ferramenta avançada para debugar bancos de dados SQLite e chamadas de rede direto na interface visual. * Acesso: fbflipper.com.
Aula: Java e JDK ☕
O Coração do Ecossistema Android
O Java Development Kit (JDK) é o kit essencial para compilar e rodar aplicativos Java e a base para o desenvolvimento Kotlin.
1. JDK (Java Development Kit) 🏗️
O JDK fornece as ferramentas e bibliotecas necessárias para transformar seu código fonte em bytecode.
Fluxo de Desenvolvimento 📊
graph LR
A[Código .java] --> B[Compilador javac]
B --> C[Bytecode .class]
C --> D[JVM - Qualquer OS]
- Baixe o JDK 17 LTS (ou 21 LTS) no site da Oracle ou Adoptium.
- Instale e configure a variável de ambiente
JAVA_HOME.
Conceito: Write Once, Run Anywhere
A grande vantagem do Java é a Máquina Virtual (JVM). Você escreve o código uma vez e ele roda em qualquer hardware que tenha uma JVM instalada.
2. Na Prática: Verificando o Ambiente 💻
3. IDEs: IntelliJ vs. VS Code 💻
- IntelliJ IDEA: A melhor experiência para Java/Kotlin (versão Community é gratuita).
- VS Code: Leve e rápido, excelente para acadêmicos e projetos menores.
Dica: JAVA_HOME
Muitas ferramentas (como o Android Studio) precisam que o JAVA_HOME esteja apontando para a pasta raiz do seu JDK instalado.
📝 Exercícios Progressivos
- Nível 1: Qual a diferença entre o JRE (Java Runtime Environment) e o JDK?
- Nível 2: Por que é importante configurar a variável de ambiente
JAVA_HOME? - Nível 3: Explique como o conceito de Bytecode ajuda na portabilidade de aplicativos entre diferentes sistemas operacionais.
🚀 Mini-Projeto: OlaMundo Mobile
Objetivo: Compilar e rodar seu primeiro programa Java via terminal.
- Tarefa 1: Criar um arquivo
OlaMundo.java. - Tarefa 2: Compilar usando
javac OlaMundo.java. - Tarefa 3: Rodar usando
java OlaMundoe observar a saída.
Aula: Do Silício ao Software 🖥️
O Ecossistema da Computação Moderna
Esta aula explora a transição entre o hardware (processadores e arquiteturas) e o software (sistemas operacionais e plataformas).
1. O Alicerce: CISC vs. RISC 🏗️
Todo software é reduzido a um ISA (Instruction Set Architecture). Existem duas filosofias principais:
- CISC (Complex Instruction Set Computer): Focada em executar tarefas complexas com poucas linhas. Ex: Intel/AMD (x86).
- RISC (Reduced Instruction Set Computer): Usa instruções simples e ultra-rápidas. Ex: ARM (Apple M-series, Snapdragon).
Comparativo de Fluxo 📊
graph LR
A[Código Top-Level] --> B{Compilador}
B --> C[ISA CISC: Instruções Complexas]
B --> D[ISA RISC: Instruções Simples]
C --> E[Hardware Tradicional]
D --> F[Hardware Mobile/Eficiente]
2. Abstração e Camadas de Software 🧠
O Sistema Operacional (SO) serve como o tradutor entre seu código e o silício.
Conceito: Abstração de Hardware
A abstração permite que você escreva print("Hello") sem se preocupar se o processador usa x86 ou ARM. O SO e o compilador cuidam da tradução para os binários específicos.
| Sistema Operacional | Arquitetura Principal | Desafio do Desenvolvedor |
|---|---|---|
| Windows | x86_64 / ARM64 | Compatibilidade de drivers e emulação. |
| macOS / iOS | ARM64 (Apple Silicon) | Otimização para memória unificada. |
| Android | ARM64 | Lidar com a fragmentação de hardware. |
Dica de Performance
Sempre prefira binários nativos. Rodar um app x86 em um Mac ARM via Rosetta 2 funciona, mas consome mais bateria e CPU.
3. Na Prática: Compilação Cruzada 💻
Quando desenvolvemos mobile, estamos quase sempre fazendo Cross-Compilation: escrevemos no PC (x86) para rodar no celular (ARM).
4. Sistemas Embarcados e IoT 🔌
Aqui o software "toca" o metal de forma direta.
- Arduino: 8 bits, extremamente simples.
- ESP32: O rei da IoT com Wi-Fi/Bluetooth e dual-core RISC.
- Raspberry Pi: Um computador ARM completo rodando Linux.
Atenção: Limites de Memória
Em sistemas embarcados, você não tem GBs de RAM. Cada byte conta! O uso de linguagens como C ou Rust é essencial.
📝 Exercícios Progressivos
- Nível 1: Explique a principal diferença entre um processador que equipa um Desktop (Intel) e um que equipa um Smartphone (Snapdragon).
- Nível 2: Por que a Apple conseguiu aumentar drasticamente a duração da bateria ao mudar de Intel para Apple Silicon?
- Nível 3: Pesquise o que é o "Instruction Set" RISC-V e por que ele é considerado o futuro do hardware open-source.
🚀 Mini-Projeto: Dashboard de Arquitetura
Objetivo: Criar um script (Python ou Node) que detecte as especificações do sistema host.
- Tarefa 1: Identificar o nome do SO e a arquitetura da CPU (
x86_64ouarm64). - Tarefa 2: Listar a quantidade de núcleos físicos vs lógicos.
- Tarefa 3: Exibir uma recomendação de build (Nativo vs Emulado) com base nos dados.
Aula: O Caso de Estudo Apple 🍎
Evolução e Eficiência
Entender as transições da Apple é entender a história da eficiência computacional. A distinção entre emulação e simulação define o fluxo de trabalho de um desenvolvedor mobile.
1. A Jornada do Silício 🕒
A Apple passou por grandes transições de arquitetura, cada uma com um "tradutor" para manter a compatibilidade.
Linha do Tempo de Transições 📊
timeline
title Evolução Apple
1994 : PowerPC (RISC) : Foco em performance bruta
2006 : Intel (CISC) : Mobilidade e compatibilidade : Rosetta
2020 : Apple Silicon (ARM) : Eficiência extrema e UMA : Rosetta 2
Conceito: Arquitetura Unificada de Memória (UMA)
No Apple Silicon, a CPU, GPU e NPU compartilham o mesmo pool de memória de alta velocidade. Isso elimina a necessidade de copiar dados entre memórias diferentes, fazendo com que 8GB de RAM rendam muito mais que em sistemas tradicionais.
2. Ferramentas de Teste: Virtualização vs. Simulação 📱
Como testamos sem o hardware físico?
| Característica | Emulação (Android) | Simulação (iOS) |
|---|---|---|
| Definição | Imita o Hardware. | Imita o Software. |
| Arquitetura | Cria uma CPU virtual (QEMU). | Roda bibliotecas nativas no Mac host. |
| Performance | Mais lenta (pesada). | Ultra rápida (leve). |
| Fidelidade | Alta (testa limites de RAM). | Média (foco em UI/UX). |
Atenção: Diferença de Comportamento
Um app que roda perfeito no Simulador iOS pode falhar no aparelho real por questões de temperatura ou memória. Nunca publique sem testar no hardware físico!
3. Na Prática: Verificando Nativismo 💻
Como saber se um processo está rodando nativamente no seu Mac?
4. Desenvolver iOS no Windows? 🖥️
A resposta curta é: Sim, com ressalvas.
- Frameworks Multiplataforma: Flutter ou React Native permitem escrever o código no Windows.
- A "Tranca" da Apple: Para gerar o arquivo
.ipafinal e publicar, um macOS (físico ou cloud) ainda é obrigatório. - Expo: Uma ótima ferramenta para testar no iPhone físico sem precisar de Mac durante o desenvolvimento inicial.
Dica: MacinCloud
Se você não tem um Mac, serviços como MacinCloud permitem alugar um servidor macOS por hora para compilar seus projetos.
📝 Exercícios Progressivos
- Nível 1: O que foi a tecnologia Rosetta e por que ela foi vital para a Apple em 2006 e 2020?
- Nível 2: Explique por que o Simulador do Xcode é geralmente mais rápido que o Emulador do Android Studio.
- Nível 3: Pesquise sobre a Arquitetura Unificada de Memória (UMA) e cite uma vantagem técnica sobre o modelo tradicional de GPU dedicada.
🚀 Mini-Projeto: Dashboard de Compatibilidade
Objetivo: Criar um guia rápido (Tabela MD) para uma equipe que usa diferentes hardwares.
- Tarefa 1: Criar uma tabela listando 3 tecnologias populares (ex: Docker, VS Code, Android Studio).
- Tarefa 2: Indicar se rodam nativamente em
x86,ARM (Silicon)ou via emulação. - Tarefa 3: Adicionar uma coluna de "Impacto de Performance" (Baixo, Médio, Alto).
Aula: Virtualização e Baixo Nível ⚙️
O "Pulo do Gato" para Desenvolvedores Modernos
Aprenda como rodar código em qualquer lugar e como o software interage com a camada de "quase-hardware".
1. Virtualização e Abstração 🏗️
Nesta camada, isolamos o hardware para ganhar portabilidade e segurança.
Camadas de Abstração 📊
graph TD
A[Hardware Real] --> B[Hypervisor]
B --> C[Máquina Virtual 1]
B --> D[Máquina Virtual 2]
A --> E[Docker Engine]
E --> F[Container x86]
E --> G[Container ARM]
- Hypervisors: Proxmox, Hyper-V e VirtualBox.
- Containers Multi-Arquitetura: Uso de Docker Buildx para rodar o mesmo app em Intel e ARM.
2. Firmware e Boot: O Acordar do PC ⚡
- BIOS vs. UEFI: Como o computador entrega o controle ao SO.
- Bootloaders: O papel do U-Boot (Mobile/ARM) e do GRUB.
- Segurança: TPM e Secure Boot (essenciais para Windows 11 e apps bancários no Mobile).
Conceito: big.LITTLE
Processadores móveis misturam núcleos de Alta Performance (potência) com núcleos de Alta Eficiência (economia). O software deve ser inteligente para não acordar os núcleos potentes sem necessidade.
3. Na Prática: Docker Multi-Arch 💻
Criando imagens que rodam tanto no seu PC quanto no Raspberry Pi.
4. Real-Time Systems (RTOS) ⏱️
Crucial para sistemas críticos como drones ou freios ABS.
Atenção: Determinismo
Diferente do Windows, um RTOS (como FreeRTOS) garante que uma tarefa será executada em um tempo exato. No desenvolvimento mobile, usamos conceitos similares para garantir a fluidez da UI (60fps).
5. Comparativo de Ecossistemas 📊
| Tema | Desktop (High) | Mobile (Mid) | Embarcados (Low) |
|---|---|---|---|
| CPU | Intel i9 / Ryzen 9 | Snapdragon / Apple A | ESP32 / AVR |
| Arquitetura | CISC (x86_64) | RISC (ARM64) | RISC (Xtensa) |
| OS Principal | Windows / Linux | Android / iOS | RTOS / Bare Metal |
Dica: WebAssembly (Wasm)
O Wasm é o "binário universal" que permite rodar código C++/Rust no navegador com performance nativa, independente da CPU por baixo.
📝 Exercícios Progressivos
- Nível 1: Explique a diferença entre uma Máquina Virtual e um Container Docker em termos de uso de recursos do hardware.
- Nível 2: Por que desenvolvedores mobile devem se preocupar com o "Thermal Throttling" (redução de clock por calor)?
- Nível 3: O que é uma NPU (Neural Processing Unit) e como ela ajuda a economizar bateria em tarefas de IA local?
🚀 Mini-Projeto: Monitor de Recursos Bare-Metal
Objetivo: Pesquisar e documentar como acessar o "Uptime" do sistema sem bibliotecas de alto nível.
- Tarefa 1: No Linux, pesquisar o arquivo no
/procque guarda a temperatura da CPU. - Tarefa 2: Criar uma tabela comparando o consumo de RAM de um app "Hello World" em Java vs. Rust.
- Tarefa 3: Simular (teoricamente) o impacto de um loop infinito em um núcleo de "Alta Eficiência" de um ARM.
Aula: Mobile (Flutter e Kotlin) 📱
Ambiente de Desenvolvimento Pro
O desenvolvimento mobile exige ferramentas mais pesadas. Prepare sua máquina para criar apps profissionais.
1. Android Studio: O Motor Nativo 🛠️
Essencial para emular celulares Android e realizar debug de baixo nível.
Fluxo de Instalação 📊
graph LR
A[Download IDE] --> B[Install SDK]
B --> C[Configure AVD]
C --> D[Ready for Kotlin/Java]
- Baixe em developer.android.com/studio.
- Instale e deixe ele baixar o Android SDK.
Atenção: Aceleração de Hardware
Para rodar o emulador rápido, ative o Intel HAXM ou Hyper-V na sua BIOS. Sem isso, o emulador será extremamente lento.
2. Flutter SDK: Multiplataforma 🚀
Para criar apps iOS e Android com a mesma base de código.
- Extraia o SDK em
C:\src\flutter. - Adicione o
binao Path do Windows.
Verificando a Saúde do Ambiente 💻
3. Visual Studio Code 💻
O editor preferido por ser leve e ter extensões poderosas.
Dica: Extensões Obrigatórias
Instale as extensões Flutter e Dart. Elas trazem autocomplete, refactoring e hot reload automático.
📝 Exercícios Progressivos
- Nível 1: Qual a função do comando
flutter doctore por que ele é a primeira coisa a se rodar após instalar o SDK? - Nível 2: Por que precisamos do Android Studio mesmo se formos programar apenas em Flutter usando o VS Code?
- Nível 3: Explique a diferença entre um AVD (Android Virtual Device) e um dispositivo físico para testes.
🚀 Mini-Projeto: First Run
Objetivo: Criar e rodar o projeto padrão do Flutter.
- Tarefa 1: Criar o projeto via terminal:
flutter create meu_primeiro_app. - Tarefa 2: Abrir o projeto no VS Code e localizar o arquivo
main.dart. - Tarefa 3: Rodar o app no emulador e testar o Hot Reload mudando a cor do tema.
Aula: Ecossistemas Mobile Modernos 📱
Pontes entre Hardware e Software
Nesta aula, exploraremos como transformamos código em apps funcionais para Android (ARM) e iOS (Apple Silicon), navegando entre soluções nativas e multiplataforma.
1. O Espectro do Desenvolvimento 🏗️
O desenvolvedor moderno deve escolher entre Performance Máxima (Nativo) ou Agilidade de Escopo (Multiplataforma).
Mapeamento de Tecnologias 📊
graph TD
A[Desenvolvimento Mobile] --> B[Nativo]
A --> C[Multiplataforma]
B --> D[Android: Kotlin/Java]
B --> E[iOS: Swift]
C --> F[Híbrido: Ionic/Capacitor]
C --> G[Renderizado: RN/Flutter]
C --> H[Compilado: .NET MAUI]
- Nativo: Acesso total ao hardware com latência zero.
- Multiplataforma: Reuso de código (escreva uma vez, rode em dois).
2. Na Prática: O Poder da CLI 💻
Para criar um app moderno, o fluxo via terminal é o padrão de mercado.
3. Blocos de Conhecimento 🧠
Conceito: Compilação AOT vs JIT
No iOS, o código deve ser compilado AOT (Ahead-of-Time) por segurança. No Android, usamos JIT (Just-in-Time) para otimizar o app enquanto ele roda.
Atenção: Bridge vs Engine
O React Native usa uma "ponte" (bridge) para falar com o nativo, o que pode causar gargalos. O Flutter carrega sua própria "engine" de desenho (Skia/Impeller), sendo mais fluido na UI.
Dica: .NET MAUI
O MAUI é a evolução do Xamarin e permite criar apps para Android, iOS e Windows ARM usando C#. É ideal para ecossistemas corporativos.
📝 Exercícios Progressivos
- Nível 1: Explique por que um app feito em Ionic tende a consumir mais memória RAM do que um app em Swift nativo.
- Nível 2: Em qual camada do sistema operacional o .NET MAUI atua para acessar o GPS de diferentes plataformas simultaneamente?
- Nível 3: Desenhe (mentalmente ou em papel) o fluxo de dados de um botão clicado em um app React Native até ele ser processado pela CPU ARM.
🚀 Mini-Projeto: Dashboard de Arquitetura
Objetivo: Criar um protótipo que detecta a arquitetura do processador.
- Requisito 1: Usar Ionic + Capacitor para acessar a API de
Device Info. - Requisito 2: Exibir se o dispositivo é
arm64,x86_64ouunknown. - Requisito 3: Adicionar um botão que simula um processamento pesado para observar o comportamento térmico.
🎮 Aula: A Arte da Simulação - Emulação Android vs. Videogames
Entender a emulação é entender a tradução em tempo real. Se o Android fala "Português" (Instruções ARM) e seu PC fala "Inglês" (Instruções x86), precisamos de um tradutor muito rápido no meio do caminho.
1. O Tradutor de Instruções (ISA)
Imagine que você quer rodar um jogo de Super Nintendo (65816) no seu PC (x86). O emulador precisa ler cada instrução do jogo e converter para algo que o seu processador entenda. No Android é igual.
- Emulação por Software: O PC lê a instrução ARM, interpreta o que ela faz e executa uma função equivalente em x86. É lento (como o emulador de PS3 no PC).
- Virtualização (HAXM/KVM): Se o Android que você está emulando for versão x86, o PC não traduz, ele apenas "isola" uma fatia do processador. É muito rápido.
graph LR
subgraph "Hardware Real (Hospedeiro)"
A[CPU Intel/AMD x86_64]
end
subgraph "Camada de Emulação"
B{Tradutor Binário}
end
subgraph "Sistema Convidado (Guest)"
C[Android ARM64]
D[Apps e Jogos]
end
D --> C
C --> B
B -- "Tradução JIT" --> A
2. Por que o Emulador de Android é "Pesado"?
Diferente de um emulador de GameBoy, o Android é um sistema operacional completo (Kernel Linux, Interface Gráfica, Drivers).
- GPU Passthrough: O emulador precisa traduzir comandos OpenGL/Vulkan do Android para a sua placa de vídeo real.
- Aceleração de Hardware: Sem o Intel VT-x ou AMD-V ativado na BIOS, o emulador tenta traduzir tudo via software, resultando em 1 FPS.
3. Na Prática: Verificando Suporte e Iniciando
Antes de rodar um "console" Android no seu PC, precisamos garantir que os motores de tradução estão ativos.
🧠 Blocos de Conhecimento
💡 Conceito: Tradução Binária Dinâmica É o processo onde o emulador traduz blocos de código ARM para x86 "on-the-fly". É exatamente o que o Rosetta 2 faz nos Macs M1/M2, mas no sentido inverso (x86 para ARM).
⚠️ Atenção: Intel Atom vs. ARM Antigamente, existiam celulares com processador Intel Atom (x86). Neles, não havia emulação, o Android rodava nativo. Hoje, 99% dos celulares são ARM, exigindo tradução pesada nos emuladores.
📝 Exercícios Progressivos
- Analítico: Por que emular um PlayStation 1 (33MHz) é muito mais fácil do que emular um celular Android moderno de entrada?
- Arquitetura: Explique a diferença entre usar uma imagem de sistema
arm64-v8avsx86_64no Android Studio. Qual terá melhor performance no seu PC? - Hardware: Pesquise por que o recurso VT-x (Intel) ou SVM (AMD) precisa estar habilitado na BIOS para o emulador funcionar bem.
🚀 Mini-Projeto: "The Emulator Benchmarker"
Objetivo: Comparar a velocidade de execução de um algoritmo de cálculo entre o seu PC nativo e o Android emulado.
- Crie um script simples que calcula números primos até 100.000.
- Execute-o no seu terminal (PowerShell/Bash).
- Execute-o dentro do emulador Android (via
adb shell). - Relatório: Calcule o "Custo da Emulação" (Tempo Android / Tempo PC). Se o Android demorar 2x mais, seu custo de tradução é de 100%.
Sobre
Sobre o Curso
🎓 Desenvolvimento Mobile Nativo Profissional
Este curso foi projetado para transformar iniciantes em desenvolvedores capazes de criar, testar e publicar aplicativos de alto desempenho para o ecossistema Android, mantendo uma base sólida de conhecimento para transição futura para iOS.
🎯 Objetivos do Curso
-
Domínio Android --- Dominar Kotlin e Java, o Android Studio e os componentes principais do sistema (Activities, Services, Manifest).
-
Arquitetura de Mercado --- Utilizar o padrão MVVM, LiveData e ViewModel para criar códigos escaláveis e fáceis de manter.
-
Dados e Networking --- Conectar apps ao mundo real via Retrofit (APIs REST) e persistência local com Room Database.
-
Publicação e Carreira --- Entender o processo de assinatura de apps, geração de AAB e publicação na Google Play Store.
📚 O Que Você Vai Aprender
Módulo 1 – Fundamentos e UI
- História do Mobile e Mercado
- Kotlin vs Java vs Swift
- Interfaces com XML e ViewBinding
- ConstraintLayout e Unidades (dp/sp)
Módulo 2 – Navegação e Arquitetura
- Intents e Backstack
- Ciclo de Vida do Android
- Padrão MVVM (ViewModel + LiveData)
- Temas e Material Design 3
Módulo 3 – Listas e Persistência
- RecyclerView e Adapters eficientes
- Banco de Dados Room (SQLite)
- Consumo de APIs com Retrofit
- Gerenciamento de Threads (Coroutines)
Módulo 4 – Recursos Avançados
- Sensores, Câmera e GPS
- Testes Unitários e Testes de UI (Espresso)
- Debugging e Logcat
- Publicação na Store
🛠️ Metodologia
Foco 100% prático. Cada aula termina com um desafio real que compõe seu portfólio. Utilizamos diagramas interativos e quizzes para garantir a fixação do conteúdo técnico.
Pronto para o próximo nível? Começar Agora
Roadmap do Projeto: Curso Mobile Nativo 📱
Este documento rastreia a evolução do curso.
✅ Fase 1: Planejamento (Concluído)
- [x] Definição Syllabus (16 Aulas)
- [x] Estrutura Android first com paralelos iOS
- [x] Configuração MkDocs Material
✅ Fase 2: Conteúdo Base (Concluído)
- [x] Criação das 16 Aulas (Markdown)
- [x] Criação dos 16 Quizzes (HTML)
- [x] Criação dos 16 Conjuntos de Exercícios
- [x] Criação dos 16 Slides (RevealJS)
✅ Fase 3: Projetos e UX (Concluído)
- [x] Definição dos 16 Challenges/Projetos
- [x] Aplicação de Material Design 3 no conteúdo
- [x] Diagramação Mermaid de ciclo de vida e arquitetura
🚀 Fase 4: Lançamento e Manutenção
- [x] Deploy GitHub Pages
- [ ] Atualização para novas versões SDK (Android 14+)
- [ ] Inclusão de vídeos demonstrativos
Status Atual: Finalizado / Manutenção Última Atualização: 19/02/2026
Materiais
Bem-vindo à seção de materiais complementares do curso. Aqui você encontra recursos adicionais para apoiar seus estudos.
-
- Acesse os slides de todas as aulas para revisão.
-
- Pratique com listas de exercícios para cada módulo.
-
- Teste seus conhecimentos com quizzes interativos.
-
- Desenvolva projetos práticos para aplicar o que aprendeu.
-
- Guias de instalação e configuração do ambiente.
Versão para Impressão
Esta página foi gerada automaticamente para impressão.