O Android lança uma versão principal por ano, e cada uma muda comportamentos de que o seu app depende. Testar um app em diferentes versões do Android não é instalar o mesmo APK em seis celulares e conferir se ele abre. É saber quais mudanças chegam até você em qual versão, e por que o mesmo build pode se comportar de forma diferente em duas delas.
Este guia mapeia do Android 12 ao 17 para desenvolvedores de apps: o que muda, como testar cada mudança com adb e como experimentar comportamentos atrelados ao target antes de subir o targetSdkVersion.
Dois eixos, não um
Toda mudança de comportamento no Android pertence a um de dois grupos. As mudanças para todos os apps valem assim que o aparelho roda a versão nova, seja qual for o target do seu app. As mudanças atreladas ao target só valem quando o seu targetSdkVersion é pelo menos o nível de API daquela versão.
Isso dá dois eixos. A versão do aparelho decide o primeiro grupo, o seu target decide o segundo. A permissão de notificações do Android 13 mostra por que os dois importam. Um app com target na API 32 ou abaixo recebe o pedido do sistema assim que tem um canal de notificação e abre uma activity. Um app com target 33 precisa pedir a permissão ele mesmo, no momento que escolher. O mesmo código, dois fluxos de primeira execução diferentes.
Então a matriz são as versões que os seus usuários usam, vezes o seu target atual, mais uma coluna para o target para o qual você está prestes a migrar.
Do Android 12 ao 17 num relance
| Versão | Nível de API | Mudanças que mais quebram apps |
|---|---|---|
| 12 | 31 (12L é a 32) | android:exported explícito; flag de mutabilidade do PendingIntent; nada de iniciar serviço em primeiro plano a partir do segundo plano; localização aproximada; splash screen do sistema |
| 13 | 33 | permissão POST_NOTIFICATIONS; permissões de mídia granulares substituem a leitura do armazenamento; seletor de fotos; idioma por app |
| 14 | 34 | acesso parcial "Selecionar fotos"; tipos de serviço em primeiro plano obrigatórios; alarmes exatos desligados por padrão em instalações novas; flag de exportação para receivers registrados em tempo de execução; targets abaixo de 23 não instalam |
| 15 | 35 | edge-to-edge obrigatório; aparelhos com páginas de memória de 16 KB; targets abaixo de 24 não instalam; animações do voltar preditivo para apps que aderiram |
| 16 | 36 | a opção de sair do edge-to-edge é ignorada; voltar preditivo ligado por padrão, onBackPressed() deixa de ser chamado; limites de orientação e redimensionamento ignorados em telas grandes |
| 17 | 37 | o Google disse que a exceção temporária para telas grandes do 16 acaba na próxima versão; leia a lista completa de mudanças de comportamento antes de subir o target |
Notificações (Android 13)
A partir do 13, as notificações ficam desligadas até o usuário permitir. Teste três caminhos: permitir, negar e negar duas vezes, depois do que o sistema para de mostrar a janela e o seu app precisa levar o usuário às configurações. Depois teste no 12, em que não há pedido, para garantir que o onboarding não peça uma permissão que ali não existe.
Alterne a concessão entre as tentativas:
adb shell pm revoke com.example.app android.permission.POST_NOTIFICATIONS adb shell pm grant com.example.app android.permission.POST_NOTIFICATIONS adb shell dumpsys package com.example.app | grep POST_NOTIFICATIONS
Revogar não traz de volta a janela da primeira execução depois que o usuário negou duas vezes. Para ver o fluxo que um usuário novo vê, desinstale e instale de novo.
Fotos e mídia (Android 13 e 14)
Apps com target 33 não conseguem mais ler mídia com READ_EXTERNAL_STORAGE. Eles pedem READ_MEDIA_IMAGES, READ_MEDIA_VIDEO ou READ_MEDIA_AUDIO. O Android 14 acrescenta uma terceira resposta ao pedido de fotos e vídeos: o usuário pode compartilhar só os itens que selecionar. O app passa a ter READ_MEDIA_VISUAL_USER_SELECTED, vê só esses arquivos e deve oferecer um jeito de mudar a seleção, em vez de supor que tem a galeria inteira.
O caminho mais limpo é o seletor de fotos, que não precisa de permissão nenhuma. ActivityResultContracts.PickVisualMedia abre o seletor do sistema onde ele existe e recorre ao ACTION_OPEN_DOCUMENT onde ele não existe. No Android 11 e 12, o seletor chega pelas atualizações de sistema do Google Play, então um celular pode ter qualquer um dos dois caminhos. Registre isPhotoPickerAvailable() em cada celular e garanta que o fluxo funcione dos dois jeitos.
Abasteça a galeria antes de testar, porque um seletor vazio esconde bugs de layout:
adb push sample-photos/ /sdcard/Pictures/
Os arquivos enviados ao armazenamento compartilhado costumam aparecer no MediaStore em segundos. Se não aparecerem, abra o seletor de novo.
Trabalho em segundo plano (Android 12, 14 e 15)
Três mudanças fazem os bugs de segundo plano variar entre versões. A partir do 12, um app em segundo plano não pode mais iniciar um serviço em primeiro plano fora de uma lista curta de exceções; a chamada lança ForegroundServiceStartNotAllowedException. A partir do 14, um app com target 34 precisa declarar um foregroundServiceType para cada serviço em primeiro plano, mais a permissão correspondente, como FOREGROUND_SERVICE_DATA_SYNC, senão o início falha. A partir do 15, um serviço em primeiro plano dataSync num app com target 35 tem cerca de seis horas por dia, e depois um callback de timeout.
Os alarmes exatos também mudaram. SCHEDULE_EXACT_ALARM apareceu no 12, e no 14 deixou de ser concedido por padrão a apps recém-instalados com target 13 ou superior. Chame canScheduleExactAlarms() e trate o caso falso.
Force as condições em vez de esperar por elas. As três primeiras linhas colocam o celular em doze e o seu app num bucket de standby baixo; rode o cenário e depois restaure com as duas últimas:
adb shell dumpsys battery unplug adb shell dumpsys deviceidle force-idle adb shell am set-standby-bucket com.example.app rare adb shell dumpsys deviceidle unforce adb shell dumpsys battery reset
Edge-to-edge e navegação de voltar (Android 15 e 16)
Um app com target 35 desenha atrás da barra de status e da barra de navegação no Android 15, tenha pedido isso ou não. Insets ausentes colocam toolbars embaixo da barra de status, botões embaixo da barra de gestos e texto embaixo de um recorte da tela. O Android 15 ainda respeita um atributo para sair disso. No 16, os apps com target 36 perdem essa opção.
Teste cada tela nos dois modos de navegação, porque a navegação com três botões deixa uma barra mais alta para compensar. Em builds baseados no AOSP, dá para alternar pelo adb; nos outros, use Configurações, Sistema, Gestos:
adb shell cmd overlay enable-exclusive --category com.android.internal.systemui.navbar.threebutton adb shell cmd overlay enable-exclusive --category com.android.internal.systemui.navbar.gestural
O voltar preditivo seguiu um caminho parecido. No 13 e no 14, ele fica atrás de uma opção do desenvolvedor. No 15, as animações do sistema rodam para apps que aderiram com android:enableOnBackInvokedCallback. No 16, apps com target 36 recebem o recurso por padrão e onBackPressed() deixa de ser chamado. Pesquise o código antes de subir o target:
grep -rn "onBackPressed\|KEYCODE_BACK" app/src/main
Passe cada ocorrência para OnBackPressedCallback e depois teste o gesto de voltar a partir de cada tela, inclusive janelas e bottom sheets.
O Android 16 também muda as telas grandes. Em telas com menor largura de 600 dp ou mais, um app com target 36 perde o bloqueio de orientação e o resizeableActivity="false". O Android 16 oferece uma exceção temporária, e o Google disse que ela acaba na próxima versão, então conte com o fim dela quando o seu target for 37. Se o seu app trava em retrato, teste numa tela grande antes de subir o target.
Páginas de memória de 16 KB (Android 15)
O Android 15 trouxe suporte a aparelhos que usam páginas de memória de 16 KB em vez de 4 KB. Apps com código nativo precisam alinhar as bibliotecas para isso, e desde novembro de 2025 o Google Play exige suporte a 16 KB em apps novos e atualizações com target Android 15 ou superior. Confira o tamanho de página de um celular e o seu build:
adb shell getconf PAGE_SIZE zipalign -c -P 16 -v 4 app-release.apk llvm-objdump -p lib/arm64-v8a/libfoo.so | grep LOAD
Os segmentos LOAD devem mostrar align 2**14. O Android Gradle Plugin 8.5.1 e posteriores alinham as bibliotecas não comprimidas dentro do APK, e o NDK r28 e posteriores compilam alinhado a 16 KB por padrão, então as bibliotecas pré-compiladas de terceiros costumam ser as culpadas. Um celular que informa 4096 não diz nada sobre o comportamento com 16 KB; faça essa verificação numa imagem de sistema de emulador com 16 KB.
Experimente mudanças atreladas ao target antes de subir o targetSdk
Você não precisa subir o targetSdkVersion para ver a maioria dos comportamentos atrelados ao target. O framework de compatibilidade do Android permite ligar mudanças individuais num build depurável:
adb shell dumpsys platform_compat | grep -i edge adb shell am compat enable CHANGE_NAME com.example.app adb shell am compat reset CHANGE_NAME com.example.app
As mesmas chaves ficam nas Opções do desenvolvedor, em Mudanças na compatibilidade de apps. Ligue uma mudança por vez e faça o seu teste rápido. Quando a lista estiver limpa, suba o target num branch e rode a matriz completa.
Onde rodar a matriz
A maioria das equipes usa três tipos de aparelho. Imagens de sistema de emulador existem para todos os níveis de API e não custam nada, o que as torna certas para testes instrumentados e varreduras de API no CI. Celulares na nuvem dão cada versão em modelos reais de celular e mantêm o estado entre sessões: o Clousd roda Android 12 a 17 em mais de 150 modelos, e um celular volta a um estado limpo entre execuções. Celulares físicos continuam sendo a referência para câmera, sensores, gráficos e comportamento do fabricante.
A lista de modelos mostra quais modelos rodam na nuvem, e a página de testes de apps mostra como ligar a matriz ao CI. É novo em celulares remotos? Comece por testar um app Android online e veja o texto sobre emulador Android na nuvem para comparar imagens de emulador e modelos reais.
Um checklist para cada versão
- Instale o build atual na versão nova com o seu target atual: ele instala, abre e sobrevive à morte do processo.
- Leia a página de "mudanças de comportamento para todos os apps" e teste cada item que toca os seus recursos.
- Primeira execução sem nada concedido, depois cada permissão negada por vez.
- Notificações: momento do pedido, recusa e o link para as configurações.
- Mídia: seletor de fotos, acesso parcial, uma galeria vazia.
- Segundo plano: serviços em primeiro plano, alarmes exatos, doze e buckets de standby.
- Layout: insets nos dois modos de navegação, recortes da tela, escala de fonte 1.3, modo escuro.
- Voltar: gesto de voltar a partir de cada tela, janela e bottom sheet.
- Código nativo: alinhamento de 16 KB de cada biblioteca.
- Suba o target num branch, leia as "mudanças de comportamento para apps com target" no novo nível e repita.


