Wie bei früheren Releases enthält Android 15 Verhaltensänderungen, die sich auf Ihre App auswirken können. Die folgenden Verhaltensänderungen gelten ausschließlich für Apps, die auf Android 15 oder höher ausgerichtet sind. Wenn Ihre App auf Android 15 oder höher ausgerichtet ist, sollten Sie sie gegebenenfalls so ändern, dass sie diese Verhaltensweisen korrekt unterstützt.
Lesen Sie sich auch die Liste der Verhaltensänderungen durch, die sich auf alle Apps auswirken, die unter Android 15 ausgeführt werden, unabhängig von der targetSdkVersion
Ihrer App.
Hauptfunktion
In Android 15 wurden verschiedene Kernfunktionen des Android-Systems geändert oder erweitert.
Änderungen an Diensten im Vordergrund
Wir nehmen unter Android 15 die folgenden Änderungen an Diensten im Vordergrund vor.
- Verhalten bei Zeitüberschreitung bei der Datensynchronisierung im Vordergrund
- Neuer Dienst für die Medienverarbeitung im Vordergrund
- Einschränkungen für
BOOT_COMPLETED
Übertragungsempfänger, die Dienste im Vordergrund starten - Einschränkungen beim Starten von Diensten im Vordergrund, während eine App die Berechtigung
SYSTEM_ALERT_WINDOW
enthält
Verhalten bei Zeitüberschreitung bei der Datensynchronisierung im Vordergrund
Unter Android 15 wird für dataSync
ein neues Zeitlimit für Apps eingeführt, die auf Android 15 (API-Level 35) oder höher ausgerichtet sind. Dies gilt auch für den neuen Diensttyp mediaProcessing
im Vordergrund.
Das System erlaubt es den dataSync
-Diensten einer App, innerhalb eines Zeitraums von 24 Stunden insgesamt 6 Stunden lang ausgeführt zu werden. Danach ruft das System die Methode Service.onTimeout(int, int)
des laufenden Dienstes auf (in Android 15 eingeführt). In dieser Zeit hat der Dienst einige Sekunden Zeit, Service.stopSelf()
aufzurufen. Wenn Service.onTimeout()
aufgerufen wird, gilt der Dienst nicht mehr als Dienst im Vordergrund. Wenn der Dienst Service.stopSelf()
nicht aufruft, löst das System eine interne Ausnahme aus. Die Ausnahme wird in Logcat mit der folgenden Meldung protokolliert:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
So vermeiden Sie Probleme mit dieser Verhaltensänderung:
- Lassen Sie Ihren Dienst die neue
Service.onTimeout(int, int)
-Methode implementieren. Wenn Ihre App den Callback empfängt, müssen Sie innerhalb weniger SekundenstopSelf()
anrufen. Wenn Sie die App nicht sofort beenden, generiert das System einen Fehler. - Die
dataSync
-Dienste Ihrer App dürfen innerhalb eines 24-Stunden-Zeitraums nicht länger als insgesamt 6 Stunden ausgeführt werden, es sei denn, der Nutzer interagiert mit der App und setzt den Timer zurück. - Starten Sie
dataSync
Dienste im Vordergrund nur als Folge einer direkten Nutzerinteraktion. Da sich Ihre App beim Start des Dienstes im Vordergrund befindet, hat Ihr Dienst die vollen sechs Stunden Zeit, nachdem die App in den Hintergrund gewechselt ist. - Verwenden Sie stattdessen eine alternative API.
dataSync
Wenn die dataSync
-Dienste im Vordergrund Ihrer App in den letzten 24 Stunden sechs Stunden lang ausgeführt wurden, können Sie keinen weiteren dataSync
-Dienst im Vordergrund starten, es sei denn, der Nutzer hat Ihre App in den Vordergrund gebracht (wodurch der Timer zurückgesetzt wird). Wenn Sie versuchen, einen weiteren dataSync
-Vordergrunddienst zu starten, gibt das System ForegroundServiceStartNotAllowedException
mit einer Fehlermeldung zurück, z. B. „Zeitlimit für den Typ ‚dataSync‘ des Vordergrunddienstes bereits überschritten“.
Testen
Sie können Zeitüberschreitungen für die Datensynchronisierung aktivieren, um das Verhalten Ihrer App zu testen, auch wenn Ihre App nicht auf Android 15 ausgerichtet ist, solange die App auf einem Android 15-Gerät ausgeführt wird. Führen Sie den folgenden Befehl adb
aus, um Zeitüberschreitungen zu aktivieren:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
Sie können auch die Zeitüberschreitung anpassen, um das Verhalten Ihrer App nach Erreichen des Limits leichter zu testen. Führen Sie den folgenden adb
-Befehl aus, um ein neues Zeitlimit festzulegen:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
Neuer Typ von Dienst zur Medienverarbeitung im Vordergrund
Android 15 introduces a new foreground service type, mediaProcessing
. This
service type is appropriate for operations like transcoding media files. For
example, a media app might download an audio file and need to convert it to a
different format before playing it. You can use a mediaProcessing
foreground
service to make sure the conversion continues even while the app is in the
background.
The system permits an app's mediaProcessing
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()
. 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 mediaProcessing did not stop within its timeout: [component name]"
To avoid having the exception, you can do one 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
mediaProcessing
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
mediaProcessing
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
mediaProcessing
foreground service, use an alternative API, like WorkManager.
If your app's mediaProcessing
foreground services have run for 6 hours in the
last 24, you cannot start another mediaProcessing
foreground service unless
the user has brought your app to the foreground (which resets the timer). If you
try to start another mediaProcessing
foreground service, the system throws
ForegroundServiceStartNotAllowedException
with an error message like "Time limit already exhausted for foreground service
type mediaProcessing".
For more information about the mediaProcessing
service type, see Changes to
foreground service types for Android 15: Media processing.
Testing
To test your app's behavior, you can enable media processing 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 media_processing_fgs_timeout_duration duration-in-milliseconds
Einschränkungen für BOOT_COMPLETED
Übertragungsempfänger, die Dienste im Vordergrund starten
在启动 BOOT_COMPLETED
广播接收器方面存在新限制
前台服务。BOOT_COMPLETED
接收器不能启动
以下类型的前台服务:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(自 Android 14 起,microphone
就受到此限制)
如果 BOOT_COMPLETED
接收器尝试启动任何上述类型的前台
服务,系统会抛出 ForegroundServiceStartNotAllowedException
。
测试
如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。运行以下 adb
命令:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
如需在不重启设备的情况下发送 BOOT_COMPLETED
广播,请运行以下 adb
命令:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
Einschränkungen beim Starten von Diensten im Vordergrund, während eine App die Berechtigung „SYSTEM_ALERT_WINDOW
“ enthält
Previously, if an app held the SYSTEM_ALERT_WINDOW
permission, it could launch
a foreground service even if the app was currently in the background (as
discussed in exemptions from background start restrictions).
If an app targets Android 15, this exemption is now narrower. The app now needs
to have the SYSTEM_ALERT_WINDOW
permission and also have a visible overlay
window. That is, the app needs to first launch a
TYPE_APPLICATION_OVERLAY
window and the window
needs to be visible before you start a foreground service.
If your app attempts to start a foreground service from the background without
meeting these new requirements (and it does not have some other exemption), the
system throws ForegroundServiceStartNotAllowedException
.
If your app declares the SYSTEM_ALERT_WINDOW
permission
and launches foreground services from the background, it may be affected by this
change. If your app gets a ForegroundServiceStartNotAllowedException
, check
your app's order of operations and make sure your app already has an active
overlay window before it attempts to start a foreground service from the
background. You can check if your overlay window is currently visible
by calling View.getWindowVisibility()
, or you
can override View.onWindowVisibilityChanged()
to get notified whenever the visibility changes.
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). To enable these new restrictions on starting foreground services
from the background, run the following adb
command:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
Änderungen bei der Möglichkeit von Apps, den globalen Status des Modus „Bitte nicht stören“ zu ändern
以 Android 15 为目标平台的应用无法再更改设备上的全局状态或勿扰 (DND) 政策(通过修改用户设置或关闭 DND 模式)。相反,应用必须提供一个 AutomaticZenRule
,系统会将后者合并到一个具有现有最严格的政策胜出方案的全局政策中。调用之前影响全局状态的现有 API(setInterruptionFilter
、setNotificationPolicy
)会导致创建或更新隐式 AutomaticZenRule
,该 AutomaticZenRule
根据这些 API 调用的调用周期而开启或关闭。
请注意,只有在应用调用 setInterruptionFilter(INTERRUPTION_FILTER_ALL)
且预期调用会停用之前由其所有者激活的 AutomaticZenRule
时,此变更才会影响可观察的行为。
Änderungen an der OpenJDK API
Android 15 将继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。
其中一些变更可能会影响以 Android 15(API 级别 35)为目标平台的应用的兼容性:
对字符串格式化 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
)来解决此问题。Arrays.asList(...).toArray()
的组件类型变更:使用Arrays.asList(...).toArray()
时,生成数组的组件类型现在为Object
,而不是底层数组元素的类型。因此,以下代码会抛出ClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
对于这种情况,如需将
String
保留为生成的数组中的组件类型,您可以改用Collection.toArray(Object[])
:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
语言代码处理方式变更:使用
Locale
API 时,希伯来语、意第绪语和印度尼西亚语的语言代码不再转换为已废弃的形式(希伯来语:iw
、意第绪语:ji
、印度尼西亚语:in
)。在为其中一种语言区域指定语言代码时,请改用 ISO 639-1 中的代码(希伯来语:he
、意第绪语:yi
、印度尼西亚语:id
)。对随机 int 序列的更改:在 https://bugs.openjdk.org/browse/JDK-8301574 中进行更改后,以下
Random.ints()
方法现在返回的数字序列与Random.nextInt()
方法返回的序列不同:通常,此更改不会导致应用出现破坏行为,但您的代码不应预期从
Random.ints()
方法生成的序列与Random.nextInt()
匹配。
在您更新应用 build 配置中的 compileSdk
以使用 Android 15(API 级别 35)后,新的 SequencedCollection
API 可能会影响应用的兼容性:
与
kotlin-stdlib
中的MutableList.removeFirst()
和MutableList.removeLast()
扩展函数发生冲突Java 中的
List
类型会映射到 Kotlin 中的MutableList
类型。由于List.removeFirst()
和List.removeLast()
API 已在 Android 15(API 级别 35)中引入,因此 Kotlin 编译器会将函数调用(例如list.removeFirst()
)静态解析为新的List
API,而不是kotlin-stdlib
中的扩展函数。如果将应用重新编译并将
compileSdk
设置为35
且将minSdk
设置为34
或更低级别,然后在 Android 14 及更低版本上运行该应用,系统会抛出运行时错误:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
Android Gradle 插件中现有的
NewApi
lint 选项可以捕获这些新的 API 用法。./gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()如需修复运行时异常和 lint 错误,可以在 Kotlin 中将
removeFirst()
和removeLast()
函数调用分别替换为removeAt(0)
和removeAt(list.lastIndex)
。如果您使用的是 Android Studio Ladybug | 2024.1.3 或更高版本,则该版本还提供了针对这些错误的快速修复选项。如果 lint 选项已停用,请考虑移除
@SuppressLint("NewApi")
和lintOptions { disable 'NewApi' }
。与 Java 中的其他方法冲突
现有类型中添加了新方法,例如
List
和Deque
。这些新方法可能与其他接口和类中具有相同名称和参数类型的方法不兼容。如果方法签名发生冲突且不兼容,javac
编译器会输出构建时错误。例如:错误示例 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 List错误示例 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 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 error如需修复这些构建错误,实现这些接口的类应使用兼容的返回类型替换该方法。例如:
@Override public Object getFirst() { return List.super.getFirst(); }
Sicherheit
Android 15 enthält Änderungen, die die Systemsicherheit verbessern und Apps und Nutzer vor schädlichen Apps schützen sollen.
Start von sicheren Hintergrundaktivitäten
Android 15 schützt Nutzer vor schädlichen Apps und gibt ihnen mehr Kontrolle über indem sie Änderungen hinzufügen, die verhindern, das Hervorheben anderer Apps im Vordergrund, Erhöhen ihrer Berechtigungen und Missbrauch der Nutzerinteraktion. Das Starten von Hintergrundaktivitäten wurde seitdem eingeschränkt Android 10 (API-Level 29)
Starten von Aktivitäten für Apps, die nicht mit der obersten UID im Stapel übereinstimmen, blockieren
Schädliche Apps können die Aktivitäten einer anderen App innerhalb derselben Aufgabe starten.
überlagern sich und erzeugen den Eindruck, diese App zu sein. Diese „Aufgabe
Kontodiebstahl“ die aktuellen Einschränkungen beim Start im Hintergrund
innerhalb derselben sichtbaren Aufgabe auftritt. Um dieses Risiko zu mindern, wird Android 15
Flag, das den Start von Apps blockiert, die nicht mit der obersten UID im Stack übereinstimmen
Aktivitäten. Wenn du alle Aktivitäten deiner App aktivieren möchtest, aktualisiere die
allowCrossUidActivitySwitchFromBelow
Attribut in der AndroidManifest.xml
-Datei Ihrer App:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
Die neuen Sicherheitsmaßnahmen sind aktiv, wenn alle der folgenden Bedingungen erfüllt sind:
- Die App, mit der die Markteinführung durchgeführt wird, ist auf Android 15 ausgerichtet.
- Die App, die dem Aufgabenstapel übergeht, ist auf Android 15 ausgerichtet.
- Die neuen Schutzmaßnahmen wurden für alle sichtbaren Aktivitäten aktiviert
Wenn die Sicherheitsmaßnahmen aktiviert sind, werden Apps möglicherweise wieder zu Hause angezeigt, der letzten sichtbaren App, wenn sie ihre eigene Aufgabe beendet.
Sonstige Änderungen
Neben der Einschränkung des UID-Abgleichs enthalten:
PendingIntent
Creator so ändern, dass Starten von Hintergrundaktivitäten blockiert werden, indem Standardeinstellung. So wird verhindert, dass Apps versehentlich einPendingIntent
, die von böswilligen Akteuren missbraucht werden könnten.- Bringe eine App nur dann in den Vordergrund, wenn der Absender
PendingIntent
. Mit dieser Änderung soll verhindert werden, dass schädliche Apps den Aktivitäten im Hintergrund starten können. Standardmäßig werden Apps nicht Sie dürfen den Aufgabenstapel in den Vordergrund holen, es sei denn, der Ersteller erlaubt Berechtigungen zum Starten von Hintergrundaktivitäten oder der Absender hat Hintergrundaktivitäten Startberechtigungen. - Steuern, wie die oberste Aktivität eines Aufgabenstapels ihre Aufgabe beenden kann. Wenn die häufigste Aktivität eine Aufgabe beendet, wechselt Android zu der Aufgabe zurück, Zuletzt aktiv. Wenn eine Aktivität, die nicht am wichtigsten ist, ihre Aufgabe beendet, wird Android kehren zum Startbildschirm zurück. wird das Ende dieser nicht oben stehenden Seite Aktivitäten.
- Starten beliebiger Aktivitäten von anderen Apps in Ihre eigene App verhindern Aufgabe. Durch diese Änderung werden schädliche Apps vor Phishing-Nutzern geschützt, indem Aktivitäten, die offenbar aus anderen Apps stammen.
- Verhindern, dass nicht sichtbare Fenster für Hintergrundaktivitäten berücksichtigt werden Markteinführungen. So wird verhindert, dass schädliche Apps den Hintergrund missbrauchen um Nutzern unerwünschte oder schädliche Inhalte anzuzeigen.
Sicherere Intents
Android 15 引入了新的可选安全措施,以提高 intent 的安全性和稳健性。这些变更旨在防止潜在的漏洞以及恶意应用可能利用的 intent 滥用行为。Android 15 对 intent 的安全性进行了两项主要改进:
- 与目标 intent 过滤器匹配:定位到特定组件的 intent 必须与目标的 intent 过滤器规范完全匹配。如果您发送 intent 来启动其他应用的 activity,目标 intent 组件需要与接收 activity 声明的 intent 过滤器保持一致。
- intent 必须具有操作:没有操作的 intent 将不再与任何 intent 过滤器匹配。这意味着,用于启动 activity 或服务的 intent 必须具有明确定义的操作。
如需检查您的应用对这些更改的响应方式,请在应用中使用 StrictMode
。如需查看有关 Intent
使用违规行为的详细日志,请添加以下方法:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
Nutzererfahrung und System-UI
Android 15 enthält einige Änderungen, die für eine einheitlichere und intuitivere Nutzererfahrung sorgen sollen.
Änderungen am Fenstereinsatz
In Android 15 gibt es zwei Änderungen im Zusammenhang mit Fenstereinsätzen: Edge-to-Edge-Änderungen werden standardmäßig erzwungen. Außerdem gibt es Konfigurationsänderungen, z. B. die Standardkonfiguration von Systemleisten.
Edge-to-Edge-Erzwingung
Apps sind auf Geräten mit Android 15 standardmäßig Edge-to-Edge-Apps, wenn sie auf Android 15 (API-Level 35) ausgerichtet sind.
Diese nicht abwärtskompatible Änderung kann sich negativ auf die Benutzeroberfläche Ihrer App auswirken. Die Änderungen betreffen die folgenden Bereiche der Benutzeroberfläche:
- Navigationsleiste mit Touch-Griff
- Standardmäßig transparent.
- Der vertikale Versatz ist deaktiviert, sodass Inhalte hinter der Navigationsleiste des Systems dargestellt werden, es sei denn, Einzüge werden angewendet.
setNavigationBarColor
undR.attr#navigationBarColor
sind eingestellt und haben keine Auswirkungen auf die Gestennavigation.setNavigationBarContrastEnforced
undR.attr#navigationBarContrastEnforced
haben weiterhin keine Auswirkungen auf die Gestennavigation.
- Bedienung über 3 Schaltflächen
- Die Deckkraft ist standardmäßig auf 80% eingestellt und die Farbe entspricht möglicherweise dem Fensterhintergrund.
- Offset am unteren Rand ist deaktiviert, sodass Inhalte hinter der Systemnavigationsleiste angezeigt werden, sofern keine Einfügungen angewendet werden.
setNavigationBarColor
undR.attr#navigationBarColor
sind standardmäßig auf den Fensterhintergrund abgestimmt. Der Fensterhintergrund muss ein farbiges Drawable sein, damit diese Standardeinstellung angewendet werden kann. Diese API wird eingestellt, hat aber weiterhin Auswirkungen auf die Navigation mit drei Schaltflächen.setNavigationBarContrastEnforced
undR.attr#navigationBarContrastEnforced
sind standardmäßig aktiviert. Dadurch wird der Navigationsbereich mit drei Schaltflächen einen 80% opaken Hintergrund haben.
- Statusleiste
- Standardmäßig transparent.
- Der obere Versatz ist deaktiviert, sodass Inhalte hinter der Statusleiste dargestellt werden, es sei denn, es werden Einzüge angewendet.
setStatusBarColor
undR.attr#statusBarColor
werden nicht mehr unterstützt und haben keine Auswirkungen auf Android 15.setStatusBarContrastEnforced
undR.attr#statusBarContrastEnforced
sind eingestellt, wirken sich aber weiterhin auf Android 15 aus.
- Displayausschnitt
layoutInDisplayCutoutMode
von nicht frei schwebenden Fenstern mussLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
sein.SHORT_EDGES
,NEVER
undDEFAULT
werden alsALWAYS
interpretiert, damit Nutzer keine schwarze Leiste sehen, die durch den Displayausschnitt verursacht wird, und die Inhalte randlos angezeigt werden.
Im folgenden Beispiel wird eine App vor und nach der Ausrichtung auf Android 15 (API-Ebene 35) sowie vor und nach dem Anwenden von Einsätzen gezeigt.
Prüfen, ob Ihre App bereits bildschirmfüllend ist
Wenn Ihre App bereits randlos ist und Einzüge verwendet, sind Sie in den folgenden Fällen davon nicht betroffen: Auch wenn Sie der Meinung sind, dass Sie nicht betroffen sind, empfehlen wir Ihnen, Ihre App zu testen.
- Sie haben ein nicht schwebendes Fenster, z. B. ein
Activity
, dasSHORT_EDGES
,NEVER
oderDEFAULT
anstelle vonLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
verwendet. Wenn Ihre App beim Starten abstürzt, kann das an Ihrem Splashscreen liegen. Sie können die Abhängigkeit des Core-Splashscreens auf 1.2.0-alpha01 oder höher aktualisieren oderwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
festlegen. - Es kann sein, dass es Bildschirme mit weniger Zugriffen gibt, auf denen die Benutzeroberfläche verdeckt ist. Prüfen Sie, ob die Benutzeroberfläche auf diesen weniger besuchten Bildschirmen nicht verdeckt ist. Beispiele für Bildschirme mit weniger Zugriffen:
- Einrichtungs- oder Anmeldebildschirme
- Einstellungsseiten
Was Sie prüfen sollten, wenn Ihre App noch nicht bildschirmfüllend ist
Wenn Ihre App noch nicht auf dem neuesten Stand ist, sind Sie höchstwahrscheinlich betroffen. Zusätzlich zu den Szenarien für Anwendungen, die bereits Edge-to-Edge-Anwendungen haben, sollten Sie Folgendes berücksichtigen:
- Wenn Ihre App Material 3-Komponenten (
androidx.compose.material3
) beim Schreiben verwendet, z. B.TopAppBar
,BottomAppBar
undNavigationBar
, sind diese Komponenten wahrscheinlich nicht betroffen, da sie Einfügungen automatisch verarbeiten. - Wenn Ihre App Material 2-Komponenten (
androidx.compose.material
) in Compose verwendet, verarbeiten diese Komponenten nicht automatisch Einfügungen. Sie können jedoch auf die Einleger zugreifen und sie manuell anwenden. In androidx.compose.material 1.6.0 und höher können Sie mit dem ParameterwindowInsets
die Einzüge manuell fürBottomAppBar
,TopAppBar
,BottomNavigation
undNavigationRail
anwenden. Verwenden Sie den ParametercontentWindowInsets
auch fürScaffold
. - Wenn Ihre App Ansichten und Material Components (
com.google.android.material
) verwendet, werden die meisten auf Ansichten basierenden Material Components wieBottomNavigationView
,BottomAppBar
,NavigationRailView
oderNavigationView
für Einzüge verwendet und erfordern keine zusätzlichen Arbeiten. Wenn SieAppBarLayout
verwenden, müssen Sie jedochandroid:fitsSystemWindows="true"
hinzufügen. - Bei benutzerdefinierten Composeables müssen Sie die Einzüge manuell als Abstand anwenden. Wenn sich Ihr Inhalt in einem
Scaffold
befindet, können Sie Einfügungen mithilfe derScaffold
-Padding-Werte aufnehmen. Andernfalls können Sie mithilfe vonWindowInsets
ein Abstandselement hinzufügen. - Wenn Ihre App Ansichten und
BottomSheet
-,SideSheet
- oder benutzerdefinierte Container verwendet, wenden Sie mitViewCompat.setOnApplyWindowInsetsListener
einen Abstand an. Wenden Sie fürRecyclerView
mit diesem Listener einen Abstand an und fügen SieclipToPadding="false"
hinzu.
Prüfen, ob Ihre App benutzerdefinierten Hintergrundschutz bieten muss
Wenn Ihre App einen benutzerdefinierten Hintergrundschutz für die Bedienung über 3 Schaltflächen oder die Statusleiste bieten muss, sollte in Ihrer App eine zusammensetzbare Funktion oder Ansicht hinter der Systemleiste platziert werden. Verwenden Sie dazu WindowInsets.Type#tappableElement()
, um die Höhe der Navigationsleiste mit 3 Schaltflächen oder WindowInsets.Type#statusBars
zu ermitteln.
Weitere Ressourcen für die Bildbearbeitung
Weitere Informationen zum Anwenden von Einfügungen finden Sie in den Leitfäden Edge to Edge View und Edge to Edge Compose.
Eingestellte APIs
Die folgenden APIs wurden verworfen, aber nicht deaktiviert:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
(für die Bedienung über drei Schaltflächen mit 80 % Alpha)Window#isStatusBarContrastEnforced
Window#setNavigationBarColor
(für die Bedienung über drei Schaltflächen, mit 80% Alpha)Window#setStatusBarContrastEnforced
Die folgenden APIs werden eingestellt und deaktiviert:
R.attr#navigationBarColor
(für die Bedienung über Gesten)R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#setDecorFitsSystemWindows
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#setNavigationBarColor
(für die Bedienung über Gesten)Window#setNavigationBarDividerColor
Window#setStatusBarColor
Stabile Konfiguration
Wenn Ihre App auf Android 15 (API-Level 35) oder höher ausgerichtet ist, werden die Systemleisten von Configuration
nicht mehr ausgeschlossen. Wenn Sie die Bildschirmgröße in der Configuration
-Klasse für die Layoutberechnung verwenden, sollten Sie sie je nach Bedarf durch bessere Alternativen wie ViewGroup
, WindowInsets
oder WindowMetricsCalculator
ersetzen.
Configuration
ist seit API 1 verfügbar. Sie wird normalerweise aus Activity.onConfigurationChanged
abgerufen. Sie enthält Informationen wie Fensterdichte, -ausrichtung und -größe. Ein wichtiges Merkmal der von Configuration
zurückgegebenen Fenstergrößen ist, dass zuvor die Systemleisten ausgeschlossen wurden.
Die Konfigurationsgröße wird in der Regel für die Ressourcenauswahl verwendet, z. B. für /res/layout-h500dp
. Dies ist weiterhin ein gültiger Anwendungsfall. Es wurde jedoch immer davon abgeraten, es zur Berechnung
des Layouts zu verwenden. In diesem Fall sollten Sie sich jetzt davon abwenden. Je nach Anwendungsfall sollten Sie Configuration
durch einen geeigneteren Wert ersetzen.
Wenn Sie es zum Berechnen des Layouts verwenden, verwenden Sie eine geeignete ViewGroup
, z. B. CoordinatorLayout
oder ConstraintLayout
. Wenn Sie damit die Höhe der System-Navigationsleiste festlegen möchten, verwenden Sie WindowInsets
. Wenn Sie die aktuelle Größe Ihres App-Fensters ermitteln möchten, verwenden Sie computeCurrentWindowMetrics
.
In der folgenden Liste werden die Felder beschrieben, die von dieser Änderung betroffen sind:
- Bei den Größen
Configuration.screenWidthDp
undscreenHeightDp
werden die Systemleisten nicht mehr ausgeblendet. Configuration.smallestScreenWidthDp
ist indirekt von Änderungen anscreenWidthDp
undscreenHeightDp
betroffen.Configuration.orientation
wird indirekt von Änderungen anscreenWidthDp
undscreenHeightDp
auf nahezu quadratischen Geräten beeinflusst.Display.getSize(Point)
ist indirekt von den Änderungen inConfiguration
betroffen. Diese Funktion wurde ab API-Level 30 eingestellt.Display.getMetrics()
funktioniert seit API-Level 33 bereits so.
Das Attribut „elegantTextHeight“ hat standardmäßig den Wert „true“.
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
.
Breite des TextViews ändert sich bei komplexen Buchstabenformen
在以前的 Android 版本中,某些具有复杂形状的手写字体或语言可能会在上一个或下一个字符的区域绘制字母。在某些情况下,此类字母会在开头或结尾处被剪裁。从 Android 15 开始,TextView
会分配宽度,以便为此类字母绘制足够的空间,并允许应用请求向左额外添加内边距以防止剪裁。
由于此更改会影响 TextView
确定宽度的方式,因此如果应用以 Android 15(API 级别 35)或更高版本为目标平台,TextView
会默认分配更多宽度。您可以通过对 TextView
调用 setUseBoundsForWidth
API 来启用或停用此行为。
由于添加左内边距可能会导致现有布局未对齐,因此默认情况下不会添加内边距,即使以 Android 15 或更高版本为目标平台的应用也是如此。不过,您可以通过调用 setShiftDrawingOffsetForStartOverhang
添加额外的内边距以防止剪裁。
以下示例展示了这些更改如何改进某些字体和语言的文本布局。
Localespezifische Standardzeilenhöhe für 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 (API level 35), 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.
Kamera und Medien
Unter Android 15 werden die folgenden Änderungen am Kamera- und Medienverhalten für Apps vorgenommen, die auf Android 15 oder höher ausgerichtet sind.
Einschränkungen beim Anfordern des Audiofokus
以 Android 15 为目标平台的应用必须是顶级应用或运行前台服务,才能请求音频焦点。如果应用在不符合其中任何一项要求时尝试请求焦点,该调用将返回 AUDIOFOCUS_REQUEST_FAILED
。
您可以参阅管理音频焦点,详细了解音频焦点。
Aktualisierte Einschränkungen für Nicht-SDKs
Android 15 includes updated lists of restricted non-SDK interfaces based on collaboration with Android developers and the latest internal testing. Whenever possible, we make sure that public alternatives are available before we restrict non-SDK interfaces.
If your app does not target Android 15, some of these changes might not immediately affect you. However, while it's possible for your app to access some non-SDK interfaces depending on your app's target API level, using any non-SDK method or field always carries a high risk of breaking your app.
If you are unsure if your app uses non-SDK interfaces, you can test your app to find out. If your app relies on non-SDK interfaces, you should begin planning a migration to SDK alternatives. Nevertheless, we understand that some apps have valid use cases for using non-SDK interfaces. If you can't find an alternative to using a non-SDK interface for a feature in your app, you should request a new public API.
Weitere Informationen zu den Änderungen in dieser Android-Version finden Sie unter Änderungen an den Einschränkungen für nicht SDK-spezifische Oberflächen in Android 15. Weitere Informationen zu Nicht-SDK-Schnittstellen finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen.