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 ini berlaku khusus bagi aplikasi yang menargetkan Android 15 atau yang lebih tinggi. Jika aplikasi Anda menargetkan Android 15 atau yang lebih tinggi, Anda harus memodifikasi aplikasi untuk mendukung perilaku ini dengan benar, jika berlaku.

Pastikan Anda juga meninjau daftar perubahan perilaku yang memengaruhi semua aplikasi yang berjalan di Android 15, terlepas dari targetSdkVersion aplikasi Anda.

Fungsi inti

Android 15 mengubah atau memperluas berbagai kemampuan inti sistem Android.

Perubahan pada layanan latar depan

Kami melakukan perubahan berikut pada layanan latar depan dengan Android 15.

Perilaku waktu tunggu layanan latar depan sinkronisasi data

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:

  1. Minta layanan Anda menerapkan metode Service.onTimeout(int, int) baru. Saat aplikasi Anda menerima callback, pastikan untuk memanggil stopSelf() dalam beberapa detik. (Jika Anda tidak segera menghentikan aplikasi, sistem akan menghasilkan kegagalan.)
  2. Pastikan layanan dataSync aplikasi Anda tidak berjalan selama lebih dari 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer).
  3. 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.
  4. 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

Jenis layanan latar depan pemrosesan media baru

Android 15 memperkenalkan jenis layanan latar depan baru, mediaProcessing. Jenis layanan ini sesuai untuk operasi seperti melakukan transcoding file media. Misalnya, aplikasi media mungkin mendownload file audio dan perlu mengonversinya ke format lain sebelum memutarnya. Anda dapat menggunakan layanan latar depan mediaProcessing untuk memastikan konversi berlanjut bahkan saat aplikasi berada di latar belakang.

Sistem mengizinkan layanan mediaProcessing 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(). 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 mediaProcessing did not stop within its timeout: [component name]"

Untuk menghindari pengecualian, Anda dapat melakukan salah satu hal berikut:

  1. Minta layanan Anda menerapkan metode Service.onTimeout(int, int) baru. Saat aplikasi Anda menerima callback, pastikan untuk memanggil stopSelf() dalam beberapa detik. (Jika Anda tidak segera menghentikan aplikasi, sistem akan menghasilkan kegagalan.)
  2. Pastikan layanan mediaProcessing aplikasi Anda tidak berjalan selama lebih dari jumlah 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer).
  3. Hanya mulai layanan latar depan mediaProcessing 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.
  4. Daripada menggunakan layanan latar depan mediaProcessing, gunakan API alternatif, seperti WorkManager.

Jika layanan latar depan mediaProcessing aplikasi Anda telah berjalan selama 6 jam dalam 24 terakhir, Anda tidak dapat memulai layanan latar depan mediaProcessing lainnya kecuali jika pengguna telah memindahkan aplikasi Anda ke latar depan (yang akan mereset timer). Jika Anda mencoba memulai layanan latar depan mediaProcessing lainnya, sistem akan menampilkan ForegroundServiceStartNotAllowedException dengan pesan error seperti "Batas waktu sudah habis untuk jenis layanan latar depan 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 dapat mengaktifkan waktu tunggu pemrosesan media meskipun aplikasi tidak menargetkan Android 15 (selama 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 media_processing_fgs_timeout_duration duration-in-milliseconds

Pembatasan pada penerima siaran BOOT_COMPLETED yang meluncurkan layanan latar depan

Ada batasan baru pada penerima siaran BOOT_COMPLETED yang meluncurkan layanan latar depan. Penerima BOOT_COMPLETED tidak diizinkan untuk meluncurkan jenis layanan latar depan berikut:

Jika penerima BOOT_COMPLETED mencoba meluncurkan salah satu jenis layanan latar depan tersebut, sistem akan menampilkan ForegroundServiceStartNotAllowedException.

Pengujian

Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan pembatasan baru ini bahkan jika aplikasi tidak menargetkan Android 15 (selama aplikasi tersebut berjalan di Android 15 perangkat). Jalankan perintah adb berikut:

adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name

Untuk mengirim siaran BOOT_COMPLETED tanpa memulai ulang perangkat, jalankan perintah adb berikut:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name

Pembatasan untuk memulai layanan latar depan saat aplikasi memiliki izin SYSTEM_ALERT_WINDOW

Sebelumnya, jika memiliki izin SYSTEM_ALERT_WINDOW, aplikasi dapat meluncurkan layanan latar depan meskipun aplikasi saat ini berada di latar belakang (seperti yang dibahas dalam pengecualian dari pembatasan mulai latar belakang).

Jika aplikasi menargetkan Android 15, pengecualian ini kini lebih sempit. Aplikasi kini harus memiliki izin SYSTEM_ALERT_WINDOW dan juga memiliki jendela overlay yang terlihat. Artinya, aplikasi harus meluncurkan jendela TYPE_APPLICATION_OVERLAY terlebih dahulu dan jendela harus terlihat sebelum Anda memulai layanan latar depan.

Jika aplikasi Anda mencoba memulai layanan latar depan dari latar belakang tanpa memenuhi persyaratan baru ini (dan tidak memiliki pengecualian lain), sistem akan menampilkan ForegroundServiceStartNotAllowedException.

Jika aplikasi Anda mendeklarasikan izin SYSTEM_ALERT_WINDOW dan meluncurkan layanan latar depan dari latar belakang, aplikasi tersebut mungkin akan terpengaruh oleh perubahan ini. Jika aplikasi Anda mendapatkan ForegroundServiceStartNotAllowedException, periksa urutan operasi aplikasi dan pastikan aplikasi Anda sudah memiliki jendela overlay yang aktif sebelum mencoba memulai layanan latar depan dari latar belakang. Anda dapat memeriksa apakah jendela overlay saat ini terlihat dengan memanggil View.getWindowVisibility(), atau Anda dapat mengganti View.onWindowVisibilityChanged() untuk mendapatkan notifikasi setiap kali visibilitas berubah.

Pengujian

Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan pembatasan baru ini meskipun aplikasi tidak menargetkan Android 15 (selama aplikasi berjalan di perangkat Android 15). Untuk mengaktifkan pembatasan baru ini saat memulai layanan latar depan dari latar belakang, jalankan perintah adb berikut:

adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name

Perubahan pada waktu aplikasi dapat mengubah status global mode Jangan Ganggu

Apps that target Android 15 (API level 35) and higher can no longer change the global state or policy of Do Not Disturb (DND) on a device (either by modifying user settings, or turning off DND mode). Instead, apps must contribute an AutomaticZenRule, which the system combines into a global policy with the existing most-restrictive-policy-wins scheme. Calls to existing APIs that previously affected global state (setInterruptionFilter, setNotificationPolicy) result in the creation or update of an implicit AutomaticZenRule, which is toggled on and off depending on the call-cycle of those API calls.

Note that this change only affects observable behavior if the app is calling setInterruptionFilter(INTERRUPTION_FILTER_ALL) and expects that call to deactivate an AutomaticZenRule that was previously activated by their owners.

Perubahan OpenJDK API

Android 15 continues the work of refreshing Android's core libraries to align with the features in the latest OpenJDK LTS releases.

Some of these changes can affect app compatibility for apps targeting Android 15 (API level 35):

  • Changes to string formatting APIs: Validation of argument index, flags, width, and precision are now more strict when using the following String.format() and Formatter.format() APIs:

    For example, the following exception is thrown when an argument index of 0 is used (%0 in the format string):

    IllegalFormatArgumentIndexException: Illegal format argument index = 0
    

    In this case, the issue can be fixed by using an argument index of 1 (%1 in the format string).

  • Changes to component type of Arrays.asList(...).toArray(): When using Arrays.asList(...).toArray(), the component type of the resulting array is now an Object—not the type of the underlying array's elements. So the following code throws a ClassCastException:

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

    For this case, to preserve String as the component type in the resulting array, you could use Collection.toArray(Object[]) instead:

    String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
    
  • Changes to language code handling: When using the Locale API, language codes for Hebrew, Yiddish, and Indonesian are no longer converted to their obsolete forms (Hebrew: iw, Yiddish: ji, and Indonesian: in). When specifying the language code for one of these locales, use the codes from ISO 639-1 instead (Hebrew: he, Yiddish: yi, and Indonesian: id).

  • Changes to random int sequences: Following the changes made in https://bugs.openjdk.org/browse/JDK-8301574, the following Random.ints() methods now return a different sequence of numbers than the Random.nextInt() methods do:

    Generally, this change shouldn't result in app-breaking behavior, but your code shouldn't expect the sequence generated from Random.ints() methods to match Random.nextInt().

