Al igual que las versiones anteriores, Android 15 incluye cambios de comportamiento que podrían afectar tu app. Los siguientes cambios se aplican exclusivamente a las apps orientadas a Android 15 o versiones posteriores. Si tu app está segmentada para 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 en el comportamiento que afectan a todas las apps que se ejecutan en Android 15, independientemente de 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 introduces a new timeout behavior to dataSync
for apps targeting
Android 15 (API level 35) or higher. This behavior also applies to the new
mediaProcessing
foreground service type.
The system permits an app's dataSync
services to run for a total of 6 hours
in a 24-hour period, after which the system calls the running service's
Service.onTimeout(int, int)
method (introduced in Android
15). At this time, the service has a few seconds to call
Service.stopSelf()
. When Service.onTimeout()
is called, the
service is no longer considered a foreground service. If the service does not
call Service.stopSelf()
, the system throws an internal exception. The
exception is logged in Logcat with the following message:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
To avoid problems with this behavior change, you can do one or more of the following:
- Have your service implement the new
Service.onTimeout(int, int)
method. When your app receives the callback, make sure to callstopSelf()
within a few seconds. (If you don't stop the app right away, the system generates a failure.) - Make sure your app's
dataSync
services don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer). - Only start
dataSync
foreground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background. - Instead of using a
dataSync
foreground service, use an alternative API.
If your app's dataSync
foreground services have run for 6 hours in the last
24, you cannot start another dataSync
foreground service unless the user
has brought your app to the foreground (which resets the timer). If you try to
start another dataSync
foreground service, the system throws
ForegroundServiceStartNotAllowedException
with an error message like "Time limit already exhausted for foreground service
type dataSync".
Testing
To test your app's behavior, you can enable data sync timeouts even if your app
is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable timeouts, run the following adb
command:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
You can also adjust the timeout period, to make it easier to test how your
app behaves when the limit is reached. To set a new timeout period, run the
following adb
command:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
新的媒体处理前台服务类型
Android 15 引入了一种新的前台服务类型 mediaProcessing
。此服务类型适用于转码媒体文件等操作。例如,媒体应用可能会下载音频文件,并需要先将其转换为其他格式,然后才能播放。您可以使用 mediaProcessing
前台服务,确保即使应用在后台运行时转换也会继续。
系统允许应用的 mediaProcessing
服务在 24 小时内总共运行 6 小时,之后系统会调用正在运行的服务的 Service.onTimeout(int, int)
方法(在 Android 15 中引入)。此时,服务有几秒钟的时间来调用 Service.stopSelf()
。如果服务未调用 Service.stopSelf()
,系统会抛出内部异常。系统会在 Logcat 中记录此异常,并显示以下消息:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
为避免出现此异常,您可以执行以下任一操作:
- 让您的服务实现新的
Service.onTimeout(int, int)
方法。当您的应用收到回调时,请务必在几秒钟内调用stopSelf()
。(如果您未立即停止应用,系统会生成失败情况。) - 确保应用的
mediaProcessing
服务在任何 24 小时内总运行时间不超过 6 小时(除非用户与应用互动,重置计时器)。 - 仅在有直接用户互动时启动
mediaProcessing
前台服务;由于服务启动时应用位于前台,因此您的服务在应用进入后台后有完整的 6 小时时间。 - 请改用 替代 API(例如 WorkManager),而不是使用
mediaProcessing
前台服务。
如果您的应用的 mediaProcessing
前台服务在过去 24 小时内运行了 6 小时,则您无法启动其他 mediaProcessing
前台服务,除非用户将您的应用切换到前台(这会重置计时器)。如果您尝试启动另一个 mediaProcessing
前台服务,系统会抛出 ForegroundServiceStartNotAllowedException
,并显示类似于“前台服务类型 mediaProcessing 的时间限制已用尽”的错误消息。
如需详细了解 mediaProcessing
服务类型,请参阅 Android 15 前台服务类型变更:媒体处理。
测试
如需测试应用的行为,您可以启用媒体处理超时,即使您的应用并非以 Android 15 为目标平台也是如此(前提是应用在 Android 15 设备上运行)。如需启用超时,请运行以下 adb
命令:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
您还可以调整超时期限,以便更轻松地测试应用在达到上限时的行为方式。如需设置新的超时期限,请运行以下 adb
命令:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
对启动前台服务的 BOOT_COMPLETED
广播接收器的限制
There are new restrictions on BOOT_COMPLETED
broadcast receivers launching
foreground services. BOOT_COMPLETED
receivers are not allowed to launch the
following types of foreground services:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(this restriction has been in place formicrophone
since Android 14)
If a BOOT_COMPLETED
receiver tries to launch any of those types of foreground
services, the system throws ForegroundServiceStartNotAllowedException
.
Testing
To test your app's behavior, you can enable these new restrictions even if your
app is not targeting Android 15 (as long as the app is running on an Android 15
device). Run the following adb
command:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
To send a BOOT_COMPLETED
broadcast without restarting the device,
run the following adb
command:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
在应用拥有 SYSTEM_ALERT_WINDOW
权限时启动前台服务的限制
Anteriormente, si una app tenía el permiso SYSTEM_ALERT_WINDOW
, podía iniciar un servicio en primer plano, incluso si la app estaba en segundo plano (como se explica en exenciones de las restricciones de inicio en segundo plano).
Si una app está orientada a Android 15, esta exención ahora es más limitada. Ahora, la app debe tener el permiso SYSTEM_ALERT_WINDOW
y también tener una ventana superpuesta visible. Es decir, la app primero debe iniciar una ventana TYPE_APPLICATION_OVERLAY
y la ventana debe ser visible antes de iniciar un servicio en primer plano.
Si tu app intenta iniciar un servicio en primer plano desde segundo plano sin cumplir con estos nuevos requisitos (y no tiene otra exención), el sistema arroja ForegroundServiceStartNotAllowedException
.
Si tu app declara el permiso SYSTEM_ALERT_WINDOW
y, luego, inicia servicios en primer plano desde el segundo plano, es posible que se vea afectada por este cambio. Si tu app obtiene una ForegroundServiceStartNotAllowedException
, verifica el orden de operaciones de tu app y asegúrate de que ya tenga una ventana de superposición activa antes de intentar iniciar un servicio en primer plano desde el segundo plano. Puedes verificar si tu ventana de superposición es visible actualmente llamando a View.getWindowVisibility()
o puedes anular View.onWindowVisibilityChanged()
para recibir notificaciones cada vez que cambie la visibilidad.
Prueba
Para probar el comportamiento de tu app, puedes habilitar estas nuevas restricciones, incluso si tu app no está segmentada para Android 15 (siempre que la app se ejecute en un dispositivo con Android 15). Para habilitar estas nuevas restricciones para iniciar servicios en primer plano desde segundo plano, ejecuta el siguiente comando adb
:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
Cambios en el momento en que las apps pueden modificar el estado global del modo No interrumpir
Las apps que se orientan a Android 15 (nivel de API 35) y versiones posteriores ya no pueden cambiar el estado o la política globales de No interrumpir (ND) en un dispositivo (ya sea modificando la configuración del usuario o desactivando el modo ND). En su lugar, las apps deben contribuir con un AutomaticZenRule
, que el sistema combina en una política global con el esquema existente de política más restrictiva. Las llamadas a las APIs existentes que antes afectaban el estado global (setInterruptionFilter
, setNotificationPolicy
) generan la creación o actualización de un AutomaticZenRule
implícito, que se activa o desactiva según el ciclo de llamadas de esas llamadas a la API.
Ten en cuenta que este cambio solo afecta el comportamiento observable si la app llama a setInterruptionFilter(INTERRUPTION_FILTER_ALL)
y espera que esa llamada desactive un AutomaticZenRule
que sus propietarios activaron anteriormente.
Cambios en la API de OpenJDK
Android 15 continues the work of refreshing Android's core libraries to align with the features in the latest OpenJDK LTS releases.
Some of these changes can affect app compatibility for apps targeting Android 15 (API level 35):
Changes to string formatting APIs: Validation of argument index, flags, width, and precision are now more strict when using the following
String.format()
andFormatter.format()
APIs:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
For example, the following exception is thrown when an argument index of 0 is used (
%0
in the format string):IllegalFormatArgumentIndexException: Illegal format argument index = 0
In this case, the issue can be fixed by using an argument index of 1 (
%1
in the format string).Changes to component type of
Arrays.asList(...).toArray()
: When usingArrays.asList(...).toArray()
, the component type of the resulting array is now anObject
—not the type of the underlying array's elements. So the following code throws aClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
For this case, to preserve
String
as the component type in the resulting array, you could useCollection.toArray(Object[])
instead:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
Changes to language code handling: When using the
Locale
API, language codes for Hebrew, Yiddish, and Indonesian are no longer converted to their obsolete forms (Hebrew:iw
, Yiddish:ji
, and Indonesian:in
). When specifying the language code for one of these locales, use the codes from ISO 639-1 instead (Hebrew:he
, Yiddish:yi
, and Indonesian:id
).Changes to random int sequences: Following the changes made in https://bugs.openjdk.org/browse/JDK-8301574, the following
Random.ints()
methods now return a different sequence of numbers than theRandom.nextInt()
methods do:Generally, this change shouldn't result in app-breaking behavior, but your code shouldn't expect the sequence generated from
Random.ints()
methods to matchRandom.nextInt()
.
The new SequencedCollection
API can affect your app's compatibility
after you update compileSdk
in your app's build configuration to use
Android 15 (API level 35):
Collision with
MutableList.removeFirst()
andMutableList.removeLast()
extension functions inkotlin-stdlib
The
List
type in Java is mapped to theMutableList
type in Kotlin. Because theList.removeFirst()
andList.removeLast()
APIs have been introduced in Android 15 (API level 35), the Kotlin compiler resolves function calls, for examplelist.removeFirst()
, statically to the newList
APIs instead of to the extension functions inkotlin-stdlib
.If an app is re-compiled with
compileSdk
set to35
andminSdk
set to34
or lower, and then the app is run on Android 14 and lower, a runtime error is thrown:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
The existing
NewApi
lint option in Android Gradle Plugin can catch these new API usages../gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()To fix the runtime exception and lint errors, the
removeFirst()
andremoveLast()
function calls can be replaced withremoveAt(0)
andremoveAt(list.lastIndex)
respectively in Kotlin. If you're using Android Studio Ladybug | 2024.1.3 or higher, it also provides a quick fix option for these errors.Consider removing
@SuppressLint("NewApi")
andlintOptions { disable 'NewApi' }
if the lint option has been disabled.Collision with other methods in Java
New methods have been added into the existing types, for example,
List
andDeque
. These new methods might not be compatible with the methods with the same name and argument types in other interfaces and classes. In the case of a method signature collision with incompatibility, thejavac
compiler outputs a build-time error. For example:Example error 1:
javac MyList.java
MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface ListExample error 2:
javac MyList.java
MyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorExample error 3:
javac MyList.java
MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorTo fix these build errors, the class implementing these interfaces should override the method with a compatible return type. For example:
@Override public Object getFirst() { return List.super.getFirst(); }
Seguridad
Android 15 incluye cambios que promueven la seguridad del sistema para ayudar a proteger las apps y a los usuarios de las apps maliciosas.
Versiones de TLS restringidas
Android 15 restringe el uso de las versiones 1.0 y 1.1 de TLS. Estas versiones ya habían dejado de estar disponibles en Android, pero ahora no se permiten para las apps que se orientan a Android 15.
Inicio seguro de actividades en segundo plano
Android 15 protege a los usuarios de apps maliciosas y les da más control sobre sus dispositivos agregando cambios que eviten que las apps llevar otras apps al primer plano, elevar sus privilegios y fomentar el abuso la interacción del usuario. Los inicios de actividades en segundo plano se restringieron desde Android 10 (nivel de API 29).
Otros cambios
Además de la restricción para la coincidencia de UID, estos otros cambios también se incluidos:
- Cambia los creadores de
PendingIntent
para que bloqueen los inicios de actividades en segundo plano de forma predeterminada. Esto ayuda a evitar que las apps creen accidentalmente unPendingIntent
que personas malintencionadas podrían aprovechar. - No lleves una app al primer plano, a menos que el remitente de
PendingIntent
lo permita. El objetivo de este cambio es evitar que las apps maliciosas abusen de la capacidad de iniciar actividades en segundo plano. De forma predeterminada, las apps no pueden llevar la pila de actividades al primer plano, a menos que el creador permita privilegios de inicio de actividad en segundo plano o que el remitente tenga privilegios de inicio de actividad en segundo plano. - Controla cómo la actividad principal de una pila de tareas puede finalizar su tarea. Si el botón una actividad principal finaliza una tarea, Android regresará a la tarea que se haya la última vez que estuvo activo. Además, si una actividad que no es de primer nivel finaliza su tarea, Android volverá a la pantalla principal y no bloqueará el final de esta actividad que no es de primer nivel.
- Evita iniciar actividades arbitrarias de otras apps en la tuya tarea. Este cambio evita que las apps maliciosas creen ataques de phishing a través de la creación actividades que parecen ser de otras aplicaciones.
- Bloquea las ventanas no visibles para que no se consideren en los inicios de la actividad en segundo plano. Esto ayuda a evitar que las apps maliciosas abusen de los inicios de actividad en segundo plano para mostrar contenido no deseado o malicioso a los usuarios.
Intents más seguros
Android 15 introduces new optional 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.
In order to check how your app responds to these changes, use
StrictMode
in your app. To see detailed
logs about Intent
usage violations, add the following method:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
Experiencia del usuario y la IU del sistema
Android 15 incluye algunos cambios que tienen como objetivo crear una experiencia del usuario más coherente e intuitiva.
Cambios en la inserción de ventana
Hay dos cambios relacionados con los insertos de ventana en Android 15: el modo de pantalla completa se aplica de forma predeterminada y también hay cambios de configuración, como la configuración predeterminada de las barras del sistema.
Edge-to-edge enforcement
如果应用以 Android 15(API 级别 35)为目标平台,则在搭载 Android 15 的设备上默认以无边框显示。

