Seperti rilis sebelumnya, Android 15 menyertakan perubahan perilaku yang mungkin memengaruhi aplikasi Anda. Perubahan perilaku berikut berlaku secara eksklusif untuk aplikasi yang yang menargetkan Android 15 atau yang lebih tinggi. Jika aplikasi Anda menargetkan Android 15 atau yang lebih tinggi, Anda harus memodifikasi aplikasi agar mendukung perilaku ini dengan benar, di mana berlaku.
Pastikan juga untuk meninjau daftar perubahan perilaku yang memengaruhi semua aplikasi
berjalan di Android 15 terlepas dari targetSdkVersion
aplikasi Anda.
Fungsi inti
Android 15 memodifikasi atau memperluas berbagai kemampuan inti sistem Android.
Perubahan pada layanan latar depan
Kami membuat 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
BOOT_COMPLETED
penerima siaran yang meluncurkan layanan latar depan - Pembatasan dalam memulai layanan latar depan saat aplikasi memiliki izin
SYSTEM_ALERT_WINDOW
Perilaku waktu tunggu layanan latar depan sinkronisasi data
Android 15 memperkenalkan perilaku waktu tunggu baru ke dataSync
untuk penargetan aplikasi
Android 15 (level API 35) atau yang lebih tinggi. Perilaku ini juga berlaku untuk
Jenis layanan latar depan mediaProcessing
.
Sistem mengizinkan layanan dataSync
aplikasi untuk berjalan selama total 6 jam
dalam periode 24 jam, setelah itu sistem akan memanggil metode
Metode Service.onTimeout(int, int)
(diperkenalkan di Android
15.) Pada saat ini, layanan memiliki waktu beberapa detik untuk memanggil
Service.stopSelf()
Saat Service.onTimeout()
dipanggil,
tidak lagi dianggap sebagai layanan latar depan. Jika layanan tidak
memanggil Service.stopSelf()
, sistem akan menampilkan pengecualian internal. Tujuan
dicatat 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 dengan perubahan perilaku ini, Anda dapat melakukan satu atau beberapa berikut ini:
- Minta layanan Anda untuk mengimplementasikan metode
Service.onTimeout(int, int)
baru. Saat aplikasi menerima callback, pastikan untuk memanggilstopSelf()
dalam beberapa detik. (Jika Anda tidak langsung menghentikan aplikasi, sistem akan membuat gagal.) - Pastikan layanan
dataSync
aplikasi Anda tidak berjalan selama total lebih dari 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer). - Hanya memulai layanan latar depan
dataSync
sebagai hasil dari pengguna langsung interaksi; karena aplikasi Anda berada di latar depan saat layanan dimulai, layanan Anda memiliki waktu 6 jam penuh setelah aplikasi berpindah ke latar belakang. - Gunakan layanan latar depan
dataSync
, bukan API alternatif.
Jika layanan latar depan dataSync
aplikasi Anda telah berjalan selama 6 jam terakhir
24, Anda tidak dapat memulai layanan latar depan dataSync
yang lain kecuali jika pengguna
telah membawa aplikasi Anda ke latar depan (yang akan menyetel ulang timer). Jika Anda mencoba
memulai layanan latar depan dataSync
lain, sistem akan menampilkan
ForegroundServiceStartNotAllowedException
dengan pesan error seperti "Batas waktu sudah habis untuk layanan latar depan
"dataSync".
Pengujian
Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan waktu tunggu sinkronisasi data meskipun aplikasi
tidak menargetkan Android 15 (selama aplikasi berjalan di Android 15
perangkat). 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 menguji bagaimana
akan berperilaku saat batas tercapai. Untuk menetapkan periode waktu tunggu yang baru, jalankan
perintah adb
berikut:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
Jenis layanan latar depan pemrosesan media baru
Android 15 memperkenalkan jenis layanan latar depan baru, yaitu mediaProcessing
. Ini
sesuai untuk operasi seperti melakukan transcoding file media. Sebagai
Misalnya, aplikasi media mungkin mengunduh file audio dan perlu mengonversinya ke
berbagai format sebelum memutarnya. Anda dapat menggunakan latar depan mediaProcessing
untuk memastikan konversi berlanjut bahkan saat aplikasi berada di
latar belakang.
Sistem mengizinkan layanan mediaProcessing
aplikasi untuk berjalan selama total 6
jam dalam periode 24 jam, setelah itu sistem akan memanggil layanan yang sedang berjalan
Metode Service.onTimeout(int, int)
(diperkenalkan di Android
15.) Pada saat ini, layanan memiliki waktu beberapa detik untuk memanggil
Service.stopSelf()
Jika layanan tidak
memanggil Service.stopSelf()
, sistem akan menampilkan pengecualian internal. Tujuan
dicatat di Logcat dengan pesan berikut:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
Untuk menghindari pengecualian, Anda dapat melakukan salah satu hal berikut:
- Minta layanan Anda untuk mengimplementasikan metode
Service.onTimeout(int, int)
baru. Saat aplikasi menerima callback, pastikan untuk memanggilstopSelf()
dalam beberapa detik. (Jika Anda tidak langsung menghentikan aplikasi, sistem akan membuat gagal.) - Pastikan layanan
mediaProcessing
aplikasi Anda tidak berjalan selama lebih dari total 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer). - Hanya memulai layanan latar depan
mediaProcessing
sebagai hasil dari pengguna langsung interaksi; karena aplikasi Anda berada di latar depan saat layanan dimulai, layanan Anda memiliki waktu 6 jam penuh setelah aplikasi berpindah ke latar belakang. - Gunakan alternatif, bukan menggunakan layanan latar depan
mediaProcessing
, API, seperti WorkManager.
Jika layanan latar depan mediaProcessing
aplikasi Anda telah berjalan selama 6 jam di
24 terakhir, Anda tidak dapat memulai layanan latar depan mediaProcessing
lainnya kecuali jika
pengguna membawa aplikasi Anda ke latar depan (yang akan mereset timer). Jika Anda
mencoba memulai layanan latar depan mediaProcessing
lain, sistem akan menampilkan
ForegroundServiceStartNotAllowedException
dengan pesan error seperti "Batas waktu sudah habis untuk layanan latar depan
jenis mediaProcessing".
Untuk informasi selengkapnya tentang jenis layanan mediaProcessing
, lihat Perubahan pada
jenis layanan latar depan untuk Android 15: Pemrosesan media.
Pengujian
Untuk menguji perilaku aplikasi, Anda bisa mengaktifkan
waktu tunggu pemrosesan media meskipun
aplikasi Anda tidak menargetkan Android 15 (selama aplikasi tersebut 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 menguji bagaimana
akan berperilaku saat batas tercapai. Untuk menetapkan periode waktu tunggu yang baru, jalankan
perintah adb
berikut:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
Pembatasan pada BOOT_COMPLETED
penerima siaran 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 dalam memulai layanan latar depan saat aplikasi memiliki izin SYSTEM_ALERT_WINDOW
Sebelumnya, jika aplikasi memiliki izin SYSTEM_ALERT_WINDOW
, aplikasi dapat diluncurkan
layanan latar depan meskipun aplikasi saat ini berada di latar belakang (seperti
yang dibahas dalam pengecualian dari pembatasan memulai di latar belakang).
Jika aplikasi menargetkan Android 15, pengecualian ini sekarang dipersempit. Aplikasi sekarang membutuhkan
untuk memiliki izin SYSTEM_ALERT_WINDOW
dan juga memiliki overlay yang terlihat
jendela. Artinya, aplikasi harus terlebih dahulu meluncurkan
TYPE_APPLICATION_OVERLAY
jendela 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 beberapa pengecualian lainnya),
sistem akan menampilkan ForegroundServiceStartNotAllowedException
.
Jika aplikasi Anda mendeklarasikan izin SYSTEM_ALERT_WINDOW
dan meluncurkan layanan latar depan dari latar belakang. Ini mungkin terpengaruh oleh
berubah. Jika aplikasi Anda mendapatkan ForegroundServiceStartNotAllowedException
, periksa
urutan operasi aplikasi dan memastikan aplikasi Anda sudah memiliki
overlay 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 bahkan jika
aplikasi tidak menargetkan Android 15 (selama aplikasi tersebut berjalan di Android 15
perangkat). Untuk mengaktifkan batasan 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 terkait waktu aplikasi dapat mengubah status global mode Jangan Ganggu
Aplikasi yang menargetkan Android 15 tidak dapat lagi mengubah status global atau kebijakan
Jangan Ganggu (DND) di perangkat (baik dengan mengubah setelan pengguna atau menonaktifkan
mode DND). Sebagai gantinya, aplikasi harus memberikan kontribusi AutomaticZenRule
, yang
digabungkan oleh sistem ke dalam kebijakan global dengan skema
yang paling ketat-kebijakan-kemenangan yang sudah ada. Panggilan ke API yang ada dan sebelumnya
memengaruhi status global (setInterruptionFilter
,
setNotificationPolicy
) menyebabkan pembuatan atau pembaruan
AutomaticZenRule
implisit, yang diaktifkan dan dinonaktifkan bergantung pada
siklus panggilan panggilan API tersebut.
Perlu diperhatikan bahwa perubahan ini hanya memengaruhi perilaku yang dapat diamati jika aplikasi memanggil
setInterruptionFilter(INTERRUPTION_FILTER_ALL)
dan mengharapkan panggilan tersebut
menonaktifkan AutomaticZenRule
yang sebelumnya diaktifkan oleh pemiliknya.
Perubahan OpenJDK API
Android 15 melanjutkan pekerjaan memuat ulang library inti Android untuk menyelaraskan dengan fitur dalam rilis terbaru OpenJDK LTS.
Beberapa perubahan ini dapat memengaruhi kompatibilitas aplikasi untuk penargetan aplikasi Android 15 (level API 35):
Perubahan pada API pemformatan string: Validasi indeks argumen, flag, lebar, dan presisi sekarang lebih ketat saat menggunakan API
String.format()
danFormatter.format()
:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
Misalnya, pengecualian berikut ditampilkan saat indeks argumen 0 digunakan (
%0
dalam string format):IllegalFormatArgumentIndexException: Illegal format argument index = 0
Dalam kasus ini, masalah dapat diperbaiki menggunakan indeks argumen 1 (
%1
di string format).Perubahan pada jenis komponen
Arrays.asList(...).toArray()
: Saat menggunakanArrays.asList(...).toArray()
, jenis komponen array yang dihasilkan adalah sekarangObject
—bukan jenis elemen array yang mendasarinya. Jadi, kode berikut akan menampilkanClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
Untuk hal ini, pertahankan
String
sebagai jenis komponen dalam hasil Anda dapat menggunakanCollection.toArray(Object[])
sebagai gantinya:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
Perubahan pada penanganan kode bahasa: Saat menggunakan
Locale
API, kode bahasa untuk bahasa Ibrani, Yiddi, dan Indonesia tidak lagi dikonversi ke bentuk yang sudah tidak berlaku (Ibrani:iw
, Yiddi:ji
, dan bahasa Indonesia:in
). Ketika menetapkan kode bahasa untuk salah satu lokal ini, gunakan kode tersebut dari ISO 639-1 (Ibrani:he
, Yiddi:yi
, dan Bahasa Indonesia:id
).Perubahan pada urutan int acak: Mengikuti perubahan yang dibuat di https://bugs.openjdk.org/browse/JDK-8301574, berikut Metode
Random.ints()
sekarang menampilkan urutan angka yang berbeda dari metodeRandom.nextInt()
melakukan:Umumnya, perubahan ini seharusnya tidak menyebabkan perilaku yang merusak aplikasi, tetapi kode seharusnya tidak mengharapkan urutan yang dihasilkan dari metode
Random.ints()
cocok denganRandom.nextInt()
.
SequencedCollection
API baru dapat memengaruhi kompatibilitas aplikasi Anda
setelah Anda mengupdate compileSdk
dalam konfigurasi build aplikasi Anda untuk menggunakan
Android 15 (level API 35):
Bertumbukan dengan
MutableList.removeFirst()
dan Fungsi ekstensiMutableList.removeLast()
dikotlin-stdlib
Jenis
List
di Java dipetakan ke jenisMutableList
di Kotlin. Karena APIList.removeFirst()
danList.removeLast()
diperkenalkan di Android 15 (API level 35), compiler Kotlin me-resolve panggilan fungsi, misalnyalist.removeFirst()
, secara statis keList
API baru, bukan fungsi ekstensi dikotlin-stdlib
.Jika aplikasi dikompilasi ulang dengan
compileSdk
disetel ke35
danminSdk
disetel ke34
atau lebih rendah, lalu aplikasi berjalan di Android 14 dan yang lebih rendah, runtime ditampilkan kesalahan: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../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,
removeFirst()
dan Panggilan fungsiremoveLast()
dapat diganti denganremoveAt(0)
danremoveAt(list.lastIndex)
masing-masing di Kotlin. Jika Anda menggunakan Kepik Android Studio | 2024.1.3 atau yang lebih tinggi, ini juga memberikan perbaikan cepat untuk pesan error ini.Sebaiknya hapus
@SuppressLint("NewApi")
danlintOptions { disable 'NewApi' }
jika opsi lint telah dinonaktifkan.Tabrakan dengan metode lain di Java
Metode baru telah ditambahkan ke dalam jenis yang ada, misalnya,
List
danDeque
. Metode baru ini mungkin tidak kompatibel dengan metode dengan nama dan jenis argumen yang sama di antarmuka lain dan class. Dalam kasus tabrakan tanda tangan metode dengan inkompatibilitas, 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.getLast(); }
Keamanan
Android 15 menyertakan perubahan yang mempromosikan keamanan sistem untuk membantu melindungi aplikasi dan pengguna dari aplikasi berbahaya.
Peluncuran aktivitas latar belakang yang aman
Android 15 melindungi pengguna dari aplikasi berbahaya dan memberi pengguna kontrol yang lebih besar perangkat mereka 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).
Blokir aplikasi yang tidak cocok dengan UID teratas pada tumpukan agar tidak meluncurkan aktivitas
Aplikasi berbahaya bisa meluncurkan aktivitas aplikasi lain dalam tugas yang sama, lalu
menempatkan diri di atasnya, menciptakan ilusi sebagai aplikasi. "Tugas ini
pembajakan" serangan menghindari pembatasan peluncuran
di latar belakang saat ini karena semuanya
muncul dalam tugas terlihat yang sama. Untuk memitigasi risiko ini, Android 15 menambahkan
penanda yang memblokir aplikasi yang tidak cocok dengan UID teratas pada tumpukan agar tidak diluncurkan
aktivitas Anda. Untuk ikut serta dalam semua aktivitas aplikasi Anda, perbarui
allowCrossUidActivitySwitchFromBelow
di file AndroidManifest.xml
aplikasi Anda:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
Langkah-langkah keamanan baru akan aktif jika semua hal berikut terpenuhi:
- Aplikasi yang melakukan peluncuran menargetkan Android 15.
- Aplikasi di atas tumpukan tugas menargetkan Android 15.
- Semua aktivitas yang terlihat telah diikutsertakan ke perlindungan baru
Jika langkah-langkah keamanan diaktifkan, aplikasi mungkin akan dikembalikan ke beranda, bukan aplikasi yang terakhir terlihat, jika mereka menyelesaikan tugas mereka sendiri.
Perubahan lainnya
Selain pembatasan untuk pencocokan UID, perubahan lain ini juga termasuk:
- Ubah
PendingIntent
kreator untuk memblokir peluncuran aktivitas latar belakang dengan default. Hal ini membantu mencegah aplikasi secara tidak sengaja membuatPendingIntent
yang dapat disalahgunakan oleh pelaku kejahatan. - Jangan memindahkan 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 yang 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 beranda; itu tidak akan memblokir penyelesaian non-top ini aktivitas Anda.
- Mencegah peluncuran aktivitas arbitrer dari aplikasi lain ke aplikasi Anda sendiri tugas. 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 baru untuk membuat intent lebih aman dan lebih banyak lagi andal. Perubahan ini bertujuan untuk mencegah potensi kerentanan dan penyalahgunaan intent yang dapat dieksploitasi oleh aplikasi berbahaya. Ada dua hal utama peningkatan 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.
- Intent tertunda: Pembuat intent yang tertunda diperlakukan sebagai pengirim intent yang disertakan, bukan pengirim intent yang disertakan maksud
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 intuitif.
Perubahan inset jendela
Ada dua perubahan terkait inset jendela di Android 15: tata letak layar penuh diterapkan secara default, dan ada juga perubahan konfigurasi, seperti konfigurasi default kolom sistem.
Penerapan menyeluruh
Aplikasi ditampilkan di layar penuh secara default di perangkat yang menjalankan Android 15 jika aplikasi yang menargetkan Android 15 (level API 35).
Ini adalah perubahan yang dapat menyebabkan gangguan yang mungkin berdampak negatif terhadap UI aplikasi Anda. Tujuan perubahan tersebut memengaruhi area UI berikut:
- Menu navigasi handel gestur
- Transparan secara default.
- Offset bawah dinonaktifkan sehingga konten digambar di belakang navigasi sistem kecuali jika inset diterapkan.
setNavigationBarColor
danR.attr#navigationBarColor
adalah tidak digunakan lagi dan tidak memengaruhi navigasi gestur.setNavigationBarContrastEnforced
danR.attr#navigationBarContrastEnforced
tetap tidak berpengaruh pada navigasi gestur.
- Navigasi 3 tombol
- Opasitas disetel ke 80% secara default, dengan warna yang mungkin sesuai dengan jendela latar belakang.
- Offset bawah dinonaktifkan sehingga konten digambar di belakang menu navigasi sistem kecuali jika inset diterapkan.
setNavigationBarColor
danR.attr#navigationBarColor
adalah disetel agar sesuai dengan latar belakang jendela secara {i>default<i}. Latar belakang jendela harus berupa warna yang dapat digambar agar default ini dapat diterapkan. API ini merupakan tidak digunakan lagi tetapi terus memengaruhi navigasi 3 tombol.setNavigationBarContrastEnforced
danR.attr#navigationBarContrastEnforced
bernilai benar (true) secara default, yang menambahkan Latar belakang buram 80% pada navigasi 3 tombol.
- Status bar
- Transparan secara default.
- Offset atas dinonaktifkan sehingga konten digambar di belakang status bar kecuali inset akan diterapkan.
setStatusBarColor
danR.attr#statusBarColor
adalah tidak digunakan lagi dan tidak berpengaruh di Android 15.setStatusBarContrastEnforced
danR.attr#statusBarContrastEnforced
tidak digunakan lagi, tetapi masih memiliki di Android 15.
- Potongan layar
layoutInDisplayCutoutMode
jendela yang tidak mengambang harusLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.SHORT_EDGES
,NEVER
, danDEFAULT
ditafsirkan sebagaiALWAYS
sehingga pengguna tidak melihat notifikasi Hitam yang disebabkan oleh potongan layar dan tampak dari tepi ke tepi.
Contoh berikut menunjukkan aplikasi sebelum dan sesudah penargetan Android 15 (level API 35), serta sebelum dan sesudah menerapkan inset.
Yang harus diperiksa apakah aplikasi Anda sudah berada di layar penuh
Jika aplikasi Anda sudah merupakan edge-to-edge dan menerapkan inset, Anda sebagian besar tidak terdampak, kecuali dalam skenario berikut. Namun, bahkan jika Anda berpikir Anda tidak akan terpengaruh, sebaiknya uji aplikasi Anda.
- Anda memiliki jendela yang tidak mengambang, seperti
Activity
yang menggunakanSHORT_EDGES
,NEVER
, atauDEFAULT
, bukanLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. Jika aplikasi Anda error saat diluncurkan, mungkin karena layar pembuka Anda. Anda dapat mengupgrade inti dependensi layar pembuka ke 1.2.0-alpha01 atau yang lebih baru, atau setelwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Mungkin ada layar dengan traffic yang lebih rendah dengan UI yang terhalang. Verifikasi ini
layar yang jarang dikunjungi tidak memiliki UI yang tertutup. Layar dengan traffic yang lebih rendah mencakup:
- Layar orientasi atau login
- Halaman setelan
Yang harus diperiksa jika aplikasi Anda belum tata letak layar penuh
Jika aplikasi Anda belum layar penuh, kemungkinan besar Anda akan terpengaruh. Di beberapa selain skenario untuk aplikasi yang sudah {i>edge-to-edge<i}, Anda harus pertimbangkan hal berikut:
- Jika aplikasi Anda menggunakan Komponen Material 3 (
androidx.compose.material3
) di compose, sepertiTopAppBar
,BottomAppBar
, danNavigationBar
, komponen ini kemungkinan tidak terdampak karena mereka menangani inset secara otomatis. - Jika aplikasi Anda menggunakan Komponen Material 2 (
androidx.compose.material
) di Compose, komponen ini tidak menangani inset secara otomatis. Namun, Anda bisa mendapatkan 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 untukBottomAppBar
,TopAppBar
,BottomNavigation
, danNavigationRail
. Demikian pula, gunakan parametercontentWindowInsets
untukScaffold
. - Jika aplikasi Anda menggunakan tampilan dan Komponen Material
(
com.google.android.material
), Materi berbasis penayangan terbanyak Komponen 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 berada dalam
Scaffold
, Anda dapat menggunakan inset menggunakanScaffold
nilai padding. Jika tidak, terapkan padding menggunakan salah satuWindowInsets
- Jika aplikasi Anda menggunakan tampilan dan
BottomSheet
,SideSheet
, atau kustom container, terapkan padding menggunakanViewCompat.setOnApplyWindowInsetsListener
SebagaiRecyclerView
, terapkan padding menggunakan pemroses ini dan juga tambahkanclipToPadding="false"
.
Yang harus diperiksa apakah aplikasi Anda harus menawarkan perlindungan latar belakang kustom
Jika aplikasi Anda harus menawarkan perlindungan latar belakang kustom ke navigasi 3 tombol atau
status bar, aplikasi Anda harus menempatkan composable atau tampilan di belakang kolom sistem
menggunakan WindowInsets.Type#tappableElement()
untuk mendapatkan tombol 3 tombol
tinggi menu navigasi, atau WindowInsets.Type#statusBars
.
Resource tata letak layar penuh tambahan
Lihat Edge to Edge Views dan Edge to Edge Compose panduan untuk pertimbangan tambahan tentang penerapan inset.
API yang tidak digunakan lagi
API berikut sekarang tidak digunakan lagi:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#isStatusBarContrastEnforced
Window#setDecorFitsSystemWindows
Window#setNavigationBarColor
Window#setNavigationBarDividerColor
Window#setStatusBarColor
Window#setStatusBarContrastEnforced
Konfigurasi stabil
Jika aplikasi Anda menargetkan Android 15 (API level 35) atau yang lebih baru, Configuration
tidak
lagi mengecualikan bilah sistem. Jika Anda menggunakan
ukuran layar di
Class Configuration
untuk penghitungan tata letak, Anda harus menggantinya dengan yang lebih baik
alternatif seperti ViewGroup
, WindowInsets
, atau yang sesuai
WindowMetricsCalculator
bergantung pada kebutuhan Anda.
Configuration
telah tersedia sejak API 1. Data ini biasanya diperoleh dari
Activity.onConfigurationChanged
. Hal ini memberikan informasi
seperti kepadatan jendela,
orientasi, dan ukuran. Satu karakteristik penting tentang ukuran jendela
yang ditampilkan dari Configuration
adalah fungsi tersebut sebelumnya mengecualikan kolom sistem.
Ukuran konfigurasi biasanya digunakan untuk pemilihan resource, seperti
/res/layout-h500dp
, dan ini masih kasus penggunaan yang valid. Namun, menggunakannya untuk
penghitungan tata letak
selalu tidak disarankan. Jika Anda melakukannya, Anda harus memindahkan
dari data tersebut sekarang. Anda harus mengganti penggunaan Configuration
dengan sesuatu
yang lebih cocok 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
dari menu navigasi sistem, gunakan WindowInsets
. Jika Anda ingin tahu ukuran saat ini
jendela aplikasi Anda, gunakan computeCurrentWindowMetrics
.
Daftar berikut menjelaskan kolom yang terpengaruh oleh perubahan ini:
- Ukuran
Configuration.screenWidthDp
danscreenHeightDp
tidak lagi mengecualikan kolom sistem. Configuration.smallestScreenWidthDp
terpengaruh secara tidak langsung oleh perubahan kescreenWidthDp
danscreenHeightDp
.Configuration.orientation
terpengaruh secara tidak langsung oleh perubahan padascreenWidthDp
danscreenHeightDp
pada perangkat yang berdekatan.Display.getSize(Point)
dipengaruhi secara tidak langsung oleh perubahan dalamConfiguration
. Penggunaan ini tidak digunakan lagi mulai level API 30.Display.getMetrics()
sudah berfungsi seperti ini sejak level API 33.
Atribut eleganTextHeight ditetapkan secara default ke benar (true)
Untuk aplikasi yang menargetkan Android 15, atribut elegantTextHeight
TextView
menjadi true
secara default, yang menggantikan
font ringkas yang digunakan secara default dengan beberapa skrip yang memiliki metrik vertikal besar
dengan metrik yang jauh lebih mudah dibaca. Font ringkas diperkenalkan untuk mencegah
tata letak rusak; Android 13 (API level 33) mencegah banyak kerusakan ini dengan
memungkinkan tata letak teks meregangkan tinggi vertikal menggunakan
atribut fallbackLineSpacing
.
Di Android 15, font yang ringkas masih tetap ada di sistem sehingga aplikasi Anda dapat menetapkan
elegantTextHeight
ke false
untuk mendapatkan perilaku yang sama seperti sebelumnya, tetapi
mungkin tidak akan didukung dalam rilis mendatang. Jadi, jika aplikasi Anda mendukung
skrip berikut: Arab, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam,
Odia, Telugu, atau Thailand, uji aplikasi Anda dengan menetapkan elegantTextHeight
ke true
.
Perubahan lebar TextView untuk bentuk huruf yang kompleks
Pada versi Android sebelumnya, beberapa {i>font<i}
atau bahasa tulis tangan yang memiliki
pembentukan yang kompleks dapat menggambar huruf di area karakter sebelumnya atau berikutnya.
Terkadang, huruf tersebut terpotong 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 {i>clipping<i}.
Karena perubahan ini memengaruhi cara TextView
menentukan lebar, TextView
mengalokasikan lebih banyak lebar secara default jika aplikasi menargetkan Android 15 (API level 35) atau
lebih tinggi. Anda dapat mengaktifkan atau menonaktifkan perilaku ini dengan memanggil metode
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 clipping dengan memanggil
setShiftDrawingOffsetForStartOverhang
.
Contoh berikut menunjukkan bagaimana perubahan ini dapat meningkatkan tata letak teks untuk beberapa font dan bahasa.
Tinggi baris default berbasis lokal untuk EditText
Pada versi Android sebelumnya, tata letak teks merentangkan tinggi
teks untuk memenuhi tinggi baris font yang cocok dengan lokalitas saat ini. Misalnya, jika konten menggunakan bahasa Jepang, karena tinggi baris font Jepang
sedikit lebih besar daripada salah satu font Latin, tinggi teks
menjadi sedikit lebih besar. Namun, terlepas dari perbedaan tinggi baris ini, elemen EditText
memiliki ukuran yang seragam, terlepas dari
lokalitas yang digunakan, seperti yang diilustrasikan dalam gambar berikut:
Untuk aplikasi yang menargetkan Android 15, tinggi baris minimum sekarang disediakan untuk
EditText
agar cocok dengan font referensi untuk Lokalitas yang ditentukan, seperti yang ditunjukkan pada
gambar berikut:
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 dalam meminta fokus audio
Aplikasi yang menargetkan Android 15 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 non-SDK yang dibatasi antarmuka berbasis kolaborasi dengan developer Android dan pengujian internal. 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 mempengaruhi Anda. Namun, meskipun aplikasi Anda dapat mengakses beberapa antarmuka non-SDK bergantung pada API level target aplikasi Anda, penggunaan metode atau kolom non-SDK selalu berisiko tinggi merusak aplikasi Anda.
Jika tidak yakin apakah aplikasi Anda menggunakan antarmuka non-SDK, Anda dapat menguji aplikasi Anda untuk mengetahuinya. Jika aplikasi Anda mengandalkan non-SDK ini, Anda harus mulai merencanakan migrasi ke alternatif SDK. Meskipun demikian, kami memahami bahwa beberapa aplikasi memiliki kasus penggunaan yang valid untuk menggunakan antarmuka non-SDK. Jika Anda tidak dapat menemukan alternatif untuk menggunakan non-SDK untuk fitur dalam aplikasi, Anda harus meminta 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.