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
我们将对 Android 15 中的前台服务进行以下更改。
数据同步前台服务超时行为
Android 15 memperkenalkan perilaku waktu tunggu baru ke dataSync
untuk aplikasi yang menargetkan
Android 15 (API level 35) atau yang lebih tinggi. Perilaku ini juga berlaku untuk
jenis layanan latar depan mediaProcessing
baru.
Sistem mengizinkan layanan dataSync
aplikasi berjalan selama total 6 jam
dalam periode 24 jam, setelah itu sistem akan memanggil metode
Service.onTimeout(int, int)
layanan yang berjalan (diperkenalkan di Android
15). Saat ini, layanan memiliki waktu beberapa detik untuk memanggil
Service.stopSelf()
. Saat Service.onTimeout()
dipanggil, layanan tidak lagi dianggap sebagai layanan latar depan. Jika layanan tidak
memanggil Service.stopSelf()
, sistem akan menampilkan pengecualian internal. Pengecualian
akan dicatat ke dalam log di Logcat dengan pesan berikut:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
Untuk menghindari masalah terkait perubahan perilaku ini, Anda dapat melakukan satu atau beberapa hal berikut:
- Minta layanan Anda menerapkan metode
Service.onTimeout(int, int)
baru. Saat aplikasi Anda menerima callback, pastikan untuk memanggilstopSelf()
dalam beberapa detik. (Jika Anda tidak segera menghentikan aplikasi, sistem akan menghasilkan kegagalan.) - Pastikan layanan
dataSync
aplikasi Anda tidak berjalan selama lebih dari 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer). - Hanya mulai layanan latar depan
dataSync
sebagai hasil dari interaksi pengguna langsung; karena aplikasi Anda berada di latar depan saat layanan dimulai, layanan Anda memiliki waktu enam jam penuh setelah aplikasi beralih ke latar belakang. - Sebagai ganti menggunakan layanan latar depan
dataSync
, gunakan API alternatif.
Jika layanan latar depan dataSync
aplikasi Anda telah berjalan selama 6 jam dalam 24
jam terakhir, Anda tidak dapat memulai layanan latar depan dataSync
lain kecuali pengguna
telah memindahkan aplikasi Anda ke latar depan (yang mereset timer). Jika Anda mencoba
memulai layanan latar depan dataSync
lainnya, sistem akan menampilkan
ForegroundServiceStartNotAllowedException
dengan pesan error seperti "Batas waktu sudah habis untuk jenis layanan latar depan
dataSync".
Pengujian
Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan waktu tunggu sinkronisasi data meskipun aplikasi
tidak menargetkan Android 15 (asalkan aplikasi berjalan di perangkat
Android 15). Untuk mengaktifkan waktu tunggu, jalankan perintah adb
berikut:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
Anda juga dapat menyesuaikan periode waktu tunggu untuk mempermudah pengujian perilaku
aplikasi saat batas tercapai. Untuk menetapkan periode waktu tunggu baru, jalankan perintah adb
berikut:
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
广播接收器的限制
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
在应用拥有 SYSTEM_ALERT_WINDOW
权限时启动前台服务的限制
以前,如果应用拥有 SYSTEM_ALERT_WINDOW
权限,即使应用当前在后台运行,也可以启动前台服务(如免于后台启动限制中所述)。
如果应用以 Android 15 为目标平台,则此豁免范围现在更窄。现在,应用需要具有 SYSTEM_ALERT_WINDOW
权限,并且还需要有一个可见的叠加窗口。也就是说,应用需要先启动 TYPE_APPLICATION_OVERLAY
窗口,并且该窗口需要处于可见状态,然后您才能启动前台服务。
如果您的应用尝试从后台启动前台服务,但不符合这些新要求(并且没有其他豁免情况),系统会抛出 ForegroundServiceStartNotAllowedException
。
如果您的应用声明了 SYSTEM_ALERT_WINDOW
权限并从后台启动前台服务,则可能会受到此变更的影响。如果您的应用获得了 ForegroundServiceStartNotAllowedException
,请检查应用的操作顺序,并确保应用在尝试从后台启动前台服务之前已具有有效的叠加层窗口。您可以通过调用 View.getWindowVisibility()
检查叠加层窗口当前是否可见,也可以替换 View.onWindowVisibilityChanged()
,以便在可见性发生变化时收到通知。
测试
如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。如需针对从后台启动前台服务启用这些新限制,请运行以下 adb
命令:
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 限制了对 TLS 版本 1.0 和 1.1 的使用。这些版本之前已在 Android 中被弃用,但现在不允许面向 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
Aplikasi ditampilkan dalam layar penuh secara default di perangkat yang menjalankan Android 15 jika aplikasi menargetkan Android 15 (level API 35).