这是一项重大变更,可能会对应用的界面产生负面影响。这些更改会影响以下界面区域:
- 手势柄导航栏
- 默认透明。
- 底部偏移量处于停用状态,因此内容会绘制在系统导航栏后面,除非应用了边衬区。
setNavigationBarColor
和R.attr#navigationBarColor
已被弃用,不会影响手势导航。setNavigationBarContrastEnforced
和R.attr#navigationBarContrastEnforced
继续对基于手势的导航没有任何影响。
- “三按钮”导航
- 默认情况下,不透明度设置为 80%,颜色可能与窗口背景颜色一致。
- 底部偏移量处于停用状态,因此内容会绘制在系统导航栏后面,除非应用了边衬区。
- 默认情况下,
setNavigationBarColor
和R.attr#navigationBarColor
设置为与窗口背景相匹配。窗口背景必须是颜色可绘制对象,才能应用此默认值。此 API 已弃用,但仍会影响三按钮导航。 setNavigationBarContrastEnforced
和R.attr#navigationBarContrastEnforced
默认值为 true,这会在三按钮导航栏中添加 80% 不透明度的背景。
- 状态栏
- 默认透明。
- 顶部偏移量处于停用状态,因此内容会绘制在状态栏后面,除非应用了边衬区。
setStatusBarColor
和R.attr#statusBarColor
已被废弃,在 Android 15 上不起作用。setStatusBarContrastEnforced
和R.attr#statusBarContrastEnforced
已废弃,但仍会对 Android 15 产生影响。
- 刘海屏
- 非浮动窗口的
layoutInDisplayCutoutMode
必须为LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
。SHORT_EDGES
、NEVER
和DEFAULT
会被解读为ALWAYS
,这样用户就不会看到因刘海屏而产生的黑条,并且应用会显示在屏幕边缘。
- 非浮动窗口的
以下示例展示了应用在以 Android 15(API 级别 35)为目标平台之前和之后,以及在应用边衬区之前和之后的效果。此示例并不全面,在 Android Auto 上可能会显示不同的内容。



