Seperti rilis sebelumnya, Android 15 menyertakan perubahan perilaku yang mungkin memengaruhi aplikasi Anda. Perubahan perilaku berikut ini berlaku khusus bagi aplikasi yang menargetkan Android 15 atau yang lebih tinggi. Jika aplikasi Anda menargetkan Android 15 atau yang lebih tinggi, Anda harus memodifikasi aplikasi untuk mendukung perilaku ini dengan benar, jika berlaku.
Pastikan Anda juga meninjau daftar perubahan perilaku yang memengaruhi semua aplikasi
yang berjalan di Android 15, terlepas dari targetSdkVersion aplikasi Anda.
Fungsi inti
Android 15 mengubah atau memperluas berbagai kemampuan inti sistem Android.
Perubahan pada layanan latar depan
Kami melakukan perubahan berikut pada layanan latar depan dengan Android 15.
- Perilaku waktu tunggu layanan latar depan sinkronisasi data
- Jenis layanan latar depan pemrosesan media baru
- Pembatasan pada penerima siaran
BOOT_COMPLETEDyang meluncurkan layanan latar depan - Pembatasan untuk memulai layanan latar depan saat aplikasi memiliki izin
SYSTEM_ALERT_WINDOW
Perilaku waktu tunggu layanan latar depan sinkronisasi data
Android 15 memperkenalkan perilaku waktu tunggu baru ke dataSync untuk aplikasi yang menargetkan
Android 15 (API level 35) atau yang lebih tinggi. Perilaku ini juga berlaku untuk
jenis layanan latar depan mediaProcessing baru.
Sistem mengizinkan layanan dataSync aplikasi berjalan selama total 6 jam
dalam periode 24 jam, setelah itu sistem akan memanggil metode
Service.onTimeout(int, int) layanan yang berjalan (diperkenalkan di Android
15). Saat ini, layanan memiliki waktu beberapa detik untuk memanggil
Service.stopSelf(). Saat Service.onTimeout() dipanggil, layanan tidak lagi dianggap sebagai layanan latar depan. Jika layanan tidak
memanggil Service.stopSelf(), sistem akan menampilkan pengecualian internal. Pengecualian
akan dicatat ke dalam log di Logcat dengan pesan berikut:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
Untuk menghindari masalah terkait perubahan perilaku ini, Anda dapat melakukan satu atau beberapa hal berikut:
- Minta layanan Anda menerapkan metode
Service.onTimeout(int, int)baru. Saat aplikasi Anda menerima callback, pastikan untuk memanggilstopSelf()dalam beberapa detik. (Jika Anda tidak segera menghentikan aplikasi, sistem akan menghasilkan kegagalan.) - Pastikan layanan
dataSyncaplikasi Anda tidak berjalan selama lebih dari 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer). - Hanya mulai layanan latar depan
dataSyncsebagai hasil dari interaksi pengguna langsung; karena aplikasi Anda berada di latar depan saat layanan dimulai, layanan Anda memiliki waktu enam jam penuh setelah aplikasi beralih ke latar belakang. - Sebagai ganti menggunakan layanan latar depan
dataSync, gunakan API alternatif.
Jika layanan latar depan dataSync aplikasi Anda telah berjalan selama 6 jam dalam 24
jam terakhir, Anda tidak dapat memulai layanan latar depan dataSync lain kecuali pengguna
telah memindahkan aplikasi Anda ke latar depan (yang mereset timer). Jika Anda mencoba
memulai layanan latar depan dataSync lainnya, sistem akan menampilkan
ForegroundServiceStartNotAllowedException
dengan pesan error seperti "Batas waktu sudah habis untuk jenis layanan latar depan
dataSync".
Pengujian
Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan waktu tunggu sinkronisasi data meskipun aplikasi
tidak menargetkan Android 15 (asalkan aplikasi berjalan di perangkat
Android 15). Untuk mengaktifkan waktu tunggu, jalankan perintah adb berikut:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
Anda juga dapat menyesuaikan periode waktu tunggu untuk mempermudah pengujian perilaku
aplikasi saat batas tercapai. Untuk menetapkan periode waktu tunggu baru, jalankan perintah adb berikut:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
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:
- Minta layanan Anda menerapkan metode
Service.onTimeout(int, int)baru. Saat aplikasi Anda menerima callback, pastikan untuk memanggilstopSelf()dalam beberapa detik. (Jika Anda tidak segera menghentikan aplikasi, sistem akan menghasilkan kegagalan.) - Pastikan layanan
mediaProcessingaplikasi Anda tidak berjalan selama lebih dari jumlah 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, mereset timer). - Hanya mulai layanan latar depan
mediaProcessingsebagai 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. - 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:
dataSynccameramediaPlaybackphoneCallmediaProjectionmicrophone(pembatasan ini telah diterapkan selamamicrophonesejak Android 14)
Jika penerima BOOT_COMPLETED mencoba meluncurkan salah satu jenis layanan latar depan
tersebut, sistem akan menampilkan ForegroundServiceStartNotAllowedException.
Pengujian
Untuk menguji perilaku aplikasi, Anda dapat mengaktifkan pembatasan baru ini bahkan jika
aplikasi tidak menargetkan Android 15 (selama aplikasi tersebut berjalan di Android 15
perangkat). Jalankan perintah adb berikut:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
Untuk mengirim siaran BOOT_COMPLETED tanpa memulai ulang perangkat,
jalankan perintah adb berikut:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
Pembatasan untuk memulai layanan latar depan saat aplikasi memiliki izin SYSTEM_ALERT_WINDOW
以前,如果应用拥有 SYSTEM_ALERT_WINDOW 权限,即使应用当前在后台运行,也可以启动前台服务(如免于后台启动限制中所述)。
如果应用以 Android 15 为目标平台,则此豁免范围现在更窄。现在,应用需要具有 SYSTEM_ALERT_WINDOW 权限,并且还需要有一个可见的叠加窗口。也就是说,应用需要先启动 TYPE_APPLICATION_OVERLAY 窗口,并且该窗口需要处于可见状态,然后您才能启动前台服务。
如果您的应用尝试从后台启动前台服务,但不符合这些新要求(并且没有其他豁免情况),系统会抛出 ForegroundServiceStartNotAllowedException。
如果您的应用声明了 SYSTEM_ALERT_WINDOW 权限并从后台启动前台服务,则可能会受到此变更的影响。如果您的应用获得了 ForegroundServiceStartNotAllowedException,请检查应用的操作顺序,并确保应用在尝试从后台启动前台服务之前已具有有效的叠加层窗口。您可以通过调用 View.getWindowVisibility() 检查叠加层窗口当前是否可见,也可以替换 View.onWindowVisibilityChanged(),以便在可见性发生变化时收到通知。
测试
如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。如需针对从后台启动前台服务启用这些新限制,请运行以下 adb 命令:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
Perubahan pada waktu aplikasi dapat mengubah status global mode Jangan Ganggu
Aplikasi yang menargetkan Android 15 (API level 35) dan yang lebih tinggi tidak dapat lagi mengubah
status atau kebijakan global Jangan Ganggu (DND) di perangkat (baik dengan mengubah
setelan pengguna, atau menonaktifkan mode DND). Sebagai gantinya, aplikasi harus berkontribusi pada
AutomaticZenRule, yang digabungkan sistem menjadi kebijakan global dengan
skema kebijakan paling ketat yang ada. Panggilan ke API yang ada yang
sebelumnya memengaruhi status global (setInterruptionFilter,
setNotificationPolicy) menghasilkan pembuatan atau pembaruan AutomaticZenRule implisit, yang diaktifkan dan dinonaktifkan bergantung pada siklus panggilan
panggilan API tersebut.
Perhatikan bahwa perubahan ini hanya memengaruhi perilaku yang dapat diamati jika aplikasi memanggil
setInterruptionFilter(INTERRUPTION_FILTER_ALL) dan mengharapkan panggilan tersebut untuk
menonaktifkan AutomaticZenRule yang sebelumnya diaktifkan oleh pemiliknya.
Perubahan OpenJDK API
Android 15 将继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。
以下变更可能会影响以 Android 15(API 级别 35)为目标平台的应用的兼容性:
对字符串格式化 API 进行了更改:现在,当使用以下
String.format()和Formatter.format()API 时,对参数索引、标志、 宽度和精度的验证要求变得更加严格:String.format(String, Object[])String.format(Locale, String, Object[])Formatter.format(String, Object[])Formatter.format(Locale, String, Object[])
例如,当使用实参索引 0(格式字符串中的
%0)时,系统会抛出以下异常:IllegalFormatArgumentIndexException: Illegal format argument index = 0在这种情况下,可以使用实参索引 1(格式字符串中的
%1)来解决此问题。对
Arrays.asList(...).toArray()的组件类型进行了更改:使用Arrays.asList(...).toArray()时,生成的数组的组件类型现在是Object,而不是底层数组元素的类型。因此,以下代码会抛出ClassCastException:String[] elements = (String[]) Arrays.asList("one", "two").toArray();在这种情况下,如需在生成的 数组中保留
String作为组件类型,您可以改用Collection.toArray(Object[]):String[] elements = Arrays.asList("two", "one").toArray(new String[0]);对语言代码处理进行了更改:使用
LocaleAPI 时, 希伯来语、意第绪语和印度尼西亚语的语言代码不再转换为 其过时形式(希伯来语:iw,意第绪语:ji,印度尼西亚语:in)。 指定其中一种语言区域的语言代码时,请改用 ISO 639-1 中的代码 (希伯来语:he,意第绪语:yi,印度尼西亚语:id)。对随机 int 序列进行了更改:根据 https://bugs.openjdk.org/browse/JDK-8301574 中所做的更改,以下
Random.ints()方法现在返回的数字序列与 theRandom.nextInt()方法返回的数字序列不同:一般来说,此更改不应导致应用出现破坏性行为,但您的代码不应期望从
Random.ints()方法生成的序列与Random.nextInt()匹配。
新的 SequencedCollection API 可能会影响应用的兼容性
在应用的 build 配置中
更新 以使用
Android 15(API 级别 35)后:compileSdk
与
MutableList.removeFirst()和MutableList.removeLast()扩展函数在kotlin-stdlib中发生冲突Java 中的
List类型映射到 Kotlin 中的MutableList类型。 由于List.removeFirst()和List.removeLast()API 是在 Android 15(API 级别 35)中引入的,因此 Kotlin 编译器 会将函数调用(例如list.removeFirst())静态解析为 新的ListAPI,而不是kotlin-stdlib中的扩展函数。如果使用
compileSdk设置为35且minSdk设置为34或更低版本重新编译应用,然后在 Android 14 及更低版本上运行该应用,则会抛出运行时错误:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;Android Gradle 插件中现有的
NewApilint 选项可以捕获这些新的 API 用法。./gradlew lintMainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()如需修复运行时异常和 lint 错误,可以将
removeFirst()和removeLast()函数调用分别替换为 Kotlin 中的removeAt(0)和removeAt(list.lastIndex)。如果您使用的是 Android Studio Ladybug | 2024.1.3 或更高版本,它还为这些错误提供了快速修复选项。如果 lint 选项已停用,请考虑移除
@SuppressLint("NewApi")和lintOptions { disable 'NewApi' }。与 Java 中的其他方法发生冲突
新的方法已添加到现有类型中,例如,
List和Deque。这些新方法可能与其他接口和类中具有相同名称和实参类型的方法不兼容。如果方法签名冲突且不兼容,javac编译器会输出 build 时错误。例如:错误示例 1:
javac MyList.javaMyList.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错误示例 2:
javac MyList.javaMyList.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错误示例 3:
javac MyList.javaMyList.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如需修复这些 build 错误,实现这些接口的类应使用兼容的返回值类型替换该方法。例如:
@Override public Object getFirst() { return List.super.getFirst(); }
Keamanan
Android 15 menyertakan perubahan yang meningkatkan keamanan sistem untuk membantu melindungi aplikasi dan pengguna dari aplikasi berbahaya.
Versi TLS yang dibatasi
Android 15 membatasi penggunaan TLS versi 1.0 dan 1.1. Versi ini sebelumnya tidak digunakan lagi di Android, tetapi sekarang tidak diizinkan untuk aplikasi yang menargetkan Android 15.
Peluncuran aktivitas latar belakang yang aman
Android 15 做出了一些变更,可防止恶意后台应用将其他应用置于前台、提升自身权限并滥用用户互动,从而保护用户免受恶意应用的侵害,并让用户更好地控制自己的设备。自 Android 10(API 级别 29)起,后台 activity 启动受到限制。
其他更改
- 将
PendingIntent创建者更改为默认阻止后台活动启动。这有助于防止应用意外创建可能被恶意行为者滥用的PendingIntent。 - 除非
PendingIntent发送方允许,否则请勿将应用转至前台。此变更旨在防止恶意应用滥用在后台启动 activity 的功能。默认情况下,除非创建者允许后台 activity 启动权限或发送者具有后台 activity 启动权限,否则不允许应用将任务堆栈带到前台。 - 控制任务堆栈的顶层 activity 如何完成其任务。如果顶部 activity 完成了一项任务,Android 将返回到上次处于活跃状态的任务。此外,如果非顶部 activity 完成其任务,Android 会返回到主屏幕;它不会阻止此非顶部 activity 完成。
- 防止从其他应用启动任意 activity 进入您自己的任务。此变更可防止恶意应用通过创建看似来自其他应用的 activity 来对用户进行钓鱼式攻击。
- 阻止将非可见窗口纳入后台 activity 启动的考虑范围。这有助于防止恶意应用滥用后台活动启动来向用户显示不必要或恶意的内容。
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
如果应用以 Android 15(API 级别 35)为目标平台,则在搭载 Android 15 的设备上默认以无边框显示。
这是一项重大变更,可能会对应用的界面产生不利影响。这些变更会影响以下界面区域:
- 手势提示条导航栏
- 默认透明。
- 底部偏移已停用,因此除非应用了边衬区,否则内容会绘制在系统导航栏后面。
setNavigationBarColor和R.attr#navigationBarColor已弃用,不会影响手势导航。setNavigationBarContrastEnforced和R.attr#navigationBarContrastEnforced仍不会影响手势导航。
- 三按钮导航
- 默认情况下,不透明度设置为 80%,颜色可能与窗口背景颜色一致。
- 底部偏移已停用,因此除非应用了边衬区,否则内容会绘制在系统导航栏后面。
setNavigationBarColor和R.attr#navigationBarColor默认设置为与窗口背景颜色一致。窗口背景必须是颜色可绘制对象,才能应用此默认设置。此 API 已弃用,但仍会影响三按钮导航。setNavigationBarContrastEnforced和R.attr#navigationBarContrastEnforced默认值为 true,这会在三按钮导航中添加 80% 不透明的背景。
- 状态栏
- 默认透明。
- 顶部偏移已停用,因此除非应用了边衬区,否则内容会绘制在状态栏后面。
setStatusBarColor和R.attr#statusBarColor已弃用,不会影响 Android 15。setStatusBarContrastEnforced和R.attr#statusBarContrastEnforced已弃用,但仍会影响 Android 15。
- 刘海屏
- 非浮动窗口的
layoutInDisplayCutoutMode必须为LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS。SHORT_EDGES、NEVER和DEFAULT会被解读为ALWAYS,这样用户就不会看到因显示屏刘海屏而产生的黑条,并且会以无边框显示。
- 非浮动窗口的
以下示例展示了应用在以 Android 15(API 级别 35)为目标平台之前和之后,以及在应用边衬区之前和之后的效果。此示例并不全面,在 Android Auto 上可能会显示不同的效果。
如果您的应用已以无边框显示,需要检查哪些内容
如果您的应用已以 无边框 显示并应用了边衬区,则大部分情况下 不会受到影响,但在以下情形中除外。不过,即使您认为自己不会受到影响,我们也建议您测试应用。
- 您有一个非浮动窗口,例如使用
SHORT_EDGES、NEVER或DEFAULT而不是LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS的Activity。如果您的应用在启动时崩溃,可能是因为启动画面所致。您可以将 核心 启动画面 依赖项升级到 1.2.0-alpha01 或更高版本,也可以设置window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always。 - 可能存在流量较低的屏幕,其界面被遮盖。验证这些访问量较少的屏幕是否没有被遮盖的界面。流量较低的屏幕包括:
- 新手入门或登录屏幕
- “设置”页面
如果您的应用尚未以无边框显示,需要检查哪些内容
如果您的应用尚未以无边框显示,则很可能会受到影响。除了已以无边框显示的应用的情形之外,您还应考虑以下情况:
- 如果您的应用在 Compose 中使用了 Material 3 组件 (
androidx.compose.material3),例如TopAppBar、BottomAppBar和NavigationBar,这些组件可能不会 受到影响,因为它们会自动处理边衬区。 - 如果应用使用的是 Compose 中的 Material 2 组件 (
androidx.compose.material),这些组件 本身并不会自动处理边衬区。不过,您可以获得边衬区的访问权限,然后手动应用边衬区。在 androidx.compose.material 1.6.0 及更高版本中,使用windowInsets参数可为BottomAppBar、TopAppBar、BottomNavigation和NavigationRail手动应用边衬区。 同样,对于Scaffold,请使用contentWindowInsets参数。 - 如果应用使用了视图和 Material 组件
(
com.google.android.material),则大多数基于视图的 Material 组件(例如BottomNavigationView、BottomAppBar、NavigationRailView或NavigationView)都会处理边衬区,因此不需要执行额外的操作。不过,您需要添加android:fitsSystemWindows="true",如果使用AppBarLayout。 - 对于自定义可组合项,请手动应用边衬区作为内边距。如果您的
内容位于
Scaffold中,则可以使用Scaffold内边距值来使用边衬区。否则,请使用其中一个WindowInsets应用内边距。 - 如果应用使用的是视图和
BottomSheet、SideSheet或自定义 容器,请使用ViewCompat.setOnApplyWindowInsetsListener应用内边距。对于RecyclerView,请使用此监听器应用内边距,同时添加clipToPadding="false"。
如果您的应用必须提供自定义背景保护,需要检查哪些内容
如果您的应用必须为“三按钮”导航或
状态栏提供自定义背景保护,则应用应使用 WindowInsets.Type#tappableElement() 将可组合函数或视图放置在系统栏后面
,以获取“三按钮”
导航栏高度或 WindowInsets.Type#statusBars。
其他无边框资源
如需了解有关应用边衬区的其他注意事项,请参阅无边框视图和无边框 Compose 指南。
已弃用的 API
以下 API 已弃用,但未停用:
R.attr#enforceStatusBarContrastR.attr#navigationBarColor(适用于三按钮导航,alpha 为 80%)Window#isStatusBarContrastEnforcedWindow#setNavigationBarColor(适用于三按钮导航,alpha 为 80%)Window#setStatusBarContrastEnforced
以下 API 已弃用并已停用:
R.attr#navigationBarColor(适用于手势导航)R.attr#navigationBarDividerColorR.attr#statusBarColorWindow#setDecorFitsSystemWindowsWindow#getNavigationBarColorWindow#getNavigationBarDividerColorWindow#getStatusBarColorWindow#setNavigationBarColor(适用于手势导航)Window#setNavigationBarDividerColorWindow#setStatusBarColor
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:
Configuration.screenWidthDpdanscreenHeightDpukuran tidak lagi mengecualikan status bar.Configuration.smallestScreenWidthDpsecara tidak langsung terpengaruh oleh perubahan padascreenWidthDpdanscreenHeightDp.Configuration.orientationsecara tidak langsung terpengaruh oleh perubahan padascreenWidthDpdanscreenHeightDpdi perangkat yang hampir persegi.Display.getSize(Point)secara tidak langsung terpengaruh oleh perubahan diConfiguration. Hal ini tidak digunakan lagi mulai API level 30.Display.getMetrics()telah berfungsi seperti ini sejak API level 33.
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.
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
Pada versi Android sebelumnya, beberapa font atau bahasa kursif yang memiliki
bentuk kompleks dapat menggambar huruf di area karakter sebelumnya atau berikutnya.
Dalam beberapa kasus, huruf tersebut dipangkas di posisi awal atau akhir.
Mulai Android 15, TextView mengalokasikan lebar untuk menggambar ruang yang cukup
untuk huruf tersebut dan memungkinkan aplikasi meminta padding tambahan ke kiri untuk
mencegah pemangkasan.
Karena perubahan ini memengaruhi cara TextView menentukan lebar, TextView
mengalokasikan lebih banyak lebar secara default jika aplikasi menargetkan Android 15 (level API 35) atau
yang lebih baru. Anda dapat mengaktifkan atau menonaktifkan perilaku ini dengan memanggil
setUseBoundsForWidth API di TextView.
Karena menambahkan padding kiri dapat menyebabkan ketidaksejajaran untuk tata letak yang ada, padding
tidak ditambahkan secara default bahkan untuk aplikasi yang menargetkan Android 15 atau yang lebih tinggi.
Namun, Anda dapat menambahkan padding tambahan untuk mencegah pemangkasan dengan memanggil
setShiftDrawingOffsetForStartOverhang.
Contoh berikut menunjukkan bagaimana perubahan ini dapat meningkatkan tata letak teks untuk beberapa font dan bahasa.
<TextView android:fontFamily="cursive" android:text="java" />
<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
<TextView android:text="คอมพิวเตอร์" />
<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
Tinggi baris default yang 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:
EditText yang
dapat berisi teks dari bahasa Inggris (en), Jepang (ja), dan Burma (my). Tinggi
EditText sama, meskipun bahasa ini
memiliki tinggi baris yang berbeda satu sama lain.Untuk aplikasi yang menargetkan Android 15 (API level 35), tinggi baris minimum kini
disediakan untuk EditText agar cocok dengan font referensi untuk Lokalitas yang ditentukan, seperti
yang ditunjukkan pada gambar berikut:
EditText yang
dapat berisi teks dari bahasa Inggris (en), Jepang (ja), dan Burma (my). Tinggi
EditText kini menyertakan ruang untuk mengakomodasi
tinggi baris default untuk font bahasa ini.Jika diperlukan, aplikasi Anda dapat memulihkan perilaku sebelumnya dengan menentukan
atribut useLocalePreferredLineHeightForMinimum
ke false, dan aplikasi Anda dapat menetapkan metrik vertikal minimum kustom menggunakan
setMinimumFontMetrics API di Kotlin dan Java.
Kamera dan media
Android 15 membuat perubahan berikut pada perilaku kamera dan media untuk aplikasi yang menargetkan Android 15 atau yang lebih tinggi.
Batasan pada permintaan fokus audio
以 Android 15(API 级别 35)为目标平台的应用必须是顶部应用或正在运行前台服务,才能请求音频焦点。如果应用在未满足上述任一要求的情况下尝试请求焦点,调用将返回 AUDIOFOCUS_REQUEST_FAILED。
如需详细了解音频焦点,请参阅管理音频焦点。
Pembatasan non-SDK yang diperbarui
Android 15 menyertakan daftar terbaru antarmuka non-SDK yang dibatasi berdasarkan kolaborasi dengan developer Android dan pengujian internal terbaru. Jika memungkinkan, kami akan memastikan ketersediaan alternatif publik sebelum membatasi antarmuka non-SDK.
Jika aplikasi Anda tidak menargetkan Android 15, beberapa perubahan ini mungkin tidak langsung memengaruhi Anda. Namun, meskipun aplikasi Anda dapat mengakses beberapa antarmuka non-SDK bergantung pada level API target aplikasi Anda, penggunaan metode atau kolom non-SDK apa pun tetap berisiko tinggi merusak aplikasi Anda.
Jika tidak yakin apakah aplikasi Anda menggunakan antarmuka non-SDK atau tidak, Anda dapat menguji aplikasi untuk mencari tahu. Jika aplikasi Anda mengandalkan antarmuka non-SDK, sebaiknya Anda mulai merencanakan migrasi ke alternatif SDK. Namun demikian, kami memahami bahwa beberapa aplikasi memiliki kasus penggunaan yang valid untuk menggunakan antarmuka non-SDK. Jika tidak dapat menemukan alternatif penggunaan antarmuka non-SDK untuk suatu fitur dalam aplikasi, Anda harus meminta API publik baru.
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.