Ini adalah perubahan yang dapat menyebabkan gangguan dan berdampak negatif pada UI aplikasi Anda. Perubahan memengaruhi area UI berikut:
- Menu navigasi tuas gestur
- Transparan secara default.
- Offset bawah dinonaktifkan sehingga konten digambar di belakang kolom navigasi sistem, kecuali jika inset diterapkan.
setNavigationBarColor
danR.attr#navigationBarColor
tidak digunakan lagi dan tidak memengaruhi navigasi gestur.setNavigationBarContrastEnforced
danR.attr#navigationBarContrastEnforced
tetap tidak berpengaruh pada navigasi gestur.
- Navigasi 3 tombol
- Opasitas ditetapkan ke 80% secara default, dengan warna yang mungkin cocok dengan latar belakang jendela.
- Offset bawah dinonaktifkan sehingga konten digambar di belakang menu navigasi sistem kecuali jika inset diterapkan.
setNavigationBarColor
danR.attr#navigationBarColor
ditetapkan agar sesuai dengan latar belakang jendela secara default. Latar belakang jendela harus berupa drawable warna agar default ini diterapkan. API ini sudah tidak digunakan lagi, tetapi terus memengaruhi navigasi 3 tombol.setNavigationBarContrastEnforced
danR.attr#navigationBarContrastEnforced
bernilai benar secara default, yang menambahkan latar belakang buram 80% di seluruh navigasi 3 tombol.
- Status bar
- Transparan secara default.
- Offset atas dinonaktifkan sehingga konten digambar di belakang status bar kecuali jika inset diterapkan.
setStatusBarColor
danR.attr#statusBarColor
tidak digunakan lagi dan tidak berpengaruh pada Android 15.setStatusBarContrastEnforced
danR.attr#statusBarContrastEnforced
tidak digunakan lagi, tetapi masih memiliki efek pada Android 15.
- Potongan layar
layoutInDisplayCutoutMode
jendela non-floating harus berupaLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.SHORT_EDGES
,NEVER
, danDEFAULT
ditafsirkan sebagaiALWAYS
sehingga pengguna tidak melihat batang hitam yang disebabkan oleh potongan layar dan muncul di layar penuh.
Contoh berikut menunjukkan aplikasi sebelum dan sesudah menargetkan Android 15 (level API 35), serta sebelum dan sesudah menerapkan inset. Contoh ini tidak lengkap, dan mungkin akan terlihat berbeda di Android Auto.