如果应用已实现全屏显示,需要检查哪些方面
如果您的应用已实现全屏显示并应用边衬区,则在大多数情况下不会受到影响,但以下情形除外。不过,即使您认为自己不受影响,我们仍建议您测试应用。
- 您有一个非浮动窗口,例如使用
SHORT_EDGES
、NEVER
或DEFAULT
而不是LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
的Activity
。如果您的应用在启动时崩溃,这可能是由启动画面引起的。您可以将核心启动画面依赖项升级到 1.2.0-alpha01 或更高版本,也可以设置window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
。 - 可能存在流量较低且界面被遮挡的屏幕。验证这些访问频率较低的界面是否没有被遮挡的界面。低流量界面包括:
- 初始配置或登录界面
- “设置”页面
如果您的应用尚未实现全屏显示,需要检查哪些方面
如果您的应用尚未实现全屏显示,则很可能会受到影响。除了已经实现全屏显示的 app 的场景之外,您还应考虑以下事项:
- 如果您的应用在 Compose 中使用 Material 3 组件 (
androidx.compose.material3
),例如TopAppBar
、BottomAppBar
和NavigationBar
,这些组件很可能不会受到影响,因为它们会自动处理边衬区。 - 如果您的应用使用的是 Compose 中的 Material 2 组件 (
androidx.compose.material
),这些组件不会自动处理边衬区。不过,您可以获得边衬区的访问权限,然后手动应用边衬区。在 androidx.compose.material 1.6.0 及更高版本中,使用windowInsets
参数可为BottomAppBar
、TopAppBar
、BottomNavigation
和NavigationRail
手动应用边衬区。 同样,请为Scaffold
使用contentWindowInsets
参数。 - 如果您的应用使用视图和 Material 组件 (
com.google.android.material
),则大多数基于视图的 Material 组件(例如BottomNavigationView
、BottomAppBar
、NavigationRailView
或NavigationView
)都会处理边衬区,因此不需要执行额外的操作。不过,如果使用的是AppBarLayout
,则需要添加android:fitsSystemWindows="true"
。 - 对于自定义可组合项,请手动应用边衬区作为内边距。如果您的内容位于
Scaffold
内,则可以使用Scaffold
内边距值来使用插边。否则,请使用WindowInsets
之一应用内边距。 - 如果应用使用的是视图和
BottomSheet
、SideSheet
或自定义容器,请使用ViewCompat.setOnApplyWindowInsetsListener
应用内边距。对于RecyclerView
,请使用此监听器应用内边距,同时添加clipToPadding="false"
。
如果应用必须提供自定义后台保护,需要检查哪些方面
如果您的应用必须为三按钮导航或状态栏提供自定义背景保护,则应使用 WindowInsets.Type#tappableElement()
或 WindowInsets.Type#statusBars
将可组合项或视图放置在系统栏后面,以获取三按钮导航栏高度。
其他全屏显示资源
如需了解有关应用边衬区的其他注意事项,请参阅全屏视图和全屏 Compose 指南。
已弃用的 API
以下 API 已弃用,但未停用:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
(适用于三按钮导航,alpha 为 80%)Window#isStatusBarContrastEnforced
Window#setNavigationBarColor
(适用于三按钮导航,透明度为 80%)Window#setStatusBarContrastEnforced
以下 API 已弃用并停用:
R.attr#navigationBarColor
(适用于手势导航)R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#setDecorFitsSystemWindows
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#setNavigationBarColor
(适用于手势导航)Window#setNavigationBarDividerColor
Window#setStatusBarColor
Stable configuration
Si tu app se segmenta para Android 15 (nivel de API 35) 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 mejores alternativas, como un ViewGroup
, WindowInsets
o WindowMetricsCalculator
apropiado, según tus necesidades.
Configuration
está disponible desde la API nivel 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 devuelve 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 se desaconsejó usarlo para el cálculo del diseño. Si es así, debes alejarte de él ahora. Debes reemplazar el uso de Configuration
por algo más adecuado según tu caso de uso.
Si lo usas para calcular el diseño, usa un ViewGroup
adecuado, como CoordinatorLayout
o ConstraintLayout
. Si lo usas para determinar la altura de la barra de navegación del sistema, usa WindowInsets
. Si quieres 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 afectado indirectamente por los cambios enscreenWidthDp
yscreenHeightDp
en dispositivos casi cuadrados.Display.getSize(Point)
se ve afectado indirectamente por los cambios enConfiguration
. Este método 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 elegantTextHeight tiene el valor predeterminado establecido en verdadero.
For apps targeting Android 15 (API level 35), the
elegantTextHeight
TextView
attribute
becomes true
by default, replacing the compact font used by default with some
scripts that have large vertical metrics with one that is much more readable.
The compact font was introduced to prevent breaking layouts; Android 13 (API
level 33) prevents many of these breakages by allowing the text layout to
stretch the vertical height utilizing the fallbackLineSpacing
attribute.
In Android 15, the compact font still remains in the system, so your app can set
elegantTextHeight
to false
to get the same behavior as before, but it is
unlikely to be supported in upcoming releases. So, if your app supports the
following scripts: Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam,
Odia, Telugu or Thai, test your app by setting elegantTextHeight
to true
.