The new SequencedCollection API can affect your app's compatibility after you update compileSdk in your app's build configuration to use Android 15 (API level 35):

  • Collision with MutableList.removeFirst() and MutableList.removeLast() extension functions in kotlin-stdlib

    The List type in Java is mapped to the MutableList type in Kotlin. Because the List.removeFirst() and List.removeLast() APIs have been introduced in Android 15 (API level 35), the Kotlin compiler resolves function calls, for example list.removeFirst(), statically to the new List APIs instead of to the extension functions in kotlin-stdlib.

    If an app is re-compiled with compileSdk set to 35 and minSdk set to 34 or lower, and then the app is run on Android 14 and lower, a runtime error is thrown:

    java.lang.NoSuchMethodError: No virtual method
    removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
    

    The existing NewApi lint option in Android Gradle Plugin can catch these new API usages.

    ./gradlew lint
    
    MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi]
          list.removeFirst()
    

    To fix the runtime exception and lint errors, the removeFirst() and removeLast() function calls can be replaced with removeAt(0) and removeAt(list.lastIndex) respectively in Kotlin. If you're using Android Studio Ladybug | 2024.1.3 or higher, it also provides a quick fix option for these errors.

    Consider removing @SuppressLint("NewApi") and lintOptions { disable 'NewApi' } if the lint option has been disabled.

  • Collision with other methods in Java

    New methods have been added into the existing types, for example, List and Deque. These new methods might not be compatible with the methods with the same name and argument types in other interfaces and classes. In the case of a method signature collision with incompatibility, the javac compiler outputs a build-time error. For example:

    Example 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
    

    Example 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
    

    Example 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
    

    To fix these build errors, the class implementing these interfaces should override the method with a compatible return type. For example:

    @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 restricts the usage of TLS versions 1.0 and 1.1. These versions had previously been deprecated in Android, but are now disallowed for apps targeting Android 15.

Peluncuran aktivitas latar belakang yang aman

Android 15 melindungi pengguna dari aplikasi berbahaya dan memberi mereka lebih banyak kontrol atas perangkat mereka dengan menambahkan perubahan yang mencegah aplikasi latar belakang berbahaya memunculkan aplikasi lain ke latar depan, meningkatkan hak istimewa mereka, dan menyalahgunakan interaksi pengguna. Peluncuran aktivitas latar belakang telah dibatasi sejak Android 10 (level API 29).

Perubahan lainnya

  • Mengubah kreator PendingIntent untuk memblokir peluncuran aktivitas latar belakang secara default. Hal ini membantu mencegah aplikasi membuat PendingIntent secara tidak sengaja yang dapat disalahgunakan oleh pihak berniat jahat.
  • Jangan membawa aplikasi ke latar depan kecuali jika PendingIntentpengirim mengizinkannya. Perubahan ini bertujuan untuk mencegah aplikasi berbahaya menyalahgunakan kemampuan untuk memulai aktivitas di latar belakang. Secara default, aplikasi tidak diizinkan untuk membawa stack tugas ke latar depan kecuali jika pembuat mengizinkan hak istimewa peluncuran aktivitas latar belakang atau pengirim memiliki hak istimewa peluncuran aktivitas latar belakang.
  • Mengontrol cara aktivitas teratas dari stack tugas dapat menyelesaikan tugasnya. Jika aktivitas teratas menyelesaikan tugas, Android akan kembali ke tugas mana pun yang terakhir aktif. Selain itu, jika aktivitas non-teratas menyelesaikan tugasnya, Android akan kembali ke layar utama; Android tidak akan memblokir penyelesaian aktivitas non-teratas ini.
  • Mencegah peluncuran aktivitas arbitrer dari aplikasi lain ke dalam tugas Anda sendiri. Perubahan ini mencegah aplikasi berbahaya melakukan phishing terhadap pengguna dengan membuat aktivitas yang tampak berasal dari aplikasi lain.
  • Mencegah jendela yang tidak terlihat dipertimbangkan untuk peluncuran aktivitas latar belakang. Hal ini membantu mencegah aplikasi berbahaya menyalahgunakan peluncuran aktivitas di latar belakang untuk menampilkan konten yang tidak diinginkan atau berbahaya kepada pengguna.

Intent yang lebih aman

Android 15 memperkenalkan StrictMode untuk intent.

Untuk melihat log mendetail tentang pelanggaran penggunaan Intent, gunakan 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

There are two changes related to window insets in Android 15: edge-to-edge is enforced by default, and there are also configuration changes, such as the default configuration of system bars.

Penerapan menyeluruh

Aplikasi menerapkan tampilan layar penuh secara default di perangkat yang menjalankan Android 15 jika aplikasi menargetkan Android 15 (level API 35).