Yang perlu diperiksa jika aplikasi Anda sudah ditampilkan di layar penuh
Jika aplikasi Anda sudah ditampilkan layar penuh dan menerapkan inset, Anda sebagian besar tidak terpengaruh, kecuali dalam skenario berikut. Namun, meskipun Anda merasa tidak terpengaruh, sebaiknya Anda menguji aplikasi Anda.
- Anda memiliki jendela non-mengambang, seperti
Activity
yang menggunakanSHORT_EDGES
,NEVER
, atauDEFAULT
, bukanLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. Jika aplikasi Anda error saat diluncurkan, penyebabnya mungkin adalah layar pembuka. Anda dapat mengupgrade dependensi layar pembuka inti ke 1.2.0-alpha01 atau yang lebih baru atau menetapkanwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Mungkin ada layar dengan traffic lebih rendah dengan UI yang tertutup. Pastikan layar yang jarang dikunjungi ini tidak memiliki UI yang tertutup. Layar dengan traffic lebih rendah mencakup:
- Layar aktivasi atau login
- Halaman setelan
Yang harus diperiksa jika aplikasi Anda belum ditampilkan di layar penuh
Jika aplikasi Anda belum ditampilkan dalam layar penuh, kemungkinan besar Anda akan terpengaruh. Selain skenario untuk aplikasi yang sudah ditampilkan di layar penuh, Anda harus mempertimbangkan hal berikut:
- Jika aplikasi Anda menggunakan Komponen Material 3 (
androidx.compose.material3
) di Compose, sepertiTopAppBar
,BottomAppBar
, danNavigationBar
, komponen ini kemungkinan tidak terpengaruh karena otomatis menangani inset. - Jika aplikasi Anda menggunakan Komponen Material 2 (
androidx.compose.material
) di Compose, komponen ini tidak otomatis menangani inset. Namun, Anda dapat memperoleh akses ke inset dan menerapkannya secara manual. Di androidx.compose.material 1.6.0 dan yang lebih baru, gunakan parameterwindowInsets
untuk menerapkan inset secara manual bagiBottomAppBar
,TopAppBar
,BottomNavigation
, danNavigationRail
. Demikian pula, gunakan parametercontentWindowInsets
untukScaffold
. - Jika aplikasi Anda menggunakan tampilan dan Komponen Material
(
com.google.android.material
), sebagian besar Komponen Material berbasis tampilan sepertiBottomNavigationView
,BottomAppBar
,NavigationRailView
, atauNavigationView
, menangani inset dan tidak memerlukan pekerjaan tambahan. Namun, Anda perlu menambahkanandroid:fitsSystemWindows="true"
jika menggunakanAppBarLayout
. - Untuk composable kustom, terapkan inset secara manual sebagai padding. Jika konten Anda berada dalam
Scaffold
, Anda dapat menggunakan inset dengan nilai paddingScaffold
. Jika tidak, terapkan padding menggunakan salah satuWindowInsets
. - Jika aplikasi Anda menggunakan tampilan dan
BottomSheet
,SideSheet
, atau kontainer kustom, terapkan padding menggunakanViewCompat.setOnApplyWindowInsetsListener
. UntukRecyclerView
, terapkan padding menggunakan pemroses ini dan juga tambahkanclipToPadding="false"
.
Yang harus diperiksa jika aplikasi Anda harus menawarkan perlindungan latar belakang kustom
Jika aplikasi Anda harus menawarkan perlindungan latar belakang kustom untuk navigasi 3 tombol atau status bar, aplikasi Anda harus menempatkan composable atau tampilan di belakang kolom sistem menggunakan WindowInsets.Type#tappableElement()
untuk mendapatkan tinggi kolom navigasi 3 tombol atau WindowInsets.Type#statusBars
.
Referensi layar penuh tambahan
Lihat panduan Tampilan Layar Penuh dan Compose Layar Penuh untuk pertimbangan tambahan tentang penerapan inset.
API yang tidak digunakan lagi
API berikut tidak digunakan lagi, tetapi tidak dinonaktifkan:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
(untuk navigasi 3 tombol, dengan alfa 80%)Window#isStatusBarContrastEnforced
Window#setNavigationBarColor
(untuk navigasi 3 tombol, dengan alpha 80%)Window#setStatusBarContrastEnforced
API berikut tidak digunakan lagi dan dinonaktifkan:
R.attr#navigationBarColor
(untuk navigasi gestur)R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#setDecorFitsSystemWindows
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#setNavigationBarColor
(untuk navigasi gestur)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
在以前的 Android 版本中,某些具有复杂形状的手写字体或语言可能会在上一个或下一个字符的区域绘制字母。在某些情况下,此类字母会在开头或结尾处被剪裁。从 Android 15 开始,TextView
会分配宽度,以便为此类字母绘制足够的空间,并允许应用请求向左额外添加内边距以防止剪裁。
由于此更改会影响 TextView
确定宽度的方式,因此如果应用以 Android 15(API 级别 35)或更高版本为目标平台,TextView
会默认分配更多宽度。您可以通过对 TextView
调用 setUseBoundsForWidth
API 来启用或停用此行为。
由于添加左内边距可能会导致现有布局未对齐,因此默认情况下不会添加内边距,即使以 Android 15 或更高版本为目标平台的应用也是如此。不过,您可以通过调用 setShiftDrawingOffsetForStartOverhang
添加额外的内边距以防止剪裁。
以下示例展示了这些更改如何改进某些字体和语言的文本布局。

<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.