elegantTextHeight
behavior for apps targeting Android 14 (API level 34) and lower.
elegantTextHeight
behavior for apps targeting Android 15.El ancho de TextView cambia para formas de letras complejas
En versiones anteriores de Android, algunas fuentes o idiomas en cursiva que tienen formas complejas podrían dibujar las letras en el área del carácter anterior o siguiente.
En algunos casos, esas letras se cortaron al principio o al final.
A partir de Android 15, un TextView
asigna ancho para dibujar suficiente espacio para esas letras y permite que las apps soliciten paddings adicionales a la izquierda para evitar los recortes.
Como este cambio afecta la forma en que un TextView
decide el ancho, TextView
asigna más ancho de forma predeterminada si la app se orienta a Android 15 (nivel de API 35) o versiones posteriores. Para habilitar o inhabilitar este comportamiento, llama a la API de setUseBoundsForWidth
en TextView
.
Como agregar padding izquierdo puede causar un desajuste en 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 de texto para algunas fuentes y algunos idiomas.

<TextView android:fontFamily="cursive" android:text="java" />

<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />

<TextView android:text="คอมพิวเตอร์" />

<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
Altura de línea predeterminada compatible con la configuración regional para EditText
在较低版本的 Android 中,文本布局会拉伸文本的高度,以满足与当前语言区域匹配的字体的行高。例如,如果内容是日语,由于日语字体的行高略高于拉丁字体,因此文本的高度会略高。不过,尽管行高存在这些差异,但无论使用的是哪种语言区域,EditText
元素的大小都是统一的,如下图所示:

