Seperti rilis sebelumnya, Android 15 menyertakan perubahan perilaku yang dapat memengaruhi aplikasi Anda. Perubahan perilaku berikut ini berlaku khusus bagi aplikasi yang menargetkan Android 15 atau yang lebih tinggi. Jika aplikasi menargetkan Android 15 atau yang lebih tinggi, Anda harus memodifikasi aplikasi agar mendukung perilaku ini dengan benar, jika memungkinkan.
Selain itu, pastikan Anda meninjau daftar perubahan perilaku yang memengaruhi semua aplikasi
yang 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 melakukan perubahan berikut pada layanan latar depan dengan Android 15.
- Jenis layanan latar depan pemrosesan media baru
- Pembatasan pada penerima siaran
BOOT_COMPLETED
yang meluncurkan layanan latar depan
Perilaku waktu tunggu layanan latar depan sinkronisasi data
Android 15 对于以 Android 15 或更高版本为目标平台的应用,在 dataSync
中引入了新的超时行为。此行为也适用于新的 mediaProcessing
前台服务类型。
系统允许应用的 dataSync
服务在 24 小时内运行总共 6 小时,之后系统会调用正在运行的服务的 Service.onTimeout(int, int)
方法(在 Android 15 中引入)。此时,服务只有几秒钟的时间来调用 Service.stopSelf()
。当调用 Service.onTimeout()
时,该服务不再被视为前台服务。如果服务未调用 Service.stopSelf()
,则会发生故障,并显示以下错误消息:“A for 前台服务 (<fgs_type> does not stop in their timeout:
<component_name>)”。在 Beta 版 2 中,失败消息显示为 ANR,但在未来的 Beta 版中,此失败消息将抛出自定义异常。
为避免此行为变更出现问题,您可以执行以下一项或多项操作:
- 让您的服务实现新的
Service.onTimeout(int, int)
方法。当应用收到回调时,请确保在几秒钟内调用stopSelf()
。(如果您没有立即停止应用,系统会生成故障。) - 确保应用的
dataSync
服务在任何 24 小时内的运行时间总共不超过 6 小时(除非用户与应用互动,请重置计时器)。 - 仅因直接用户互动而启动
dataSync
前台服务;由于您的应用在服务启动时正处于前台,因此在它进入后台后,您的服务有整整六个小时的时间。 - 请使用替代 API,而不要使用
dataSync
前台服务。
如果应用的 dataSync
前台服务在过去 24 小时内运行了 6 小时,那么除非用户已将您的应用带到前台(这会重置计时器),否则您无法启动其他 dataSync
前台服务。如果您尝试启动另一个 dataSync
前台服务,系统会抛出 ForegroundServiceStartNotAllowedException
,并显示“时间限制已用完前台服务类型 dataSync 的时间限制”这样的错误消息。
Jenis layanan latar depan pemrosesan media baru
Android 15 memperkenalkan jenis layanan latar depan baru, mediaProcessing
. Jenis
layanan ini cocok untuk operasi seperti 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 terus berlanjut meskipun 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 sedang berjalan (diperkenalkan di Android
15). Saat ini, layanan memiliki beberapa detik untuk memanggil
Service.stopSelf()
. Jika layanan tidak
memanggil Service.stopSelf()
, kegagalan akan terjadi dengan pesan error ini: "Layanan
latar depan <fgs_type> tidak berhenti dalam waktu tunggunya:
<component_name>". Di Beta 2, pesan kegagalan ditampilkan sebagai
ANR, tetapi dalam rilis Beta mendatang, pesan kegagalan ini akan menampilkan pengecualian
kustom.
Untuk menghindari ANR, Anda dapat melakukan salah satu hal berikut:
- Minta layanan Anda mengimplementasikan metode
Service.onTimeout(int, int)
baru. Saat aplikasi menerima callback, pastikan untuk memanggilstopSelf()
dalam beberapa detik. (Jika Anda tidak langsung menghentikan aplikasi, sistem akan mengalami kegagalan.) - Pastikan layanan
mediaProcessing
aplikasi Anda tidak berjalan lebih dari total 6 jam dalam periode 24 jam (kecuali jika pengguna berinteraksi dengan aplikasi, menyetel ulang timer). - Hanya mulai layanan latar depan
mediaProcessing
sebagai hasil dari interaksi pengguna langsung; karena aplikasi 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 telah berjalan selama 6 jam dalam
24 terakhir, Anda tidak dapat memulai layanan latar depan mediaProcessing
lainnya kecuali
pengguna telah membawa aplikasi ke latar depan (yang mereset timer). Jika Anda
mencoba memulai layanan latar depan mediaProcessing
lain, sistem akan menampilkan
ForegroundServiceStartNotAllowedException
dengan pesan error seperti "Time limit alreadyUjis untuk jenis layanan latar depan mediaProcessing".
Untuk mengetahui informasi selengkapnya tentang jenis layanan mediaProcessing
, lihat Perubahan pada
jenis layanan latar depan untuk Android 15: Pemrosesan media.
Pembatasan pada BOOT_COMPLETED
penerima siaran yang meluncurkan layanan latar depan
Ada pembatasan baru pada penerima siaran BOOT_COMPLETED
yang meluncurkan
layanan latar depan. Penerima BOOT_COMPLETED
tidak diizinkan meluncurkan
jenis layanan latar depan berikut:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(pembatasan ini telah diterapkan untukmicrophone
sejak Android 14)
Jika penerima BOOT_COMPLETED
mencoba meluncurkan salah satu jenis layanan
latar depan tersebut, sistem akan menampilkan ForegroundServiceStartNotAllowedException
.
Pembatasan dalam memulai layanan latar depan saat aplikasi memiliki izin SYSTEM_ALERT_WINDOW
Previously, if an app held the SYSTEM_ALERT_WINDOW
permission, it could launch
a foreground service even if the app was currently in the background (as
discussed in exemptions from background start restrictions).
If an app targets Android 15, this exemption is now narrower. The app now needs
to have the SYSTEM_ALERT_WINDOW
permission and also have a visible overlay
window. That is, the app needs to first launch a
TYPE_APPLICATION_OVERLAY
window and the window
needs to be visible before you start a foreground service.
If your app attempts to start a foreground service from the background without
meeting these new requirements (and it does not have some other exemption), the
system throws ForegroundServiceStartNotAllowedException
.
If your app declares the SYSTEM_ALERT_WINDOW
permission
and launches foreground services from the background, it may be affected by this
change. If your app gets a ForegroundServiceStartNotAllowedException
, check
your app's order of operations and make sure your app already has an active
overlay window before it attempts to start a foreground service from the
background. You can check if your overlay window is currently visible
by calling View.getWindowVisibility()
, or you
can override View.onWindowVisibilityChanged()
to get notified whenever the visibility changes.
Testing
To test your app's behavior, you can enable these new restrictions even if your
app is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable these new restrictions on starting foreground services
from the background, run the following adb
command:
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 17
Android 15 会继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。
对于以 Android 15 为目标平台的应用,以下变更可能会影响应用兼容性:
字符串格式设置 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]);
语言代码处理方面的变更:使用
Locale
API 时,希伯来语、意第绪语和印度尼西亚语的语言代码不再转换为过时的形式(希伯来语:iw
、意第绪语:ji
和印度尼西亚语:in
)。在为其中一个语言区域指定语言代码时,请改用 ISO 639-1 中的代码:yi
、Yid1(希伯来语):yi
。he
id
随机 int 序列变更:在 https://bugs.openjdk.org/browse/JDK-8301574 中做出更改后,以下
Random.ints()
方法现在返回的数字序列现在与Random.nextInt()
方法不同:通常,此变更不会导致应用破坏行为,但您的代码不应期望从
Random.ints()
方法生成的序列与Random.nextInt()
匹配。
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 通过添加变更来防止恶意后台应用将其他应用带到前台、提升其权限和滥用用户互动,从而保护用户免受恶意应用的侵害,并使用户能够更好地控制其设备。从 Android 10(API 级别 29)开始,后台 activity 启动已受到限制。
阻止与堆栈中顶部 UID 不匹配的应用启动 activity
恶意应用可以在同一任务内启动另一个应用的 activity,然后叠加在上面,制造出作为该应用的错觉。这种“任务劫持”攻击绕过了当前的后台启动限制,因为它都发生在同一可见任务内。为了降低这种风险,Android 15 添加了一个标志,用于阻止与堆栈上的顶级 UID 不匹配的应用启动 activity。如需选择启用应用的所有 activity,请更新应用的 AndroidManifest.xml
文件中的 allowCrossUidActivitySwitchFromBelow
属性:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
如果满足以下所有条件,则新的安全措施就会生效:
- 执行启动的应用以 Android 15 为目标平台。
- 任务堆栈顶部的应用以 Android 15 为目标平台。
- 所有可见的活动均已启用新版保护措施
如果启用了安全措施,应用如果完成自己的任务,可能会返回主屏幕,而不是返回上一个可见的应用。
其他变更
除了 UID 匹配的限制之外,还包含以下其他更改:
- 将
PendingIntent
创建者更改为默认阻止后台 activity 启动。这有助于防止应用意外创建可能会被恶意操作者滥用的PendingIntent
。 - 请勿将应用置于前台,除非
PendingIntent
发送者允许该应用。此变更旨在防止恶意应用滥用在后台启动 activity 的功能。默认情况下,不允许应用将任务堆栈置于前台,除非创建者允许后台 activity 启动特权或发送者具有后台 activity 启动特权。 - 控制任务堆栈的顶层 activity 完成其任务的方式。如果顶层 activity 完成某项任务,Android 会返回到上次处于活动状态的任务。此外,如果非顶层 activity 完成其任务,Android 将返回主屏幕;它不会阻止此非顶部 activity 的完成。
- 防止将其他应用中的任意 activity 启动到您自己的任务中。这项变更会通过创建看似来自其他应用的活动,防止恶意应用向用户进行钓鱼式攻击。
- 阻止系统考虑将不可见窗口用于后台 activity 启动。这有助于防止恶意应用滥用后台 activity 启动来向用户显示不受欢迎或恶意内容。
Intent yang lebih aman
Android 15 引入了新的安全措施,使 intent 更加安全可靠。这些变更旨在防止潜在漏洞和被恶意应用利用的 intent 滥用。Android 15 中对 intent 的安全性进行了两项主要改进:
- 匹配目标 intent 过滤器:定位特定组件的 intent 必须准确匹配目标的 intent 过滤器规范。如果您通过发送 intent 来启动其他应用的 activity,则目标 intent 组件需要与接收 activity 声明的 intent 过滤器保持一致。
- intent 必须具有操作:没有操作的 intent 将不再与任何 intent 过滤器匹配。这意味着,用于启动 activity 或服务的 intent 必须具有明确定义的操作。
- 待处理 intent:待处理 intent 的创建者被视为封装 intent 的发送者,而非待处理 intent 的发送者
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
Pengalaman pengguna dan UI sistem
Android 15 menyertakan beberapa perubahan yang dimaksudkan untuk menciptakan pengalaman pengguna yang lebih konsisten dan intuitif.
Perubahan inset jendela
Ada dua perubahan 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 menargetkan Android 15 (level API 35).
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-1.png?authuser=4&hl=id)
Ini adalah perubahan yang dapat menyebabkan gangguan yang mungkin berdampak negatif terhadap UI aplikasi Anda. Perubahan tersebut memengaruhi area UI berikut:
- Menu navigasi handel gestur
- Transparan secara default.
- Offset bawah dinonaktifkan sehingga konten digambar di belakang menu navigasi sistem kecuali inset diterapkan.
setNavigationBarColor
danR.attr#navigationBarColor
tidak digunakan lagi dan tidak memengaruhi navigasi gestur.setNavigationBarContrastEnforced
danR.attr#navigationBarContrastEnforced
tetap tidak berpengaruh pada navigasi gestur.
- Navigasi 3 tombol
- Opasitas ditetapkan ke 80% secara default, dengan warna yang mungkin cocok dengan latar belakang jendela.
- Offset bawah dinonaktifkan sehingga konten digambar di belakang menu navigasi sistem kecuali inset diterapkan.
setNavigationBarColor
danR.attr#navigationBarColor
disetel 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
danR.attr#navigationBarContrastEnforced
bernilai benar (true) secara default, yang menambahkan latar belakang buram 80% di navigasi 3 tombol.
- Status bar
- Transparan secara default.
- Offset atas dinonaktifkan sehingga konten digambar di belakang status bar kecuali inset diterapkan.
setStatusBarColor
danR.attr#statusBarColor
tidak digunakan lagi dan tidak berpengaruh di Android 15.setStatusBarContrastEnforced
danR.attr#statusBarContrastEnforced
tidak digunakan lagi, tetapi masih berpengaruh di Android 15.
- Potongan layar
layoutInDisplayCutoutMode
dari jendela yang tidak mengambang harusLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.SHORT_EDGES
,NEVER
, danDEFAULT
ditafsirkan sebagaiALWAYS
sehingga pengguna tidak melihat batang Hitam yang disebabkan oleh potongan layar dan muncul dari tepi ke tepi.
Contoh berikut menunjukkan aplikasi sebelum dan sesudah menargetkan Android 15 (level API 35), serta sebelum dan sesudah menerapkan inset.
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-4.png?authuser=4&hl=id)
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-6.png?authuser=4&hl=id)
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-2.png?authuser=4&hl=id)
Yang harus diperiksa apakah aplikasi Anda sudah berada di layar penuh
Jika aplikasi Anda sudah bersifat edge-to-edge dan menerapkan inset, sebagian besar tidak akan terpengaruh, kecuali dalam skenario berikut. Namun, meskipun Anda merasa tidak terpengaruh, sebaiknya uji aplikasi Anda.
- Anda memiliki jendela yang tidak mengambang, seperti
Activity
yang menggunakanSHORT_EDGES
,NEVER
, atauDEFAULT
, bukanLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. Jika aplikasi Anda error saat peluncuran, hal ini mungkin disebabkan oleh layar pembuka. Anda dapat mengupgrade dependensi layar pembuka inti ke 1.2.0-alpha01 atau yang lebih baru, atau menetapkanwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Mungkin ada layar dengan traffic yang lebih rendah dengan UI yang terhalang. Pastikan
layar yang kurang dikunjungi ini tidak memiliki UI yang terhalang. 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. Selain skenario untuk aplikasi yang sudah layar penuh, Anda harus mempertimbangkan hal berikut:
- Jika aplikasi Anda menggunakan Komponen Material 3 (
androidx.compose.material3
) di compose, sepertiTopAppBar
,BottomAppBar
, danNavigationBar
, komponen ini mungkin tidak terpengaruh karena otomatis menangani inset. - Jika aplikasi Anda menggunakan Komponen Material 2 (
androidx.compose.material
) di Compose, komponen ini tidak otomatis menangani inset. Namun, Anda bisa mendapatkan akses ke inset dan menerapkannya secara manual. Di androidx.compose.material 1.6.0 dan yang lebih baru, gunakan parameterwindowInsets
untuk menerapkan inset secara manual untukBottomAppBar
,TopAppBar
,BottomNavigation
, danNavigationRail
. Demikian pula, gunakan parametercontentWindowInsets
untukScaffold
. - Jika aplikasi Anda menggunakan tampilan dan Komponen Material
(
com.google.android.material
), sebagian besar Komponen Material berbasis tampilan sepertiBottomNavigationView
,BottomAppBar
,NavigationRailView
, atauNavigationView
, akan menangani inset dan tidak memerlukan pekerjaan tambahan. Namun, Anda perlu menambahkanandroid:fitsSystemWindows="true"
jika menggunakanAppBarLayout
. - Untuk composable kustom, terapkan inset secara manual sebagai padding. Jika
konten Anda berada dalam
Scaffold
, Anda dapat menggunakan inset menggunakan nilai paddingScaffold
. Jika tidak, terapkan padding menggunakan salah satuWindowInsets
. - Jika aplikasi Anda menggunakan tampilan dan
BottomSheet
,SideSheet
, atau penampung khusus, terapkan padding menggunakanViewCompat.setOnApplyWindowInsetsListener
. UntukRecyclerView
, terapkan padding menggunakan pemroses ini dan juga tambahkanclipToPadding="false"
.
Yang harus diperiksa apakah aplikasi Anda harus menawarkan perlindungan latar belakang kustom
Jika aplikasi Anda harus menawarkan perlindungan latar belakang kustom untuk navigasi 3 tombol atau
status bar, aplikasi Anda harus menempatkan composable atau tampilan di belakang kolom sistem
menggunakan WindowInsets.Type#tappableElement()
untuk mendapatkan tinggi menu
navigasi 3 tombol atau WindowInsets.Type#statusBars
.
Resource tata letak layar penuh tambahan
Lihat panduan Tampilan Edge to Edge dan Edge to Edge Compose untuk pertimbangan tambahan terkait penerapan inset.
API yang tidak digunakan lagi
API berikut sekarang tidak digunakan lagi:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#isStatusBarContrastEnforced
Window#setDecorFitsSystemWindows
Window#setNavigationBarColor
Window#setNavigationBarDividerColor
Window#setStatusBarColor
Window#setStatusBarContrastEnforced
Konfigurasi stabil
If your app targets Android 15 (API level 35) or higher, Configuration
no
longer excludes the system bars. If you use the screen size in the
Configuration
class for layout calculation, you should replace it with better
alternatives like an appropriate ViewGroup
, WindowInsets
, or
WindowMetricsCalculator
depending on your need.
Configuration
has been available since API 1. It is typically obtained from
Activity.onConfigurationChanged
. It provides information like window density,
orientation, and sizes. One important characteristic about the window sizes
returned from Configuration
is that it previously excluded the system bars.
The configuration size is typically used for resource selection, such as
/res/layout-h500dp
, and this is still a valid use case. However, using it for
layout calculation has always been discouraged. If you do so, you should move
away from it now. You should replace the use of Configuration
with something
more suitable depending on your use case.
If you use it to calculate the layout, use an appropriate ViewGroup
, such as
CoordinatorLayout
or ConstraintLayout
. If you use it to determine the height
of the system navbar, use WindowInsets
. If you want to know the current size
of your app window, use computeCurrentWindowMetrics
.
The following list describes the fields affected by this change:
Configuration.screenWidthDp
andscreenHeightDp
sizes no longer exclude the system bars.Configuration.smallestScreenWidthDp
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
.Configuration.orientation
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
on close-to-square devices.Display.getSize(Point)
is indirectly affected by the changes inConfiguration
. This was deprecated beginning in API level 30.Display.getMetrics()
has already worked like this since API level 33.
Atribut eleganTextHeight ditetapkan secara default ke benar (true)
对于以 Android 15 为目标平台的应用,elegantTextHeight
TextView
属性默认变为 true
,将默认使用的紧凑字体替换为一些具有较大垂直指标的脚本,并且这种字体更易于阅读。紧凑字体的引入是为了防止破坏布局;Android 13(API 级别 33)允许文本布局利用 fallbackLineSpacing
属性拉伸垂直高度,以防止许多此类破坏。
在 Android 15 中,紧凑字体仍保留在系统中,因此您的应用可以将 elegantTextHeight
设置为 false
,以获得与之前相同的行为,但即将在未来版本中提供支持。因此,如果您的应用支持以下文字:阿拉伯语、老挝语、缅甸、泰米尔语、古吉拉特语、卡纳达语、马拉雅拉姆语、奥里亚语、泰卢固语或泰语,请将 elegantTextHeight
设置为 true
,以测试应用。
![](https://developer.android.google.cn/static/about/versions/15/images/elegant-text-height-before.png?authuser=4&hl=id)
elegantTextHeight
行为。![](https://developer.android.google.cn/static/about/versions/15/images/elegant-text-height-after.png?authuser=4&hl=id)
elegantTextHeight
行为。Perubahan lebar TextView untuk bentuk huruf yang kompleks
Pada versi Android sebelumnya, beberapa font atau bahasa tulis tangan yang memiliki
pembentukan kompleks dapat menggambar huruf di area karakter sebelumnya atau berikutnya.
Terkadang, huruf seperti itu 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 agar
tidak terpotong.
Karena perubahan ini memengaruhi cara TextView
menentukan lebar, TextView
mengalokasikan lebih banyak lebar secara default jika aplikasi menargetkan Android 15 atau yang lebih tinggi. Anda dapat mengaktifkan atau menonaktifkan perilaku ini dengan memanggil API setUseBoundsForWidth
pada TextView
.
Karena penambahan 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 pemotongan dengan memanggil
setShiftDrawingOffsetForStartOverhang
.
Contoh berikut menunjukkan bagaimana perubahan ini dapat meningkatkan tata letak teks untuk beberapa font dan bahasa.
![](https://developer.android.google.cn/static/about/versions/15/images/cursive-clipped.png?authuser=4&hl=id)
<TextView android:fontFamily="cursive" android:text="java" />
![](https://developer.android.google.cn/static/about/versions/15/images/cursive-noclipping.png?authuser=4&hl=id)
<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
![](https://developer.android.google.cn/static/about/versions/15/images/thai-clipped.png?authuser=4&hl=id)
<TextView android:text="คอมพิวเตอร์" />
![](https://developer.android.google.cn/static/about/versions/15/images/thai-noclipping.png?authuser=4&hl=id)
<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
Tinggi baris default berbasis lokal untuk EditText
在以前的 Android 版本中,文本布局拉伸了文本的高度,使其适应与当前语言区域匹配的字体的行高。例如,如果内容是日语,由于日语字体的行高比拉丁字体的行高略大,因此文本的高度就略大了。不过,尽管行高存在这些差异,但无论使用何种语言区域,EditText
元素的大小都是一致的,如下图所示:
![](https://developer.android.google.cn/static/about/versions/15/images/locale-aware-line-height-before.png?authuser=4&hl=id)
EditText
元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText
的高度相同,即使这两种语言的行高不同。对于以 Android 15 为目标平台的应用,系统现在会为 EditText
预留最小行高,以匹配指定语言区域的参考字体,如下图所示:
![](https://developer.android.google.cn/static/about/versions/15/images/locale-aware-line-height-after.png?authuser=4&hl=id)
EditText
元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText
的高度现在包含空间,可适应这些语言字体的默认行高。如果需要,您的应用可以通过将 useLocalePreferredLineHeightForMinimum
属性设置为 false
来恢复之前的行为,并且可以通过 Kotlin 和 Java 中的 setMinimumFontMetrics
API 设置自定义最小行业指标。
Kamera dan media
Android 15 melakukan perubahan berikut pada perilaku kamera dan media untuk aplikasi yang menargetkan Android 15 atau yang lebih baru.
Batasan dalam meminta fokus audio
以 Android 15 为目标平台的应用必须是热门应用或运行与音频相关的前台服务,才能请求音频焦点。如果应用在不符合其中任何一项要求时尝试请求焦点,调用会返回 AUDIOFOCUS_REQUEST_FAILED
。
如果前台服务的类型为 mediaPlayback
、camera
、microphone
或 phoneCall
,则会被视为与音频相关。
如需详细了解音频焦点,请参阅管理音频焦点。
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 tetap sangat berisiko 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. Meskipun demikian, kami memahami bahwa beberapa aplikasi memiliki kasus penggunaan yang valid untuk menggunakan antarmuka non-SDK. Jika Anda tidak dapat menemukan alternatif penggunaan antarmuka non-SDK untuk fitur dalam aplikasi Anda, sebaiknya minta API publik baru.
Untuk mempelajari perubahan dalam rilis Android ini lebih lanjut, baca Pembaruan pembatasan antarmuka non-SDK di Android 15. Untuk mempelajari lebih lanjut antarmuka non-SDK secara umum, baca Pembatasan antarmuka non-SDK.