Aplikasi yang menargetkan Android 14 dan tidak menerapkan tampilan layar penuh di perangkat Android 15.


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

Ini adalah perubahan yang dapat menyebabkan gangguan dan mungkin berdampak negatif pada UI aplikasi Anda. Perubahan ini memengaruhi area UI berikut:

  • Menu navigasi gestur
    • Transparan secara default.
    • Offset bawah dinonaktifkan sehingga konten digambar di belakang menu navigasi sistem, kecuali jika inset diterapkan.
    • setNavigationBarColor dan R.attr#navigationBarColor tidak digunakan lagi dan tidak memengaruhi navigasi gestur.
    • setNavigationBarContrastEnforced dan R.attr#navigationBarContrastEnforced terus tidak memengaruhi 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 dan R.attr#navigationBarColor ditetapkan agar cocok dengan latar belakang jendela secara default. Latar belakang jendela harus berupa drawable warna agar default ini dapat diterapkan. API ini tidak digunakan lagi, tetapi terus memengaruhi navigasi 3 tombol.
    • setNavigationBarContrastEnforced dan R.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 dan R.attr#statusBarColor tidak digunakan lagi dan tidak berpengaruh pada Android 15.
    • setStatusBarContrastEnforced dan R.attr#statusBarContrastEnforced tidak digunakan lagi, tetapi masih berpengaruh pada Android 15.
  • Area tampilan yang terpotong
    • layoutInDisplayCutoutMode jendela non-mengambang harus LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. SHORT_EDGES, NEVER, dan DEFAULT ditafsirkan sebagai ALWAYS sehingga pengguna tidak melihat kolom hitam yang disebabkan oleh area tampilan yang terpotong dan muncul di tepi layar.

Contoh berikut menunjukkan aplikasi sebelum dan sesudah menargetkan Android 15 (level API 35), serta sebelum dan sesudah menerapkan inset. Contoh ini tidak komprehensif, dan mungkin akan terlihat berbeda di Android Auto.

Aplikasi yang menargetkan Android 14 dan tidak menerapkan tampilan layar penuh di perangkat Android 15.
Aplikasi yang menargetkan Android 15 (level API 35) dan menerapkan tampilan layar penuh di perangkat Android 15. Namun, banyak elemen kini disembunyikan oleh status bar, menu navigasi 3 tombol, atau area tampilan yang terpotong karena penerapan tampilan layar penuh Android 15. UI yang tersembunyi mencakup panel aplikasi atas Material 2, tombol tindakan mengambang, dan item daftar.
Aplikasi yang menargetkan Android 15 (level API 35), menerapkan tampilan layar penuh di perangkat Android 15, dan menerapkan inset sehingga UI tidak tersembunyi.
Hal yang perlu diperiksa jika aplikasi Anda sudah menerapkan tampilan layar penuh

Jika aplikasi Anda sudah menerapkan tampilan layar penuh dan menerapkan inset, Anda sebagian besar tidak akan terpengaruh, kecuali dalam skenario berikut. Namun, meskipun Anda merasa tidak terpengaruh, sebaiknya uji aplikasi Anda.

  • Anda memiliki jendela non-mengambang, seperti Activity yang menggunakan SHORT_EDGES, NEVER, atau DEFAULT, bukan LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. Jika aplikasi Anda error saat diluncurkan, hal ini mungkin disebabkan oleh layar pembuka. Anda dapat mengupgrade dependensi inti layar pembuka ke 1.2.0-alpha01 atau yang lebih baru, atau menetapkan window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always.
  • Mungkin ada layar dengan traffic lebih rendah yang UI-nya terhalang. Pastikan layar yang jarang dikunjungi ini tidak memiliki UI yang terhalang. Layar dengan traffic lebih rendah mencakup:
    • Layar orientasi atau login
    • Halaman setelan
Hal yang perlu diperiksa jika aplikasi Anda belum menerapkan tampilan layar penuh