EditText
元素。EditText
的高度相同,即使这些语言的行高各不相同。对于以 Android 15(API 级别 35)为目标平台的应用,现在为 EditText
预留了最小行高,以匹配指定语言区域的参考字体,如下图所示:

EditText
元素。EditText
的高度现在包含足够的空间来容纳这些语言字体的默认行高。如有需要,您的应用可以将 useLocalePreferredLineHeightForMinimum
属性指定为 false
,以恢复之前的行为;您的应用还可以在 Kotlin 和 Java 中使用 setMinimumFontMetrics
API 设置自定义最小垂直指标。
Cámara y contenido multimedia
Android 15 realiza los siguientes cambios en el comportamiento de la cámara y los medios para las apps que se segmentan para Android 15 o versiones posteriores.
Restricciones para solicitar el foco de audio
以 Android 15(API 级别 35)为目标平台的应用必须是顶部应用或正在运行前台服务,才能请求音频焦点。如果应用在未满足上述任一要求的情况下尝试请求焦点,调用将返回 AUDIOFOCUS_REQUEST_FAILED
。
如需详细了解音频焦点,请参阅管理音频焦点。
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á segmentada para Android 15, es posible que algunos de estos cambios no te afecten de inmediato. Sin embargo, si bien tu app puede acceder a algunas interfaces que no pertenecen al SDK según el nivel de API objetivo de tu app, usar cualquier método o campo que no pertenezca al SDK siempre implica un gran riesgo de error para tu app.
Si no sabes con seguridad si tu app usa este tipo de interfaces, puedes probarla para verificarlo. Si tu app depende de interfaces que no pertenecen al SDK, deberías 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 al 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.