Seperti rilis sebelumnya, Android 15 menyertakan perubahan perilaku yang mungkin memengaruhi aplikasi Anda. Perubahan perilaku berikut ini berlaku khusus bagi aplikasi yang menargetkan Android 15 atau yang lebih tinggi. Jika aplikasi Anda menargetkan Android 15 atau yang lebih tinggi, Anda harus memodifikasi aplikasi untuk mendukung perilaku ini dengan benar, jika berlaku.
Pastikan Anda juga meninjau daftar perubahan perilaku yang memengaruhi semua aplikasi yang berjalan di Android 15, terlepas dari targetSdkVersion
aplikasi Anda.
Fungsi inti
Android 15 mengubah atau memperluas berbagai kemampuan inti sistem Android.
Perubahan pada layanan latar depan
Kami melakukan perubahan berikut pada layanan latar depan dengan Android 15.
- Perilaku waktu tunggu layanan latar depan sinkronisasi data
- Jenis layanan latar depan pemrosesan media baru
- Pembatasan pada penerima siaran
BOOT_COMPLETED
yang meluncurkan layanan latar depan - Pembatasan untuk memulai layanan latar depan saat aplikasi memiliki izin
SYSTEM_ALERT_WINDOW
Perilaku waktu tunggu layanan latar depan sinkronisasi data
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
Jenis layanan latar depan pemrosesan media baru
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
Pembatasan pada penerima siaran BOOT_COMPLETED
yang meluncurkan layanan latar depan
Ada batasan baru pada penerima siaran BOOT_COMPLETED
yang meluncurkan
layanan latar depan. Penerima BOOT_COMPLETED
tidak diizinkan untuk meluncurkan
jenis layanan latar depan berikut:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(pembatasan ini telah diterapkan selamamicrophone
sejak Android 14)
Jika penerima BOOT_COMPLETED
mencoba meluncurkan salah satu jenis layanan latar depan
tersebut, sistem akan menampilkan ForegroundServiceStartNotAllowedException
.
Pengujian
Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan pembatasan baru ini bahkan jika
aplikasi tidak menargetkan Android 15 (selama aplikasi tersebut berjalan di Android 15
perangkat). Jalankan perintah adb
berikut:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
Untuk mengirim siaran BOOT_COMPLETED
tanpa memulai ulang perangkat,
jalankan perintah adb
berikut:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
Pembatasan untuk memulai layanan latar depan saat aplikasi memiliki izin SYSTEM_ALERT_WINDOW
Sebelumnya, jika memiliki izin SYSTEM_ALERT_WINDOW
, aplikasi dapat meluncurkan
layanan latar depan meskipun aplikasi saat ini berada di latar belakang (seperti
yang dibahas dalam pengecualian dari pembatasan mulai latar belakang).
Jika aplikasi menargetkan Android 15, pengecualian ini kini lebih sempit. Aplikasi kini harus
memiliki izin SYSTEM_ALERT_WINDOW
dan juga memiliki jendela overlay
yang terlihat. Artinya, aplikasi harus meluncurkan
jendela TYPE_APPLICATION_OVERLAY
terlebih dahulu dan jendela
harus terlihat sebelum Anda memulai layanan latar depan.
Jika aplikasi Anda mencoba memulai layanan latar depan dari latar belakang tanpa
memenuhi persyaratan baru ini (dan tidak memiliki pengecualian lain), sistem
akan menampilkan ForegroundServiceStartNotAllowedException
.
Jika aplikasi Anda mendeklarasikan izin SYSTEM_ALERT_WINDOW
dan meluncurkan layanan latar depan dari latar belakang, aplikasi tersebut mungkin akan terpengaruh oleh
perubahan ini. Jika aplikasi Anda mendapatkan ForegroundServiceStartNotAllowedException
, periksa
urutan operasi aplikasi dan pastikan aplikasi Anda sudah memiliki jendela
overlay yang aktif sebelum mencoba memulai layanan latar depan dari
latar belakang. Anda dapat memeriksa apakah jendela overlay saat ini terlihat
dengan memanggil View.getWindowVisibility()
, atau Anda
dapat mengganti View.onWindowVisibilityChanged()
untuk mendapatkan notifikasi setiap kali visibilitas berubah.
Pengujian
Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan pembatasan baru ini meskipun
aplikasi tidak menargetkan Android 15 (selama aplikasi berjalan di perangkat
Android 15). Untuk mengaktifkan pembatasan baru ini saat memulai layanan latar depan
dari latar belakang, jalankan perintah adb
berikut:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
Perubahan pada waktu aplikasi dapat mengubah status global mode Jangan Ganggu
Aplikasi yang menargetkan Android 15 (API level 35) dan yang lebih tinggi tidak dapat lagi mengubah
status atau kebijakan global Jangan Ganggu (DND) di perangkat (baik dengan mengubah
setelan pengguna, atau menonaktifkan mode DND). Sebagai gantinya, aplikasi harus berkontribusi pada
AutomaticZenRule
, yang digabungkan sistem menjadi kebijakan global dengan
skema kebijakan paling ketat yang ada. Panggilan ke API yang ada yang
sebelumnya memengaruhi status global (setInterruptionFilter
,
setNotificationPolicy
) menghasilkan pembuatan atau pembaruan AutomaticZenRule
implisit, yang diaktifkan dan dinonaktifkan bergantung pada siklus panggilan
panggilan API tersebut.
Perhatikan bahwa perubahan ini hanya memengaruhi perilaku yang dapat diamati jika aplikasi memanggil
setInterruptionFilter(INTERRUPTION_FILTER_ALL)
dan mengharapkan panggilan tersebut untuk
menonaktifkan AutomaticZenRule
yang sebelumnya diaktifkan oleh pemiliknya.
Perubahan API OpenJDK
Android 15 melanjutkan pekerjaan memuat ulang library inti Android agar selaras dengan fitur dalam rilis OpenJDK LTS terbaru.
Beberapa perubahan ini dapat memengaruhi kompatibilitas aplikasi yang menargetkan Android 15 (level API 35):
Perubahan pada API pemformatan string: Validasi indeks argumen, flag, lebar, dan presisi kini lebih ketat saat menggunakan API
String.format()
danFormatter.format()
berikut:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
Misalnya, pengecualian berikut terjadi saat indeks argumen 0 digunakan (
%0
dalam string format):IllegalFormatArgumentIndexException: Illegal format argument index = 0
Dalam hal ini, masalah dapat diperbaiki dengan menggunakan indeks argumen 1 (
%1
dalam string format).Perubahan pada jenis komponen
Arrays.asList(...).toArray()
: Saat menggunakanArrays.asList(...).toArray()
, jenis komponen array yang dihasilkan sekarang adalahObject
—bukan jenis elemen array yang mendasarinya. Jadi, kode berikut akan memunculkanClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
Untuk kasus ini, guna mempertahankan
String
sebagai jenis komponen dalam array yang dihasilkan, Anda dapat menggunakanCollection.toArray(Object[])
:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
Perubahan pada penanganan kode bahasa: Saat menggunakan
Locale
API, kode bahasa untuk Ibrani, Yiddish, dan Indonesia tidak lagi dikonversi ke bentuknya yang sudah tidak digunakan (Ibrani:iw
, Yiddish:ji
, dan Indonesia:in
). Saat menentukan kode bahasa untuk salah satu lokalitas ini, gunakan kode dari ISO 639-1 (Ibrani:he
, Yiddish:yi
, dan Indonesia:id
).Perubahan pada urutan bilangan bulat acak: Setelah perubahan yang dilakukan di https://bugs.openjdk.org/browse/JDK-8301574, metode
Random.ints()
berikut kini menampilkan urutan angka yang berbeda dengan metodeRandom.nextInt()
:Umumnya, perubahan ini tidak akan menyebabkan perilaku yang merusak aplikasi, tetapi kode Anda tidak boleh mengharapkan urutan yang dihasilkan dari metode
Random.ints()
agar cocok denganRandom.nextInt()
.
API SequencedCollection
baru dapat memengaruhi kompatibilitas aplikasi Anda
setelah Anda mengupdate compileSdk
dalam konfigurasi build aplikasi untuk menggunakan
Android 15 (level API 35):
Konflik dengan fungsi ekstensi
MutableList.removeFirst()
danMutableList.removeLast()
dikotlin-stdlib
Jenis
List
di Java dipetakan ke jenisMutableList
di Kotlin. Karena APIList.removeFirst()
danList.removeLast()
telah diperkenalkan di Android 15 (level API 35), compiler Kotlin menyelesaikan panggilan fungsi, misalnyalist.removeFirst()
, secara statis ke APIList
baru, bukan ke fungsi ekstensi dikotlin-stdlib
.Jika aplikasi dikompilasi ulang dengan
compileSdk
ditetapkan ke35
danminSdk
ditetapkan ke34
atau yang lebih rendah, lalu aplikasi dijalankan di Android 14 dan yang lebih rendah, error runtime akan terjadi:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
Opsi lint
NewApi
yang ada di Plugin Android Gradle dapat menangkap penggunaan API baru ini../gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()Untuk memperbaiki pengecualian runtime dan error lint, panggilan fungsi
removeFirst()
danremoveLast()
dapat diganti denganremoveAt(0)
danremoveAt(list.lastIndex)
masing-masing di Kotlin. Jika Anda menggunakan Android Studio Ladybug | 2024.1.3 atau yang lebih tinggi, opsi perbaikan cepat untuk error ini juga tersedia.Pertimbangkan untuk menghapus
@SuppressLint("NewApi")
danlintOptions { disable 'NewApi' }
jika opsi lint telah dinonaktifkan.Konflik dengan metode lain di Java
Metode baru telah ditambahkan ke jenis yang ada, misalnya,
List
danDeque
. Metode baru ini mungkin tidak kompatibel dengan metode yang memiliki nama dan jenis argumen yang sama di antarmuka dan class lainnya. Jika terjadi tabrakan tanda tangan metode dengan ketidakcocokan, compilerjavac
akan menghasilkan error waktu build. Contoh:Contoh 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 ListContoh 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 errorContoh 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 errorUntuk memperbaiki error build ini, class yang mengimplementasikan antarmuka ini harus mengganti metode dengan jenis nilai yang ditampilkan yang kompatibel. Contoh:
@Override public Object getFirst() { return List.super.getFirst(); }
Keamanan
Android 15 menyertakan perubahan yang meningkatkan keamanan sistem untuk membantu melindungi aplikasi dan pengguna dari aplikasi berbahaya.
Versi TLS yang dibatasi
Android 15 membatasi penggunaan TLS versi 1.0 dan 1.1. Versi ini sebelumnya tidak digunakan lagi di Android, tetapi sekarang tidak diizinkan untuk aplikasi yang menargetkan Android 15.
Peluncuran aktivitas latar belakang yang diamankan
Android 15 melindungi pengguna dari aplikasi berbahaya dan memberi mereka kontrol lebih besar terhadap perangkat dengan menambahkan perubahan yang mencegah aplikasi latar belakang berbahaya membawa aplikasi lain ke latar depan, meningkatkan hak istimewanya, dan menyalahgunakan interaksi pengguna. Peluncuran aktivitas latar belakang dibatasi sejak Android 10 (level API 29).
Perubahan lainnya
Selain batasan untuk pencocokan UID, perubahan lain ini juga disertakan:
- Mengubah pembuat
PendingIntent
untuk memblokir peluncuran aktivitas latar belakang secara default. Hal ini membantu mencegah aplikasi secara tidak sengaja membuatPendingIntent
yang dapat disalahgunakan oleh pelaku kejahatan. - Jangan tampilkan aplikasi ke latar depan kecuali jika pengirim
PendingIntent
mengizinkannya. Perubahan ini bertujuan untuk mencegah aplikasi berbahaya menyalahgunakan kemampuan untuk memulai aktivitas di latar belakang. Secara default, aplikasi tidak diizinkan untuk memindahkan stack tugas ke latar depan kecuali jika kreator mengizinkan hak istimewa peluncuran aktivitas latar belakang atau pengirim memiliki aktivitas latar belakang hak istimewa peluncuran. - Kontrol cara aktivitas teratas tumpukan tugas dapat menyelesaikan tugasnya. Jika aktivitas teratas menyelesaikan tugas, Android akan kembali ke tugas mana pun yang terakhir aktif. Selain itu, jika aktivitas non-top menyelesaikan tugasnya, Android akan kembali ke layar utama; Android tidak akan memblokir penyelesaian aktivitas non-top ini.
- Cegah peluncuran aktivitas arbitrer dari aplikasi lain ke dalam tugas Anda sendiri. Perubahan ini mencegah aplikasi berbahaya melakukan phishing pengguna dengan membuat aktivitas yang tampaknya berasal dari aplikasi lain.
- Memblokir jendela yang tidak terlihat agar tidak dipertimbangkan untuk aktivitas latar belakang peluncuran. Tindakan ini membantu mencegah aplikasi berbahaya menyalahgunakan latar belakang peluncuran aktivitas untuk menampilkan konten yang tidak diinginkan atau berbahaya kepada pengguna.
Intent yang lebih aman
Android 15 memperkenalkan langkah keamanan opsional baru untuk membuat intent lebih aman dan lebih tangguh. Perubahan ini bertujuan untuk mencegah potensi kerentanan dan penyalahgunaan intent yang dapat dieksploitasi oleh aplikasi berbahaya. Ada dua peningkatan utama pada keamanan intent di Android 15:
- Mencocokkan filter intent target: Intent yang menargetkan komponen tertentu harus sesuai dengan spesifikasi filter intent target secara akurat. Jika Anda mengirim intent untuk meluncurkan aktivitas aplikasi lain, komponen intent target harus selaras dengan filter intent yang dideklarasikan aktivitas penerima.
- Intent harus memiliki tindakan: Intent tanpa tindakan tidak akan cocok lagi filter intent apa pun. Ini berarti intent yang digunakan untuk memulai aktivitas atau layanan harus memiliki tindakan yang didefinisikan dengan jelas.
Untuk memeriksa bagaimana aplikasi Anda merespons perubahan ini, gunakan
StrictMode
di aplikasi Anda. Untuk melihat detail
log tentang pelanggaran penggunaan Intent
, tambahkan metode berikut:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
Pengalaman pengguna dan UI sistem
Android 15 menyertakan beberapa perubahan yang dimaksudkan untuk menciptakan pengalaman pengguna yang lebih konsisten dan intuitif.
Perubahan inset jendela
Ada dua perubahan yang terkait dengan inset jendela di Android 15: edge-to-edge diberlakukan secara default, dan ada juga perubahan konfigurasi, seperti konfigurasi default panel sistem.
Penerapan menyeluruh
如果应用以 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
(适用于三按钮导航,透明度为 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
Konfigurasi stabil
Jika aplikasi Anda menargetkan Android 15 (level API 35) atau yang lebih tinggi, Configuration
tidak
lagi mengecualikan kolom sistem. Jika Anda menggunakan ukuran layar di class
Configuration
untuk penghitungan tata letak, Anda harus menggantinya dengan alternatif
yang lebih baik seperti ViewGroup
, WindowInsets
, atau
WindowMetricsCalculator
yang sesuai, bergantung pada kebutuhan Anda.
Configuration
telah tersedia sejak API 1. Biasanya diperoleh dari
Activity.onConfigurationChanged
. Laporan ini memberikan informasi seperti kepadatan jendela,
orientasi, dan ukuran. Salah satu karakteristik penting tentang ukuran jendela yang ditampilkan dari Configuration
adalah bahwa sebelumnya ukuran tersebut tidak menyertakan kolom sistem.
Ukuran konfigurasi biasanya digunakan untuk pemilihan resource, seperti
/res/layout-h500dp
, dan ini masih merupakan kasus penggunaan yang valid. Namun, penggunaannya untuk
penghitungan tata letak selalu tidak disarankan. Jika Anda melakukannya, Anda harus menjauh dari perangkat tersebut sekarang. Anda harus mengganti penggunaan Configuration
dengan sesuatu yang lebih sesuai, bergantung pada kasus penggunaan Anda.
Jika Anda menggunakannya untuk menghitung tata letak, gunakan ViewGroup
yang sesuai, seperti
CoordinatorLayout
atau ConstraintLayout
. Jika Anda menggunakannya untuk menentukan tinggi navbar sistem, gunakan WindowInsets
. Jika Anda ingin mengetahui ukuran jendela aplikasi saat ini, gunakan computeCurrentWindowMetrics
.
Daftar berikut menjelaskan kolom yang terpengaruh oleh perubahan ini:
- Ukuran
Configuration.screenWidthDp
danscreenHeightDp
tidak lagi mengecualikan kolom sistem. Configuration.smallestScreenWidthDp
dipengaruhi secara tidak langsung oleh perubahan padascreenWidthDp
danscreenHeightDp
.Configuration.orientation
secara tidak langsung terpengaruh oleh perubahan padascreenWidthDp
danscreenHeightDp
di perangkat yang hampir persegi.Display.getSize(Point)
secara tidak langsung terpengaruh oleh perubahan diConfiguration
. Hal ini tidak digunakan lagi mulai dari level API 30.Display.getMetrics()
sudah berfungsi seperti ini sejak level API 33.
Atribut elegantTextHeight secara default adalah benar (true)
Untuk aplikasi yang menargetkan Android 15 (API level 35), atribut TextView
elegantTextHeight
menjadi true
secara default, menggantikan font ringkas yang digunakan secara default dengan beberapa
skrip yang memiliki metrik vertikal besar dengan skrip yang jauh lebih mudah dibaca.
Font rapat diperkenalkan untuk mencegah kerusakan tata letak; Android 13 (API
level 33) mencegah banyak kerusakan ini dengan memungkinkan tata letak teks
meregangkan tinggi vertikal menggunakan atribut
fallbackLineSpacing
.
Di Android 15, font ringkas masih ada di sistem, sehingga aplikasi Anda dapat menetapkan
elegantTextHeight
ke false
untuk mendapatkan perilaku yang sama seperti sebelumnya, tetapi kemungkinan
tidak akan didukung dalam rilis mendatang. Jadi, jika aplikasi Anda mendukung
skrip berikut: Arab, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam,
Odia, Telugu, atau Thai, uji aplikasi Anda dengan menetapkan elegantTextHeight
ke true
.

elegantTextHeight
untuk aplikasi yang menargetkan Android 14 (API level 34) dan yang lebih lama.
elegantTextHeight
untuk aplikasi yang menargetkan Android 15.Lebar TextView berubah untuk bentuk huruf yang kompleks
Pada versi Android sebelumnya, beberapa font atau bahasa kursif yang memiliki
bentuk kompleks dapat menggambar huruf di area karakter sebelumnya atau berikutnya.
Dalam beberapa kasus, huruf tersebut dipangkas di posisi awal atau akhir.
Mulai Android 15, TextView
mengalokasikan lebar untuk menggambar ruang yang cukup
untuk huruf tersebut dan memungkinkan aplikasi meminta padding tambahan ke kiri untuk
mencegah pemangkasan.
Karena perubahan ini memengaruhi cara TextView
menentukan lebar, TextView
mengalokasikan lebih banyak lebar secara default jika aplikasi menargetkan Android 15 (level API 35) atau
yang lebih baru. Anda dapat mengaktifkan atau menonaktifkan perilaku ini dengan memanggil
setUseBoundsForWidth
API di TextView
.
Karena menambahkan padding kiri dapat menyebabkan ketidaksejajaran untuk tata letak yang ada, padding
tidak ditambahkan secara default bahkan untuk aplikasi yang menargetkan Android 15 atau yang lebih tinggi.
Namun, Anda dapat menambahkan padding tambahan untuk mencegah pemangkasan dengan memanggil
setShiftDrawingOffsetForStartOverhang
.
Contoh berikut menunjukkan bagaimana perubahan ini dapat meningkatkan tata letak teks untuk beberapa font dan bahasa.

<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" />
Tinggi baris default yang sesuai dengan lokalitas untuk EditText
Pada versi Android sebelumnya, tata letak teks meregangkan tinggi
teks untuk memenuhi tinggi baris font yang cocok dengan lokalitas saat ini. Misalnya, jika konten dalam bahasa Jepang, karena tinggi baris font
Jepang sedikit lebih besar dari font Latin, tinggi teks
menjadi sedikit lebih besar. Namun, meskipun ada perbedaan tinggi baris ini, elemen
EditText
berukuran seragam, terlepas
dari lokalitas yang digunakan, seperti yang diilustrasikan pada gambar berikut:

EditText
yang
dapat berisi teks dari bahasa Inggris (en), Jepang (ja), dan Burma (my). Tinggi
EditText
sama, meskipun bahasa ini
memiliki tinggi baris yang berbeda satu sama lain.Untuk aplikasi yang menargetkan Android 15 (API level 35), tinggi baris minimum kini
disediakan untuk EditText
agar cocok dengan font referensi untuk Lokalitas yang ditentukan, seperti
yang ditunjukkan pada gambar berikut:

EditText
yang
dapat berisi teks dari bahasa Inggris (en), Jepang (ja), dan Burma (my). Tinggi
EditText
kini menyertakan ruang untuk mengakomodasi
tinggi baris default untuk font bahasa ini.Jika diperlukan, aplikasi Anda dapat memulihkan perilaku sebelumnya dengan menentukan
atribut useLocalePreferredLineHeightForMinimum
ke false
, dan aplikasi Anda dapat menetapkan metrik vertikal minimum kustom menggunakan
setMinimumFontMetrics
API di Kotlin dan Java.
Kamera dan media
Android 15 membuat perubahan berikut pada perilaku kamera dan media untuk aplikasi yang menargetkan Android 15 atau yang lebih tinggi.
Batasan untuk meminta fokus audio
Aplikasi yang menargetkan Android 15 (API level 35) harus menjadi aplikasi teratas atau menjalankan
layanan latar depan untuk meminta fokus audio. Jika aplikasi
mencoba meminta fokus saat tidak memenuhi salah satu persyaratan ini, panggilan akan menampilkan AUDIOFOCUS_REQUEST_FAILED
.
Anda dapat mempelajari fokus audio lebih lanjut di Mengelola fokus audio.
Pembatasan non-SDK yang diperbarui
Android 15 menyertakan daftar terbaru antarmuka non-SDK yang dibatasi berdasarkan kolaborasi dengan developer Android dan pengujian internal terbaru. Jika memungkinkan, kami akan memastikan ketersediaan alternatif publik sebelum membatasi antarmuka non-SDK.
Jika aplikasi Anda tidak menargetkan Android 15, beberapa perubahan ini mungkin tidak langsung memengaruhi Anda. Namun, meskipun aplikasi Anda dapat mengakses beberapa antarmuka non-SDK bergantung pada level API target aplikasi Anda, penggunaan metode atau kolom non-SDK apa pun selalu berisiko tinggi merusak aplikasi Anda.
Jika tidak yakin apakah aplikasi Anda menggunakan antarmuka non-SDK atau tidak, Anda dapat menguji aplikasi untuk mencari tahu. Jika aplikasi Anda mengandalkan antarmuka non-SDK, sebaiknya Anda mulai merencanakan migrasi ke alternatif SDK. Namun demikian, kami memahami bahwa beberapa aplikasi memiliki kasus penggunaan yang valid untuk menggunakan antarmuka non-SDK. Jika tidak dapat menemukan alternatif selain menggunakan antarmuka non-SDK untuk fitur dalam aplikasi Anda, sebaiknya minta API publik baru.
Untuk mempelajari perubahan dalam rilis Android ini lebih lanjut, baca Pembaruan pembatasan antarmuka non-SDK di Android 15. Untuk mempelajari lebih lanjut antarmuka non-SDK secara umum, baca Pembatasan antarmuka non-SDK.