Perubahan perilaku: Aplikasi yang menargetkan Android 15 atau yang lebih tinggi

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

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:

  1. Minta layanan Anda untuk mengimplementasikan metode Service.onTimeout(int, int) baru. Saat aplikasi menerima callback, pastikan untuk memanggil stopSelf() dalam beberapa detik. (Jika Anda tidak langsung menghentikan aplikasi, sistem akan membuat gagal.)
  2. 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).
  3. 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.
  4. 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:

  1. Minta layanan Anda untuk mengimplementasikan metode Service.onTimeout(int, int) baru. Saat aplikasi menerima callback, pastikan untuk memanggil stopSelf() dalam beberapa detik. (Jika Anda tidak langsung menghentikan aplikasi, sistem akan membuat gagal.)
  2. 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).
  3. 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.
  4. 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:

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() dan Formatter.format():

    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 menggunakan Arrays.asList(...).toArray(), jenis komponen array yang dihasilkan adalah sekarang Object—bukan jenis elemen array yang mendasarinya. Jadi, kode berikut akan menampilkan ClassCastException:

    String[] elements = (String[]) Arrays.asList("one", "two").toArray();
    

    Untuk hal ini, pertahankan String sebagai jenis komponen dalam hasil Anda dapat menggunakan Collection.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 metode Random.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 dengan Random.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 ekstensi MutableList.removeLast() di kotlin-stdlib

    Jenis List di Java dipetakan ke jenis MutableList di Kotlin. Karena API List.removeFirst() dan List.removeLast() diperkenalkan di Android 15 (API level 35), compiler Kotlin me-resolve panggilan fungsi, misalnya list.removeFirst(), secara statis ke List API baru, bukan fungsi ekstensi di kotlin-stdlib.

    Jika aplikasi dikompilasi ulang dengan compileSdk disetel ke 35 dan minSdk disetel ke 34 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 fungsi removeLast() dapat diganti dengan removeAt(0) dan removeAt(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") dan lintOptions { disable 'NewApi' } jika opsi lint telah dinonaktifkan.

  • Tabrakan dengan metode lain di Java

    Metode baru telah ditambahkan ke dalam jenis yang ada, misalnya, List dan Deque. 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, compiler javac 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 List
    

    Contoh 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 error
    

    Contoh error 3:

    javac MyList.java
    
    MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible;
    public static class MyList implements List<Object>, MyInterface<Object> {
      class MyList inherits unrelated defaults for getFirst() from types List and MyInterface
      where E#1,E#2 are type-variables:
        E#1 extends Object declared in interface List
        E#2 extends Object declared in interface MyInterface
    1 error
    

    Untuk 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 membuat PendingIntent 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).

Aplikasi yang menargetkan Android 14 dan bukan tata letak layar penuh Perangkat Android 15.


Aplikasi yang menargetkan Android 15 (API level 35) dan ditampilkan di layar penuh di perangkat Android 15. Aplikasi ini sebagian besar menggunakan Komponen Compose Material 3 yang secara otomatis menerapkan inset. Layar ini tidak terkena dampak negatif oleh Penerapan menyeluruh Android 15.

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 dan R.attr#navigationBarColor adalah tidak digunakan lagi dan tidak memengaruhi navigasi gestur.
    • setNavigationBarContrastEnforced dan R.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 dan R.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 dan R.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 dan R.attr#statusBarColor adalah tidak digunakan lagi dan tidak berpengaruh di Android 15.
    • setStatusBarContrastEnforced dan R.attr#statusBarContrastEnforced tidak digunakan lagi, tetapi masih memiliki di Android 15.
  • Potongan layar
    • layoutInDisplayCutoutMode jendela yang tidak mengambang harus LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. SHORT_EDGES, NEVER, dan DEFAULT ditafsirkan sebagai ALWAYS 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.

Aplikasi yang menargetkan Android 14 dan bukan tata letak layar penuh Perangkat Android 15.
Aplikasi yang menargetkan Android 15 (API level 35) dan ditampilkan di layar penuh di perangkat Android 15. Namun, banyak elemen kini disembunyikan oleh status menu navigasi, menu navigasi 3 tombol, atau potongan layar karena adanya Android 15 penegakan kebijakan menyeluruh. UI tersembunyi menyertakan Material 2 panel aplikasi atas, tombol tindakan mengambang, dan item daftar.
Aplikasi yang menargetkan Android 15 (API level 35), tata letak layar penuh perangkat Android 15 dan menerapkan inset sehingga UI tidak disembunyikan.
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 menggunakan SHORT_EDGES, NEVER, atau DEFAULT, bukan LAYOUT_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 setel window.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, seperti TopAppBar, BottomAppBar, dan NavigationBar, 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 parameter windowInsets untuk menerapkan inset secara manual untuk BottomAppBar, TopAppBar, BottomNavigation, dan NavigationRail. Demikian pula, gunakan parameter contentWindowInsets untuk Scaffold.
  • Jika aplikasi Anda menggunakan tampilan dan Komponen Material (com.google.android.material), Materi berbasis penayangan terbanyak Komponen seperti BottomNavigationView, BottomAppBar, NavigationRailView, atau NavigationView, menangani inset dan tidak memerlukan pekerjaan tambahan. Namun, Anda perlu menambahkan android:fitsSystemWindows="true" jika menggunakan AppBarLayout.
  • Untuk composable kustom, terapkan inset secara manual sebagai padding. Jika konten berada dalam Scaffold, Anda dapat menggunakan inset menggunakan Scaffold nilai padding. Jika tidak, terapkan padding menggunakan salah satu WindowInsets
  • Jika aplikasi Anda menggunakan tampilan dan BottomSheet, SideSheet, atau kustom container, terapkan padding menggunakan ViewCompat.setOnApplyWindowInsetsListener Sebagai RecyclerView, terapkan padding menggunakan pemroses ini dan juga tambahkan clipToPadding="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:

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:

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.

Perilaku elegantTextHeight untuk aplikasi yang menargetkan Android 14 (API level 34) dan yang lebih rendah.
Perilaku elegantTextHeight untuk aplikasi yang menargetkan Android 15.

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.

Tata letak standar untuk teks bahasa Inggris dalam font tulis tangan. Beberapa huruf terpotong. Berikut XML yang sesuai:

<TextView
    android:fontFamily="cursive"
    android:text="java" />
Tata letak untuk teks bahasa Inggris yang sama dengan tambahan lebar dan padding. Berikut XML yang sesuai:

<TextView
    android:fontFamily="cursive"
    android:text="java"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />
Tata letak standar untuk teks Thailand. Beberapa huruf diklip. Berikut XML yang sesuai:

<TextView
    android:text="คอมพิวเตอร์" />
Tata letak untuk teks bahasa Thai yang sama dengan tambahan lebar dan padding. Berikut XML yang sesuai:

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

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:

Tiga kotak yang mewakili elemen 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, tinggi baris minimum sekarang disediakan untuk EditText agar cocok dengan font referensi untuk Lokalitas yang ditentukan, seperti yang ditunjukkan pada gambar berikut:

Tiga kotak yang mewakili elemen 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 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.