Al igual que las versiones anteriores, Android 15 incluye cambios de comportamiento que podrían afectar a tu app. Los siguientes cambios se aplican exclusivamente a las apps orientadas a Android 15 o versiones posteriores. Si tu app está orientada a Android 15 o versiones posteriores, debes modificarla para que admita estos comportamientos correctamente, cuando corresponda.
Asegúrate de revisar también la lista de cambios de comportamiento que afectan a todas las apps que se ejecutan en Android 15, independientemente de la targetSdkVersion
de tu app.
Funcionalidad principal
Android 15 modifica o expande varias capacidades principales del sistema Android.
Cambios en los servicios en primer plano
Realizaremos los siguientes cambios en los servicios en primer plano con Android 15.
- Nuevo tipo de servicio en primer plano de procesamiento de contenido multimedia
- Restricciones sobre los receptores de emisión de
BOOT_COMPLETED
que inician servicios en primer plano
Nuevo tipo de servicio en primer plano de procesamiento de contenido multimedia
Android 15 presenta un nuevo tipo de servicio en primer plano, mediaProcessing
. Este tipo de servicio es adecuado para operaciones como la transcodificación de archivos multimedia. Por ejemplo, una app de música podría descargar un archivo de audio y necesitar convertirlo a un formato diferente antes de reproducirlo. Puedes usar un servicio en primer plano mediaProcessing
para asegurarte de que la conversión continúe incluso mientras la app se encuentra en segundo plano.
Para obtener más información sobre el tipo de servicio mediaProcessing
, consulta Cambios en los tipos de servicio en primer plano para Android 15.
Restricciones en los receptores de emisión de BOOT_COMPLETED
que inician servicios en primer plano
Hay nuevas restricciones en los receptores de emisión de BOOT_COMPLETED
que inician servicios en primer plano. Los receptores BOOT_COMPLETED
no tienen permitido iniciar los siguientes tipos de servicios en primer plano:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(esta restricción se aplica amicrophone
desde Android 14)
Si un receptor BOOT_COMPLETED
intenta iniciar cualquiera de esos tipos de servicios en primer plano, el sistema arrojará ForegroundServiceStartNotAllowedException
.
Experiencia del usuario
Android 15 incluye algunos cambios destinados a crear una experiencia del usuario más intuitiva y coherente.
Cambios en la inserción de ventana
En Android 15, habrá dos cambios relacionados con las inserciones de ventana. En la versión Beta 1, se aplicará de borde a borde. También hay próximos cambios de configuración, incluida la configuración predeterminada de las barras del sistema.
Aplicación de borde a borde
Las apps serán de borde a borde de forma predeterminada en dispositivos que ejecutan Android 15 si están orientadas a esa versión.
Este es un cambio rotundo que podría afectar de forma negativa la IU de tu app. Los cambios son los siguientes:
- Barra de navegación del controlador de gestos
- Es transparente de forma predeterminada.
- El desplazamiento inferior está inhabilitado para que el contenido se dibuje detrás de la barra de navegación del sistema, a menos que se apliquen inserciones.
setNavigationBarColor
yR.attr#navigationBarColor
dejaron de estar disponibles y no afectan la navegación por gestos.setNavigationBarContrastEnforced
yR.attr#navigationBarContrastEnforced
continúan sin tener efecto en la navegación por gestos.
- Navegación con 3 botones
- La opacidad se establece en un 80% de forma predeterminada y es posible que el color coincida con el fondo de la ventana.
- El desplazamiento inferior está inhabilitado para que el contenido se dibuje detrás de la barra de navegación del sistema, a menos que se apliquen inserciones.
setNavigationBarColor
yR.attr#navigationBarColor
están configurados para que coincidan con el fondo de la ventana de forma predeterminada. El fondo de la ventana debe ser un elemento de diseño de color para que se aplique este valor predeterminado. Esta API dejó de estar disponible, pero continúa afectando la navegación de tres botones.setNavigationBarContrastEnforced
yR.attr#navigationBarContrastEnforced
son verdaderos de forma predeterminada, lo que agrega un 80% de fondo opaco en la navegación con tres botones.
- Barra de estado
- Es transparente de forma predeterminada.
- El desplazamiento superior está inhabilitado, por lo que el contenido se dibujará detrás de la barra de estado, a menos que se apliquen inserciones.
setStatusBarColor
yR.attr#statusBarColor
dejaron de estar disponibles y no tienen efecto en Android 15.setStatusBarContrastEnforced
yR.attr#statusBarContrastEnforced
dejaron de estar disponibles, pero aún tienen efecto en Android 15.
- Corte de pantalla
- El
layoutInDisplayCutoutMode
de las ventanas no flotantes debe serLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. De lo contrario, las apps fallarán con una IllegalArgumentException. SIEMPRE es la única opción permitida para que los usuarios no vean una barra negra causada por el corte de la pantalla en modo horizontal y, por lo tanto, aparezcan de borde a borde.
- El
En el siguiente ejemplo, se muestra una app antes y después de orientarla a Android 15, y antes y después de aplicar las inserciones.
Si tu app:
- ya es de de borde a borde y aplica inserciones, en la mayoría de los casos, no se verá afectado, excepto en las siguientes situaciones. Sin embargo, incluso si sientes que no te afecta, te recomendamos que pruebes la app.
- Tu app falla porque tienes una ventana no flotante, como una actividad que usa
SHORT_EDGES, NEVER
oDEFAULT
en lugar deLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. Si la app falla durante el inicio, puede deberse a la pantalla de presentación. Hasta que haya una solución disponible, configurawindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Es posible que haya pantallas con menos tráfico si la IU está oculta. Verifica que estas pantallas menos visitadas no tengan una IU oculta. Estas son algunas de las pantallas de menor tráfico:
- Pantallas de integración o acceso
- Páginas de configuración
- Tu app falla porque tienes una ventana no flotante, como una actividad que usa
- no es de borde a borde, lo más probable es que te afecte. Además de las situaciones de las apps que ya son de borde a borde, deberás tener en cuenta lo siguiente:
- Si tu app usa componentes de Material 3 (androidx.compose.material3 en Compose, como
TopAppBar, BottomAppBar
yNavigationBar
, es probable que estos componentes no se vean afectados porque controlan las inserciones automáticamente. - Si tu app usa componentes de Material 2 (androidx.compose.material en Compose, estos componentes no controlan las inserciones automáticamente. Sin embargo, puedes obtener acceso a las inserciones y aplicarlas manualmente. En androidx.compose.material 1.6.0 y posteriores, usa el parámetro windowInsets para aplicar las inserciones de forma manual para
BottomAppBar
,TopAppBar
,BottomNavigation
yNavigationRail
. Del mismo modo, usa el parámetrocontentWindowInsets
paraScaffold
. - Si tu app usa Views y componentes de Material (com.google.android.material, la mayoría de los componentes de Material basados en Views, como
BottomNavigationView
,BottomAppBar
,NavigationRailView
oNavigationView
), controlan las inserciones y no requieren trabajo adicional. Sin embargo, deberás agregarandroid:fitsSystemWindows="true"
si usasAppBarLayout
. - En el caso de los elementos componibles personalizados, aplica las inserciones de forma manual como padding. Si tu contenido está dentro de Scaffold, puedes consumir inserciones con valores de padding de Scaffold. De lo contrario, aplica padding mediante uno de los
WindowInsets
. - Si tu app usa Views, BottomSheet, SideSheet o contenedores personalizados, aplica padding con
ViewCompat.setOnApplyWindowInsetsListener
. Para RecyclerView, aplica padding con este objeto de escucha y también agregaclipToPadding="false"
.
- Si tu app usa componentes de Material 3 (androidx.compose.material3 en Compose, como
- debes ofrecer una protección de fondo personalizada para la navegación con tres botones o la barra de estado, tu app debe colocar un elemento componible o una vista detrás de la barra del sistema con
WindowInsets.Type#tappableElement()
para obtener la altura de la barra de navegación con tres botones oWindowInsets.Type#statusBars
.
Consulta las guías de Edge to Edge Views y las guías de Edge to Edge Compose para obtener consideraciones adicionales sobre la aplicación de inserciones.
Esta es la lista de APIs inhabilitadas y obsoletas:
- R.attr#estadoBarColor
- R.attr#navegaciónBarColor
- R.attr#navegaciónBarDividerColor
- Ventana#setDecorFitsSystemWindows
- Ventana#setStatusBarColor
- Ventana#setStatusBarContrastEnforced
- Ventana#setNavigationBarColor
- Ventana#setNavigationBarDividerColor
- Ventana#getStatusBarColor
- Ventana#getStatusBarContrastEnforced
- Ventana#getNavigationBarColor
- Ventana#getNavigationBarDividerColor
Configuración estable
Este cambio no está disponible para probar en la versión beta 1, pero pronto lo estará.
Si tu app se orienta a Android 15 o versiones posteriores, Configuration
ya no excluye las barras del sistema. Si usas el tamaño de pantalla en la clase Configuration
para el cálculo del diseño, debes reemplazarlo por alternativas mejores, como un ViewGroup
, WindowInsets
o WindowMetricsCalculator
apropiados según tus necesidades.
Configuration
está disponible desde la API 1. Por lo general, se obtiene de Activity.onConfigurationChanged
. Proporciona información como la densidad, la orientación y los tamaños de las ventanas. Una característica importante sobre los tamaños de ventana que muestra Configuration
es que antes excluía las barras del sistema.
El tamaño de la configuración se suele usar para la selección de recursos, como /res/layout-h500dp
, y este sigue siendo un caso de uso válido. Sin embargo, siempre no se recomienda su uso para el cálculo del diseño. Si lo haces, debes dejar de hacerlo ahora. Debes reemplazar el uso de Configuration
por algo más adecuado según tu caso de uso.
Si la usas para calcular el diseño, utiliza un ViewGroup
apropiado, como CoordinatorLayout
o ConstraintLayout
. Si la usas para determinar la altura de la barra de navegación del sistema, utiliza WindowInsets
. Si deseas conocer el tamaño actual de la ventana de tu app, usa computeCurrentWindowMetrics
.
En la siguiente lista, se describen los campos afectados por este cambio:
- Los tamaños
Configuration.screenWidthDp
yscreenHeightDp
ya no excluyen las barras del sistema. Configuration.smallestScreenWidthDp
se ve afectado indirectamente por los cambios enscreenWidthDp
yscreenHeightDp
.Configuration.orientation
se ve afectada indirectamente por los cambios enscreenWidthDp
yscreenHeightDp
en dispositivos casi cuadrados.Display.getSize(Point)
se ve afectado de forma indirecta por los cambios en la Configuración. Esta función dejó de estar disponible a partir del nivel de API 30.Display.getMetrics()
ya funciona de esta manera desde el nivel de API 33.
El atributo eleganteTextHeight se establece en verdadero de forma predeterminada.
En el caso de las apps orientadas a Android 15, el atributo TextView
elegantTextHeight
se convierte en true
de forma predeterminada, lo que reemplaza la fuente compacta de forma predeterminada con algunas secuencias de comandos que tienen métricas verticales grandes por una mucho más legible. La fuente compacta se introdujo para evitar diseños rotos. Android 13 (nivel de API 33) evita muchas de estas fallas permitiendo que el diseño de texto estire la altura vertical con el atributo fallbackLineSpacing
.
En Android 15, la fuente compacta aún permanece en el sistema, por lo que tu app puede establecer elegantTextHeight
en false
para obtener el mismo comportamiento que antes, pero es poco probable que se admita en próximas versiones. Por lo tanto, si tu app admite las siguientes secuencias de comandos: árabe, laosiano, Birmania, tamil, guyaratí, canarés, malabar, oriya, telugu o tailandés, configura elegantTextHeight
en true
para probar la app.
Cámara y contenido multimedia
En Android 15, se realizan los siguientes cambios en el comportamiento de la cámara y el contenido multimedia para las apps orientadas a Android 15 o versiones posteriores.
Restricciones para solicitar foco de audio
Las apps orientadas a Android 15 deben ser la app principal o ejecutar un servicio en primer plano relacionado con el audio para solicitar el foco de audio. Si una app intenta solicitar el foco cuando no cumple con uno de estos requisitos, la llamada mostrará AUDIOFOCUS_REQUEST_FAILED
.
Un servicio en primer plano se considera relacionado con el audio si su tipo es mediaPlayback
, camera
, microphone
o phoneCall
.
Puedes obtener más información sobre el foco de audio en Cómo administrar el foco de audio.
Actualización de restricciones que no pertenecen al SDK
Android 15 incluye listas actualizadas de este tipo de interfaces que están basadas en la colaboración con desarrolladores de Android y las pruebas internas más recientes. Siempre que sea posible, nos aseguramos de que las alternativas públicas estén disponibles antes de restringir las interfaces que no pertenecen al SDK.
Si tu app no está orientada a Android 15, es posible que algunos de estos cambios no te afecten de inmediato. Sin embargo, aunque es posible que tu app acceda a algunas interfaces que no pertenecen al SDK según el nivel de API al que está orientada tu app, usar cualquier método o campo que no pertenece al SDK siempre implica un gran riesgo de error para tu app.
Si no sabes con certeza si tu app usa este tipo de interfaces, puedes probarla para averiguarlo. Si tu app depende de interfaces que no pertenecen al SDK, debes comenzar a planificar una migración hacia otras alternativas SDK. Sin embargo, sabemos que algunas apps tienen casos de uso válidos para usar interfaces que no pertenecen al SDK. Si no encuentras una alternativa para reemplazar el uso de una interfaz que no pertenece al SDK para una función de tu app, deberías solicitar una nueva API pública.
Para obtener más información sobre los cambios implementados en esta versión de Android, consulta Actualizaciones a las restricciones de interfaces que no pertenecen al SDK en Android 15. Para obtener más información sobre interfaces que no pertenecen al SDK en general, consulta Restricciones en interfaces que no pertenecen al SDK.