Android publica una versión principal cada año, y cada una cambia comportamientos de los que depende tu app. Probar una app en diferentes versiones de Android no consiste en instalar el mismo APK en seis teléfonos y comprobar que se abre. Consiste en saber qué cambios te afectan en qué versión y por qué la misma build puede comportarse distinto en dos de ellas.
Esta guía recorre Android 12 a 17 para desarrolladores de apps: qué cambia, cómo probar cada cambio con adb y cómo probar el comportamiento ligado al target antes de subir el targetSdkVersion.
Dos ejes, no uno
Todo cambio de comportamiento de Android pertenece a uno de dos grupos. Los cambios para todas las apps se aplican en cuanto el dispositivo corre la nueva versión, sea cual sea el target de tu app. Los cambios ligados al target solo se aplican cuando tu targetSdkVersion es como mínimo el nivel de API de esa versión.
Eso te da dos ejes. La versión del dispositivo decide el primer grupo, tu target decide el segundo. El permiso de notificaciones de Android 13 muestra por qué importan los dos. Una app con target 32 o inferior recibe el aviso del sistema en cuanto tiene un canal de notificaciones y abre una actividad. Una app con target 33 tiene que pedir el permiso ella misma, en el momento que elija. El mismo código, dos flujos de primer uso distintos.
Así que la matriz son las versiones que usan tus usuarios multiplicadas por tu target actual, más una columna para el target al que estás por pasar.
Android 12 a 17 de un vistazo
| Versión | Nivel de API | Cambios que más a menudo rompen apps |
|---|---|---|
| 12 | 31 (12L es 32) | android:exported explícito; indicador de mutabilidad de PendingIntent; no se pueden iniciar servicios en primer plano desde el segundo plano; ubicación aproximada; pantalla de inicio del sistema |
| 13 | 33 | permiso POST_NOTIFICATIONS; permisos de multimedia granulares en lugar de la lectura de almacenamiento; selector de fotos; idioma por app |
| 14 | 34 | acceso parcial “Seleccionar fotos”; tipos de servicio en primer plano obligatorios; alarmas exactas desactivadas por defecto en instalaciones nuevas; indicador de exportación para receptores registrados en tiempo de ejecución; no se instalan targets por debajo de 23 |
| 15 | 35 | edge-to-edge obligatorio; dispositivos con páginas de memoria de 16 KB; no se instalan targets por debajo de 24; animaciones de atrás predictivo para las apps que lo activan |
| 16 | 36 | se ignora la exclusión de edge-to-edge; atrás predictivo activado por defecto, ya no se llama a onBackPressed(); en pantallas grandes se ignoran los límites de orientación y de redimensionamiento |
| 17 | 37 | Google dijo que la exclusión temporal para pantallas grandes de 16 termina con la siguiente versión; lee la lista completa de cambios de comportamiento antes de subir el target |
Notificaciones (Android 13)
En 13 y posteriores, las notificaciones están desactivadas hasta que el usuario las permite. Prueba tres caminos: permitir, denegar y denegar dos veces, tras lo cual el sistema deja de mostrar el diálogo y tu app tiene que enviar al usuario a los ajustes. Después prueba en 12, donde no hay aviso, para que el onboarding no pida un permiso que ahí no existe.
Cambia el permiso entre intentos:
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
Revocar el permiso no hace que vuelva el diálogo del primer uso si el usuario ya lo denegó dos veces. Para ver el flujo que ve un usuario nuevo, desinstala y vuelve a instalar.
Fotos y multimedia (Android 13 y 14)
Las apps con target 33 ya no pueden leer multimedia con READ_EXTERNAL_STORAGE. En su lugar piden READ_MEDIA_IMAGES, READ_MEDIA_VIDEO o READ_MEDIA_AUDIO. Android 14 agrega una tercera respuesta al aviso de fotos y videos: el usuario puede compartir solo los elementos que selecciona. La app recibe entonces READ_MEDIA_VISUAL_USER_SELECTED, ve solo esos archivos y debería ofrecer una forma de cambiar la selección en lugar de dar por hecho que tiene toda la galería.
El camino más limpio es el selector de fotos, que no necesita ningún permiso. ActivityResultContracts.PickVisualMedia abre el selector del sistema donde existe y recurre a ACTION_OPEN_DOCUMENT donde no. En Android 11 y 12 el selector llega con las actualizaciones del sistema de Google Play, así que un teléfono concreto puede tener cualquiera de los dos caminos. Registra isPhotoPickerAvailable() en cada teléfono y asegúrate de que el flujo funcione de las dos maneras.
Llena la galería antes de probar, porque un selector vacío oculta errores de diseño:
adb push sample-photos/ /sdcard/Pictures/
Los archivos que se envían al almacenamiento compartido suelen aparecer en MediaStore en segundos. Si no aparecen, vuelve a abrir el selector.
Trabajo en segundo plano (Android 12, 14 y 15)
Tres cambios mueven los bugs de segundo plano entre versiones. Desde 12, una app en segundo plano ya no puede iniciar un servicio en primer plano fuera de una lista corta de excepciones; la llamada lanza ForegroundServiceStartNotAllowedException. Desde 14, una app con target 34 tiene que declarar un foregroundServiceType para cada servicio en primer plano, más el permiso correspondiente, como FOREGROUND_SERVICE_DATA_SYNC, o el inicio falla. Desde 15, un servicio en primer plano dataSync en una app con target 35 tiene unas seis horas al día y después recibe una llamada de tiempo agotado.
Las alarmas exactas también cambiaron. SCHEDULE_EXACT_ALARM apareció en 12, y en 14 ya no se concede por defecto a las apps recién instaladas con target 13 o posterior. Llama a canScheduleExactAlarms() y maneja el caso false.
Fuerza las condiciones en lugar de esperarlas. Las tres primeras líneas ponen el teléfono en doze y tu app en un bucket de standby bajo; ejecuta el escenario y luego restablece con las dos ú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 y navegación hacia atrás (Android 15 y 16)
Una app con target 35 dibuja detrás de las barras de estado y de navegación en Android 15, lo haya pedido o no. Si faltan los insets, las barras de herramientas quedan bajo la barra de estado, los botones bajo la barra de gestos y el texto bajo un recorte de pantalla. Android 15 todavía respeta un atributo de exclusión. En 16, las apps con target 36 lo pierden.
Prueba cada pantalla con los dos modos de navegación, porque la navegación con tres botones deja una barra más alta que hay que compensar. En las compilaciones basadas en AOSP puedes cambiarlo desde adb; en las demás, usa Ajustes, 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
El atrás predictivo siguió un camino parecido. En 13 y 14 está detrás de una opción para desarrolladores. En 15 las animaciones del sistema se ejecutan para las apps que lo activaron con android:enableOnBackInvokedCallback. En 16, las apps con target 36 lo tienen por defecto y ya no se llama a onBackPressed(). Busca en el código antes de subir el target:
grep -rn "onBackPressed\|KEYCODE_BACK" app/src/main
Pasa cada coincidencia a OnBackPressedCallback y luego prueba el gesto atrás desde cada pantalla, incluidos los diálogos y las hojas inferiores.
Android 16 también cambia las pantallas grandes. En pantallas con un ancho mínimo de 600 dp o más, una app con target 36 pierde su bloqueo de orientación y resizeableActivity="false". Android 16 ofrece una exclusión temporal, y Google dijo que termina con la siguiente versión, así que cuenta con que desaparezca cuando apuntes a 37. Si tu app bloquea la orientación vertical, pruébala en una pantalla grande antes de subir el target.
Páginas de memoria de 16 KB (Android 15)
Android 15 agregó soporte para dispositivos que usan páginas de memoria de 16 KB en lugar de 4 KB. Las apps con código nativo tienen que alinear sus bibliotecas para eso, y desde noviembre de 2025 Google Play exige soporte de 16 KB a las apps nuevas y a las actualizaciones con target Android 15 o posterior. Revisa el tamaño de página de un teléfono y tu 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
Los segmentos LOAD deberían mostrar align 2**14. Android Gradle Plugin 8.5.1 y posteriores alinean las bibliotecas sin comprimir dentro del APK, y NDK r28 y posteriores compilan alineado a 16 KB por defecto, así que las bibliotecas precompiladas de terceros suelen ser las culpables. Un teléfono que reporta 4096 no te dice nada del comportamiento con 16 KB; haz esa prueba en una imagen del sistema de emulador de 16 KB.
Prueba los cambios ligados al target antes de subir el targetSdk
No hace falta subir el targetSdkVersion para ver la mayor parte del comportamiento ligado al target. El framework de compatibilidad de Android te permite activar cambios individuales en una build depurable:
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
Los mismos interruptores están en Opciones para desarrolladores, en Cambios de compatibilidad de la app. Activa un cambio a la vez y haz tu prueba de humo. Cuando la lista esté limpia, sube el target en una rama y corre la matriz completa.
Dónde correr la matriz
La mayoría de los equipos usa tres tipos de dispositivo. Hay imágenes del sistema de emulador para cada nivel de API y no cuestan nada, lo que las hace adecuadas para las pruebas de instrumentación y los barridos de API en el CI. Los teléfonos en la nube te dan cada versión en modelos de teléfono reales y conservan el estado entre sesiones: Clousd ejecuta Android 12 a 17 en más de 150 modelos, y un teléfono se puede restablecer a un estado limpio entre ejecuciones. Los teléfonos físicos siguen siendo la referencia para la cámara, los sensores, los gráficos y el comportamiento de cada fabricante.
La lista de modelos muestra qué modelos funcionan en la nube, y la página de pruebas de apps muestra cómo conectar la matriz al CI. ¿Es tu primera vez con teléfonos remotos? Empieza por probar una app Android online, y lee el artículo sobre el emulador de Android en la nube para comparar las imágenes de emulador con los modelos reales.
Una lista de control para cada lanzamiento
- Instala la build actual en la versión nueva con tu target actual: se instala, arranca y sobrevive a la muerte del proceso.
- Lee la página de “cambios de comportamiento para todas las apps” y prueba cada punto que toque tus funciones.
- Primer uso sin nada concedido, y luego cada permiso denegado por turno.
- Notificaciones: momento del aviso, denegación y enlace a los ajustes.
- Multimedia: selector de fotos, acceso parcial, galería vacía.
- Segundo plano: servicios en primer plano, alarmas exactas, doze y buckets de standby.
- Diseño: insets con los dos modos de navegación, recortes de pantalla, escala de fuente 1.3, modo oscuro.
- Atrás: gesto atrás desde cada pantalla, diálogo y hoja inferior.
- Código nativo: alineación a 16 KB de cada biblioteca.
- Sube el target en una rama, lee los “cambios de comportamiento para apps con target” del nuevo nivel y repite.