Jika aplikasi Anda belum menerapkan tampilan layar penuh, kemungkinan besar Anda akan terpengaruh. Selain skenario untuk aplikasi yang sudah menerapkan tampilan layar penuh, Anda harus mempertimbangkan hal berikut:

  • Jika aplikasi Anda menggunakan Komponen Material 3 ( androidx.compose.material3) di Compose, seperti TopAppBar, BottomAppBar, dan NavigationBar, komponen ini kemungkinan tidak terpengaruh karena otomatis menangani inset.
  • Jika aplikasi Anda menggunakan Komponen Material 2 ( androidx.compose.material) di Compose, komponen tersebut 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 parameter windowInsets untuk menerapkan inset secara manual bagi BottomAppBar, TopAppBar, BottomNavigation, dan NavigationRail. Demikian pula, gunakan parameter contentWindowInsets untuk Scaffold.
  • Jika aplikasi Anda menggunakan tampilan dan Komponen Material (com.google.android.material), sebagian besar Komponen Material berbasis tampilan 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 Anda 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 kontainer kustom , terapkan padding menggunakan ViewCompat.setOnApplyWindowInsetsListener. Untuk RecyclerView, terapkan padding menggunakan pemroses ini dan juga tambahkan clipToPadding="false".
Hal yang perlu diperiksa jika 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 tinggi menu navigasi 3 tombol atau WindowInsets.Type#statusBars.

Referensi tampilan layar penuh tambahan

Lihat panduan Tampilan Layar Penuh dan Compose Layar Penuh untuk pertimbangan tambahan tentang penerapan inset.

API tidak digunakan lagi

API berikut tidak digunakan lagi, tetapi tidak dinonaktifkan:

API berikut tidak digunakan lagi dan dinonaktifkan:

Konfigurasi stabil

Jika aplikasi Anda menargetkan Android 15 (API level 35) atau yang lebih baru, Configuration tidak lagi mengecualikan status bar. Jika Anda menggunakan ukuran layar di class Configuration untuk perhitungan 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. Class ini memberikan informasi seperti kepadatan, orientasi, dan ukuran jendela. Salah satu karakteristik penting tentang ukuran jendela yang ditampilkan dari Configuration adalah bahwa sebelumnya status bar dikecualikan.

Ukuran konfigurasi biasanya digunakan untuk pemilihan resource, seperti /res/layout-h500dp, dan ini masih merupakan kasus penggunaan yang valid. Namun, menggunakannya untuk perhitungan tata letak selalu tidak disarankan. Jika Anda melakukannya, Anda harus segera berhenti. 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:

Atribut elegantTextHeight secara default adalah 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.

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

Perubahan lebar TextView untuk bentuk huruf yang kompleks

In previous versions of Android, some cursive fonts or languages that have complex shaping might draw the letters in the previous or next character's area. In some cases, such letters were clipped at the beginning or ending position. Starting in Android 15, a TextView allocates width for drawing enough space for such letters and allows apps to request extra paddings to the left to prevent clipping.

Because this change affects how a TextView decides the width, TextView allocates more width by default if the app targets Android 15 (API level 35) or higher. You can enable or disable this behavior by calling the setUseBoundsForWidth API on TextView.

Because adding left padding might cause a misalignment for existing layouts, the padding is not added by default even for apps that target Android 15 or higher. However, you can add extra padding to preventing clipping by calling setShiftDrawingOffsetForStartOverhang.

The following examples show how these changes can improve text layout for some fonts and languages.

Standard layout for English text in a cursive font. Some of the letters are clipped. Here is the corresponding XML:

<TextView
    android:fontFamily="cursive"
    android:text="java" />
Layout for the same English text with additional width and padding. Here is the corresponding XML:

<TextView
    android:fontFamily="cursive"
    android:text="java"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />
Standard layout for Thai text. Some of the letters are clipped. Here is the corresponding XML:

<TextView
    android:text="คอมพิวเตอร์" />
Layout for the same Thai text with additional width and padding. Here is the corresponding XML:

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

Tinggi baris default yang mendukung 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:

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 (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:

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 pada permintaan 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 includes updated lists of restricted non-SDK interfaces based on collaboration with Android developers and the latest internal testing. Whenever possible, we make sure that public alternatives are available before we restrict non-SDK interfaces.

If your app does not target Android 15, some of these changes might not immediately affect you. However, while it's possible for your app to access some non-SDK interfaces depending on your app's target API level, using any non-SDK method or field always carries a high risk of breaking your app.

If you are unsure if your app uses non-SDK interfaces, you can test your app to find out. If your app relies on non-SDK interfaces, you should begin planning a migration to SDK alternatives. Nevertheless, we understand that some apps have valid use cases for using non-SDK interfaces. If you can't find an alternative to using a non-SDK interface for a feature in your app, you should request a new public API.

To learn more about the changes in this release of Android, see Updates to non-SDK interface restrictions in Android 15. To learn more about non-SDK interfaces generally, see Restrictions on non-SDK interfaces.