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
我们将对 Android 15 中的前台服务做出以下更改。
新增媒体处理前台服务类型
Android 15 引入了一种新的前台服务类型 mediaProcessing
。此服务类型适用于对媒体文件进行转码等操作。例如,媒体应用可能下载音频文件,并且需要将其转换为其他格式才能播放。您可以使用 mediaProcessing
前台服务来确保即使应用在后台运行,转换也会继续进行。
如需详细了解 mediaProcessing
服务类型,请参阅 Android 15 前台服务类型变更。
对启动前台服务的 BOOT_COMPLETED
广播接收器的限制
针对启动前台服务的 BOOT_COMPLETED
广播接收器存在新的限制。BOOT_COMPLETED
接收器不能启动以下类型的前台服务:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(从 Android 14 开始,系统针对microphone
实施了此限制)
如果 BOOT_COMPLETED
接收器尝试启动任何此类前台服务,系统会抛出 ForegroundServiceStartNotAllowedException
。
Cambios en la capacidad de las apps para modificar el estado global del modo No interrumpir
Apps that target Android 15 can no longer change the global state or policy of
Do Not Disturb (DND) on a device (either by modifying user settings, or turning
off DND mode). Instead, apps must contribute an AutomaticZenRule
, which
the system combines into a global policy with the existing
most-restrictive-policy-wins scheme. Calls to existing APIs that previously
affected global state (setInterruptionFilter
,
setNotificationPolicy
) result in the creation or update of an
implicit AutomaticZenRule
, which is toggled on and off depending on the
call-cycle of those API calls.
Note that this change only affects observable behavior if the app is calling
setInterruptionFilter(INTERRUPTION_FILTER_ALL)
and expects that call to
deactivate an AutomaticZenRule
that was previously activated by their owners.
Cambios en OpenJDK 17
Android 15 会继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。
对于以 Android 15 为目标平台的应用,以下变更可能会影响应用兼容性:
字符串格式设置 API 的变化:在使用以下
String.format()
和Formatter.format()
API 时,现在对参数索引、标志、宽度和精度的验证更为严格:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
例如,使用参数索引 0 时(格式字符串中的
%0
)会抛出以下异常:IllegalFormatArgumentIndexException: Illegal format argument index = 0
在这种情况下,可以通过在格式字符串中使用
%1
的参数索引 1 来解决此问题。语言代码处理方面的变更:使用
Locale
API 时,希伯来语、意第绪语和印度尼西亚语的语言代码不再转换为过时的形式(希伯来语:iw
、意第绪语:ji
和印度尼西亚语:in
)。在为其中一个语言区域指定语言代码时,请改用 ISO 639-1 中的代码:yi
、Yid1(希伯来语):yi
。he
id
随机 int 序列变更:在 https://bugs.openjdk.org/browse/JDK-8301574 中做出更改后,以下
Random.ints()
方法现在返回的数字序列现在与Random.nextInt()
方法不同:通常,此变更不会导致应用破坏行为,但您的代码不应期望从
Random.ints()
方法生成的序列与Random.nextInt()
匹配。
Seguridad
Android 15 incluye cambios que promueven la seguridad del sistema para proteger a los usuarios y las apps de apps maliciosas.
Lanzamientos seguros de actividades en segundo plano
Android 15 protege a los usuarios de apps maliciosas y les brinda más control sobre sus dispositivos, ya que agregan cambios que evitan que las apps maliciosas en segundo plano lleven otras apps al primer plano, elevan sus privilegios y abusen de la interacción con los usuarios. Los inicios de actividades en segundo plano están restringidos desde Android 10 (nivel de API 29).
Bloquear el inicio de actividades en las apps que no coincidan con el UID superior de la pila
Las apps maliciosas pueden iniciar la actividad de otra app dentro de la misma tarea y, luego, superponerse sobre ellas, lo que crea la ilusión de ser esa app. Este ataque de “secuestro de tareas” omite las restricciones actuales de inicio en segundo plano porque todo ocurre dentro de la misma tarea visible. Para mitigar este riesgo, en Android 15, se agrega una marca que bloquea las apps que no coinciden con el UID superior de la pila para que no inicien actividades. Para habilitar todas las actividades de tu app, actualiza el atributo allowCrossUidActivitySwitchFromBelow
en el archivo AndroidManifest.xml
de la app:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
Otros cambios
Además de la restricción para la coincidencia de UID, también se incluyen estos otros cambios:
- Cambia los creadores de
PendingIntent
para que bloqueen inicios de actividades en segundo plano de forma predeterminada. Esto ayuda a evitar que las apps creen accidentalmente unPendingIntent
que podría ser abusado por actores maliciosos. - No coloques una app en primer plano, a menos que lo permita el remitente del
PendingIntent
. El objetivo de este cambio es evitar que apps maliciosas abusen de la capacidad de iniciar actividades en segundo plano. De forma predeterminada, las apps no pueden llevar la pila de tareas al primer plano, a menos que el creador permita privilegios de inicio de la actividad en segundo plano o que el remitente tenga privilegios de inicio de actividad en segundo plano. - Controla cómo la actividad superior de una pila de tareas puede completar su tarea. Si la actividad principal finaliza una tarea, Android regresará a la tarea que estuvo activa por última vez. Además, si una actividad que no es principal finaliza su tarea, Android regresará a la pantalla principal y no bloqueará el final de esa actividad no principal.
- Evita iniciar actividades arbitrarias de otras apps en tu propia tarea. Este cambio evita que las apps maliciosas suplanten a los usuarios mediante la creación de actividades que parecen provenir de otras apps.
- Bloquea las ventanas no visibles a fin de que no se consideren para el inicio de actividades en segundo plano. Esto ayuda a evitar que las apps maliciosas abusen de los inicios de actividades en segundo plano para mostrar contenido malicioso o no deseado a los usuarios.
Intents más seguros
Android 15 introduces new security measures to make intents safer and more robust. These changes are aimed at preventing potential vulnerabilities and misuse of intents that can be exploited by malicious apps. There are two main improvements to the security of intents in Android 15:
- Match target intent-filters: Intents that target specific components must accurately match the target's intent-filter specifications. If you send an intent to launch another app's activity, the target intent component needs to align with the receiving activity's declared intent-filters.
- Intents must have actions: Intents without an action will no longer match any intent-filters. This means that intents used to start activities or services must have a clearly defined action.
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
IU del sistema y 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.
全面强制执行
Apps will be edge-to-edge by default on devices running Android 15 if the app is targeting Android 15.
This is a breaking change that might negatively impact your app's UI. The changes are as follows:
- Gesture handle navigation bar
- Transparent by default.
- Bottom offset is disabled so content draws behind the system navigation bar unless insets are applied.
setNavigationBarColor
andR.attr#navigationBarColor
is deprecated and does not affect gesture navigation.setNavigationBarContrastEnforced
andR.attr#navigationBarContrastEnforced
continues to have no effect on gesture navigation.
- 3 button navigation
- Opacity set to 80% by default, with color possibly matching the window background.
- Bottom offset disabled so content draws behind the system navigation bar unless insets are applied.
setNavigationBarColor
andR.attr#navigationBarColor
is set to match the window background by default. The window background must be a color drawable for this default to apply. This API is deprecated but continues to affect three button navigation.setNavigationBarContrastEnforced
andR.attr#navigationBarContrastEnforced
is true by default, which adds an 80% opaque background across three button navigation.
- Status bar
- Transparent by default.
- The top offset is disabled so content will draw behind the status bar unless insets are applied.
setStatusBarColor
andR.attr#statusBarColor
are deprecated and have no effect on Android 15.setStatusBarContrastEnforced
andR.attr#statusBarContrastEnforced
are deprecated but still have an effect on Android 15.
- Display cutout
layoutInDisplayCutoutMode
of non-floating windows must beLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. In Android 15 Beta 1, apps will crash with an IllegalArgumentException if usingSHORT_EDGES
,NEVER
, orDEFAULT
(e.g.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
). In Android 15 Beta 2,SHORT_EDGES
,NEVER
andDEFAULT
will be interpreted asALWAYS
so that users don't see a Black bar caused by the display cutout and appear edge-to-edge.
The following example shows an app before and after targeting Android 15, and before and after applying insets.
If your app:
- is already edge-to-edge and applies insets, you are mostly
unimpacted, except in the following scenarios. However, even if you feel you
aren't impacted, we recommend you test your app.
- You have a non-floating window, such as an Activity that uses
SHORT_EDGES, NEVER
orDEFAULT
instead ofLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. If your app crashes on launch, this may be due to your splashscreen. You can either upgrade the core splashscreen dependency to 1.2.0-alpha01 or later, setwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
, or test with Android 15 Beta 2 instead of Beta 1. - There may be lower traffic screens with occluded UI. Verify these less
visited screens don't have occluded UI. Lower traffic screens include:
- Onboarding or sign-in screens
- Settings pages
- You have a non-floating window, such as an Activity that uses
- is not edge-to-edge, you are most likely impacted. In addition to the
scenarios for apps that are already edge-to-edge, you will need to consider
the following:
- If your app uses Material 3 Components (androidx.compose.material3 in
compose, such as
TopAppBar, BottomAppBar
, andNavigationBar
, these components are likely not impacted because they automatically handle insets. - If your app is using Material 2 Components
(androidx.compose.material in Compose, these components don't
automatically handle insets. However, you can get access to the insets and
apply them manually. In androidx.compose.material 1.6.0 and
later use the windowInsets parameter to apply the insets manually for
BottomAppBar
,TopAppBar
,BottomNavigation
, andNavigationRail
. Likewise, use thecontentWindowInsets
parameter forScaffold
. - If your app uses Views and Material Components
(com.google.android.material, most Views based Material Components
such as
BottomNavigationView
,BottomAppBar
,NavigationRailView
, orNavigationView
, handle insets and require no additional work. However, you will need to addandroid:fitsSystemWindows="true"
if usingAppBarLayout
. - For custom Composables, apply the insets manually as padding. If your
content is within a Scaffold, you may consume insets using Scaffold's
padding values. Otherwise, apply padding using one of the
WindowInsets
. - If your app is using Views and BottomSheet, SideSheet or custom containers,
apply padding using
ViewCompat.setOnApplyWindowInsetsListener
. For RecyclerView, apply padding using this listener and also addclipToPadding="false"
.
- If your app uses Material 3 Components (androidx.compose.material3 in
compose, such as
- must offer custom background protection to three button navigation or the
status bar, you app should place a composable or view behind the system bar
using
WindowInsets.Type#tappableElement()
to get the three button navigation bar height orWindowInsets.Type#statusBars
.
See the Edge to Edge Views and Edge to Edge Compose guides for additional considerations on applying insets.
The list of deprecated and disabled APIs are:
- R.attr#statusBarColor
- R.attr#navigationBarColor
- R.attr#navigationBarDividerColor
- Window#setDecorFitsSystemWindows
- Window#setStatusBarColor
- Window#setStatusBarContrastEnforced
- Window#setNavigationBarColor
- Window#setNavigationBarDividerColor
- Window#getStatusBarColor
- Window#getStatusBarContrastEnforced
- Window#getNavigationBarColor
- Window#getNavigationBarDividerColor
稳定配置
If your app targets Android 15 or higher, Configuration
no
longer excludes the system bars. If you use the screen size in the
Configuration
class for layout calculation, you should replace it with better
alternatives like an appropriate ViewGroup
, WindowInsets
or
WindowMetricsCalculator
depending on your need.
Configuration
has been available since API 1. It is typically obtained from
Activity.onConfigurationChanged
. It provides information like window density,
orientation, and sizes. One important characteristic about the window sizes
returned from Configuration
is that it previously excluded the system bars.
The configuration size is typically used for resource selection, such as
/res/layout-h500dp
, and this is still a valid use case. However, using it for
layout calculation has always been discouraged. If you do so, you should move
away from it now. You should replace the use of Configuration
with something
more suitable depending on your use case.
If you use it to calculate the layout, use an appropriate ViewGroup
such as
CoordinatorLayout
or ConstraintLayout
. If you use it to determine the height
of the system navbar, use WindowInsets
. If you want to know the current size
of your app window, use computeCurrentWindowMetrics
.
The following list describes the fields affected by this change:
Configuration.screenWidthDp
andscreenHeightDp
sizes no longer exclude the system bars.Configuration.smallestScreenWidthDp
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
.Configuration.orientation
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
on close-to-square devices.Display.getSize(Point)
is indirectly affected by the changes in Configuration. This has been deprecated beginning in API level 30.Display.getMetrics()
has already worked like this since API level 33.
El atributo eleganteTextHeight se establece en verdadero de forma predeterminada.
对于以 Android 15 为目标平台的应用,elegantTextHeight
TextView
属性默认变为 true
,将默认使用的紧凑字体替换为一些具有较大垂直指标的脚本,并且这种字体更易于阅读。紧凑字体的引入是为了防止破坏布局;Android 13(API 级别 33)允许文本布局利用 fallbackLineSpacing
属性拉伸垂直高度,以防止许多此类破坏。
在 Android 15 中,紧凑字体仍保留在系统中,因此您的应用可以将 elegantTextHeight
设置为 false
,以获得与之前相同的行为,但即将在未来版本中提供支持。因此,如果您的应用支持以下文字:阿拉伯语、老挝语、缅甸、泰米尔语、古吉拉特语、卡纳达语、马拉雅拉姆语、奥里亚语、泰卢固语或泰语,请将 elegantTextHeight
设置为 true
,以测试应用。
Cambios en el ancho de TextView para formas de letras complejas
En versiones anteriores de Android, algunas fuentes cursivas o idiomas con formas complejas podían dibujar las letras en el área del carácter anterior o siguiente.
En algunos casos, esas letras se recortaban en la posición inicial o final.
A partir de Android 15, un TextView
asigna ancho a fin de generar suficiente espacio para esas letras y permite que las apps soliciten paddings adicionales a la izquierda para evitar el recorte.
Debido a que este cambio afecta la manera en que una TextView
decide el ancho, TextView
asigna más ancho de forma predeterminada si la app se orienta a Android 15 o versiones posteriores. Para habilitar o inhabilitar este comportamiento, llama a la API de setUseBoundsForWidth
en TextView
.
Como agregar padding izquierdo puede causar una desalineación para los diseños existentes, el padding no se agrega de forma predeterminada incluso en el caso de las apps orientadas a Android 15 o versiones posteriores.
Sin embargo, puedes agregar padding adicional para evitar el recorte llamando a setShiftDrawingOffsetForStartOverhang
.
En los siguientes ejemplos, se muestra cómo estos cambios pueden mejorar el diseño del texto de algunos idiomas y fuentes.
Altura de línea predeterminada en función de la configuración regional para EditText
In previous versions of Android, the text layout stretched the height of the
text to meet the line height of the font that matched the current locale. For
example, if the content was in Japanese, because the line height of the Japanese
font is slightly larger than the one of a Latin font, the height of the text
became slightly larger. However, despite these differences in line heights, the
EditText
element was sized uniformly, regardless
of the locale being used, as illustrated in the following image:
For apps targeting Android 15, a minimum line height is now reserved for
EditText
to match the reference font for the specified Locale, as shown in the
following image:
If needed, your app can restore the previous behavior by specifying the
useLocalePreferredLineHeightForMinimum
attribute
to false
, and your app can set custom minimum vertical metrics using the
setMinimumFontMetrics
API in Kotlin and Java.
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
以 Android 15 为目标平台的应用必须是热门应用或运行与音频相关的前台服务,才能请求音频焦点。如果应用在不符合其中任何一项要求时尝试请求焦点,调用会返回 AUDIOFOCUS_REQUEST_FAILED
。
如果前台服务的类型为 mediaPlayback
、camera
、microphone
或 phoneCall
,则会被视为与音频相关。
如需详细了解音频焦点,请参阅管理音频焦点。
Actualización de restricciones que no pertenecen al SDK
Android 15 包含更新后的受限非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测试)。在限制使用非 SDK 接口之前,我们会尽可能确保有可用的公开替代方案。
如果您的应用并非以 Android 15 为目标平台,其中一些变更可能不会立即对您产生影响。不过,虽然您的应用可以访问某些非 SDK 接口(具体取决于应用的目标 API 级别),但使用任何非 SDK 方法或字段始终存在导致应用出问题的显著风险。
如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试该应用进行确认。如果您的应用依赖于非 SDK 接口,则应开始计划迁移到 SDK 替代方案。不过,我们知道某些应用具有使用非 SDK 接口的有效用例。如果您无法为应用中的功能找到无需使用非 SDK 接口的替代方案,则应请求新的公共 API。
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.