行為變更:指定 Android 15 以上版本的應用程式

和先前版本一樣,Android 15 也包含可能會影響應用程式的行為變更。以下行為變更僅適用於指定 Android 15 以上版本的應用程式。如果您的應用程式指定 Android 15 以上版本,建議您視情況修改應用程式,以支援這些行為。

此外,無論應用程式的 targetSdkVersion 為何,請務必查看對所有 Android 15 應用程式有影響的行為變更清單。

核心功能

Android 15 修改或擴充了 Android 系統的各種核心功能。

前景服務異動

我們將對 Android 15 的前景服務進行下列異動。

資料同步處理前景服務逾時行為

Android 15 introduces a new timeout behavior to dataSync for apps targeting Android 15 (API level 35) or higher. This behavior also applies to the new mediaProcessing foreground service type.

The system permits an app's dataSync services to run for a total of 6 hours in a 24-hour period, after which the system calls the running service's Service.onTimeout(int, int) method (introduced in Android 15). At this time, the service has a few seconds to call Service.stopSelf(). When Service.onTimeout() is called, the service is no longer considered a foreground service. If the service does not call Service.stopSelf(), the system throws an internal exception. The exception is logged in Logcat with the following message:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"

To avoid problems with this behavior change, you can do one or more of the following:

  1. Have your service implement the new Service.onTimeout(int, int) method. When your app receives the callback, make sure to call stopSelf() within a few seconds. (If you don't stop the app right away, the system generates a failure.)
  2. Make sure your app's dataSync services don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer).
  3. Only start dataSync foreground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background.
  4. Instead of using a dataSync foreground service, use an alternative API.

If your app's dataSync foreground services have run for 6 hours in the last 24, you cannot start another dataSync foreground service unless the user has brought your app to the foreground (which resets the timer). If you try to start another dataSync foreground service, the system throws ForegroundServiceStartNotAllowedException with an error message like "Time limit already exhausted for foreground service type dataSync".

Testing

To test your app's behavior, you can enable data sync timeouts even if your app is not targeting Android 15 (as long as the app is running on an Android 15 device). To enable timeouts, run the following adb command:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

You can also adjust the timeout period, to make it easier to test how your app behaves when the limit is reached. To set a new timeout period, run the following adb command:

adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds

新的媒體處理前景服務類型

Android 15 introduces a new foreground service type, mediaProcessing. This service type is appropriate for operations like transcoding media files. For example, a media app might download an audio file and need to convert it to a different format before playing it. You can use a mediaProcessing foreground service to make sure the conversion continues even while the app is in the background.

The system permits an app's mediaProcessing services to run for a total of 6 hours in a 24-hour period, after which the system calls the running service's Service.onTimeout(int, int) method (introduced in Android 15). At this time, the service has a few seconds to call Service.stopSelf(). If the service does not call Service.stopSelf(), the system throws an internal exception. The exception is logged in Logcat with the following message:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"

To avoid having the exception, you can do one of the following:

  1. Have your service implement the new Service.onTimeout(int, int) method. When your app receives the callback, make sure to call stopSelf() within a few seconds. (If you don't stop the app right away, the system generates a failure.)
  2. Make sure your app's mediaProcessing services don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer).
  3. Only start mediaProcessing foreground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background.
  4. Instead of using a mediaProcessing foreground service, use an alternative API, like WorkManager.

If your app's mediaProcessing foreground services have run for 6 hours in the last 24, you cannot start another mediaProcessing foreground service unless the user has brought your app to the foreground (which resets the timer). If you try to start another mediaProcessing foreground service, the system throws ForegroundServiceStartNotAllowedException with an error message like "Time limit already exhausted for foreground service type mediaProcessing".

For more information about the mediaProcessing service type, see Changes to foreground service types for Android 15: Media processing.

Testing

To test your app's behavior, you can enable media processing timeouts even if your app is not targeting Android 15 (as long as the app is running on an Android 15 device). To enable timeouts, run the following adb command:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

You can also adjust the timeout period, to make it easier to test how your app behaves when the limit is reached. To set a new timeout period, run the following adb command:

adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds

BOOT_COMPLETED 廣播接收器啟動前景服務的限制

There are new restrictions on BOOT_COMPLETED broadcast receivers launching foreground services. BOOT_COMPLETED receivers are not allowed to launch the following types of foreground services:

If a BOOT_COMPLETED receiver tries to launch any of those types of foreground services, the system throws ForegroundServiceStartNotAllowedException.

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). Run the following adb command:

adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name

To send a BOOT_COMPLETED broadcast without restarting the device, run the following adb command:

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

應用程式擁有 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

應用程式可修改「零打擾」模式全域狀態的時間異動

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.

OpenJDK API 變更

Android 15 持續更新 Android 核心程式庫,以便與最新版 OpenJDK LTS 中的功能保持一致。

如果應用程式指定 Android 15 (API 級別 35),以下部分變更可能會影響應用程式相容性:

  • 字串格式化 API 的變更:使用下列 String.format()Formatter.format() API 時,系統現在會更嚴格地驗證引數索引、旗標、寬度和精確度:

    舉例來說,使用引數索引 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 的代碼 (希伯來文:he、意第緒文:yi、印尼文:id)。

  • 隨機整數序列的變更:根據 https://bugs.openjdk.org/browse/JDK-8301574 中所做的變更,下列 Random.ints() 方法現在會傳回與 Random.nextInt() 方法不同的數字序列:

    一般來說,這項變更不會導致應用程式發生中斷行為,但您的程式碼不應預期從 Random.ints() 方法產生的序列會與 Random.nextInt() 相符。

在應用程式的建構設定中更新 compileSdk,改用 Android 15 (API 級別 35) 後,新的 SequencedCollection API 可能會影響應用程式的相容性:

  • kotlin-stdlib 中的 MutableList.removeFirst()MutableList.removeLast() 擴充函式發生衝突

    Java 中的 List 型別會對應至 Kotlin 中的 MutableList 型別。由於 Android 15 (API 級別 35) 中已導入 List.removeFirst()List.removeLast() API,Kotlin 編譯器會將函式呼叫 (例如 list.removeFirst()) 靜態解析為新的 List API,而不是 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 外掛程式中的現有 NewApi lint 選項可以偵測這些新 API 用法。

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

    如要修正執行階段例外狀況和 Lint 錯誤,可以在 Kotlin 中將 removeFirst()removeLast() 函式呼叫分別替換為 removeAt(0)removeAt(list.lastIndex)。如果您使用 Android Studio Ladybug | 2024.1.3 以上版本,也可以選擇快速修正這些錯誤。

    如果已停用 Lint 選項,請考慮移除 @SuppressLint("NewApi")lintOptions { disable 'NewApi' }

  • 與 Java 中的其他方法發生衝突

    現有型別已新增方法,例如 ListDeque。這些新方法可能與其他介面和類別中,名稱和引數類型相同的方法不相容。如果方法簽章與不相容的項目發生衝突,javac 編譯器會輸出建構時間錯誤。例如:

    錯誤示例 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
    

    錯誤示例 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
    

    錯誤示例 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
    

    如要修正這些建構錯誤,實作這些介面的類別應使用相容的回傳型別覆寫方法。例如:

    @Override
    public Object getFirst() {
        return List.super.getFirst();
    }
    

安全性

Android 15 包含多項變更,可提升系統安全性,協助保護應用程式和使用者免受惡意應用程式侵害。

受限的 TLS 版本

Android 15 會限制 TLS 1.0 和 1.1 版本的使用。這些版本先前已在 Android 中淘汰,但現在已禁止用於指定 Android 15 為目標版本的應用程式。

安全啟動背景活動

Android 15 protects users from malicious apps and gives them more control over their devices by adding changes that prevent malicious background apps from bringing other apps to the foreground, elevating their privileges, and abusing user interaction. Background activity launches have been restricted since Android 10 (API level 29).

Other changes

  • Change PendingIntent creators to block background activity launches by default. This helps prevent apps from accidentally creating a PendingIntent that could be abused by malicious actors.
  • Don't bring an app to the foreground unless the PendingIntent sender allows it. This change aims to prevent malicious apps from abusing the ability to start activities in the background. By default, apps are not allowed to bring the task stack to the foreground unless the creator allows background activity launch privileges or the sender has background activity launch privileges.
  • Control how the top activity of a task stack can finish its task. If the top activity finishes a task, Android will go back to whichever task was last active. Moreover, if a non-top activity finishes its task, Android will go back to the home screen; it won't block the finish of this non-top activity.
  • Prevent launching arbitrary activities from other apps into your own task. This change prevents malicious apps from phishing users by creating activities that appear to be from other apps.
  • Block non-visible windows from being considered for background activity launches. This helps prevent malicious apps from abusing background activity launches to display unwanted or malicious content to users.

更安全的意圖

Android 15 推出了新的選用安全措施,讓意圖更安全、更健全。這些異動旨在防止意圖遭到惡意應用程式濫用,並避免潛在的安全漏洞。Android 15 對意圖的安全性有兩項主要改善:

  • 比對目標意圖篩選器:指定特定元件的意圖必須準確比對目標的意圖篩選器規格。如果傳送 意圖啟動其他應用程式的活動,目標意圖元件 對應至接收活動宣告的意圖篩選器
  • 意圖必須包含動作:沒有動作的意圖將不再與任何意圖篩選器相符。這表示用於啟動活動或 服務必須具有明確定義的動作

如要檢查應用程式如何回應這些變更,請在應用程式中使用 StrictMode。如要查看 Intent 使用違規的詳細記錄,請新增下列方法:

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        .detectUnsafeIntentLaunch()
        .build()
    )
}

Java

public void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
            .detectUnsafeIntentLaunch()
            .build());
}

使用者體驗和系統 UI

Android 15 包含一些變更,旨在打造更一致、直覺的使用者體驗。

視窗插邊變更

Android 15 有兩項與視窗內嵌相關的變更:預設會強制執行邊到邊,且有設定變更,例如系統列的預設設定。

邊緣到邊緣強制執行

Apps are edge-to-edge by default on devices running Android 15 if the app is targeting Android 15 (API level 35).

An app that targets Android 14 and is not edge-to-edge on an Android 15 device.


An app that targets Android 15 (API level 35) and is edge-to-edge on an Android 15 device. This app mostly uses Material 3 Compose Components that automatically apply insets. This screen is not negatively impacted by the Android 15 edge-to-edge enforcement.

This is a breaking change that might negatively impact your app's UI. The changes affect the following UI areas:

  • Gesture handle navigation bar
    • Transparent by default.
    • Bottom offset is disabled so content draws behind the system navigation bar unless insets are applied.
    • setNavigationBarColor and R.attr#navigationBarColor are deprecated and don't affect gesture navigation.
    • setNavigationBarContrastEnforced and R.attr#navigationBarContrastEnforced continue to have no effect on gesture navigation.
  • 3-button navigation
    • Opacity set to 80% by default, with color possibly matching the window background.
    • Bottom offset disabled so content draws behind the system navigation bar unless insets are applied.
    • setNavigationBarColor and R.attr#navigationBarColor are set to match the window background by default. The window background must be a color drawable for this default to apply. This API is deprecated but continues to affect 3-button navigation.
    • setNavigationBarContrastEnforced and R.attr#navigationBarContrastEnforced is true by default, which adds an 80% opaque background across 3-button navigation.
  • Status bar
    • Transparent by default.
    • The top offset is disabled so content draws behind the status bar unless insets are applied.
    • setStatusBarColor and R.attr#statusBarColor are deprecated and have no effect on Android 15.
    • setStatusBarContrastEnforced and R.attr#statusBarContrastEnforced are deprecated but still have an effect on Android 15.
  • Display cutout
    • layoutInDisplayCutoutMode of non-floating windows must be LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. SHORT_EDGES, NEVER, and DEFAULT are interpreted as ALWAYS so that users don't see a black bar caused by the display cutout and appear edge-to-edge.

The following example shows an app before and after targeting Android 15 (API level 35), and before and after applying insets. This example is not comprehensive, this might appear differently on Android Auto.

An app that targets Android 14 and is not edge-to-edge on an Android 15 device.
An app that targets Android 15 (API level 35) and is edge-to-edge on an Android 15 device. However, many elements are now hidden by the status bar, 3-button navigation bar, or display cutout due to the Android 15 edge-to-edge enforcements. Hidden UI includes the Material 2 top app bar, floating action buttons, and list items.
An app that targets Android 15 (API level 35), is edge to edge on an Android 15 device and applies insets so that UI is not hidden.
What to check if your app is already edge-to-edge

If your app is already edge-to-edge and applies insets, you are mostly unimpacted, except in the following scenarios. However, even if you think you aren't impacted, we recommend you test your app.

  • You have a non-floating window, such as an Activity that uses SHORT_EDGES, NEVER or DEFAULT instead of LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. If your app crashes on launch, this might be due to your splashscreen. You can either upgrade the core splashscreen dependency to 1.2.0-alpha01 or later or set window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always.
  • There might be lower-traffic screens with occluded UI. Verify these less-visited screens don't have occluded UI. Lower-traffic screens include:
    • Onboarding or sign-in screens
    • Settings pages
What to check if your app is not already edge-to-edge

If your app is not already edge-to-edge, you are most likely impacted. In addition to the scenarios for apps that are already edge-to-edge, you should consider the following:

  • If your app uses Material 3 Components ( androidx.compose.material3) in compose, such as TopAppBar, BottomAppBar, and NavigationBar, these components are likely not impacted because they automatically handle insets.
  • If your app is using Material 2 Components ( androidx.compose.material) in Compose, these components don't automatically handle insets. However, you can get access to the insets and apply them manually. In androidx.compose.material 1.6.0 and later, use the windowInsets parameter to apply the insets manually for BottomAppBar, TopAppBar, BottomNavigation, and NavigationRail. Likewise, use the contentWindowInsets parameter for Scaffold.
  • If your app uses views and Material Components (com.google.android.material), most views-based Material Components such as BottomNavigationView, BottomAppBar, NavigationRailView, or NavigationView, handle insets and require no additional work. However, you need to add android:fitsSystemWindows="true" if using AppBarLayout.
  • For custom composables, apply the insets manually as padding. If your content is within a Scaffold, you can consume insets using the Scaffold padding values. Otherwise, apply padding using one of the WindowInsets.
  • If your app is using views and BottomSheet, SideSheet or custom containers, apply padding using ViewCompat.setOnApplyWindowInsetsListener. For RecyclerView, apply padding using this listener and also add clipToPadding="false".
What to check if your app must offer custom background protection

If your app must offer custom background protection to 3-button navigation or the status bar, your app should place a composable or view behind the system bar using WindowInsets.Type#tappableElement() to get the 3-button navigation bar height or WindowInsets.Type#statusBars.

Additional edge-to-edge resources

See the Edge to Edge Views and Edge to Edge Compose guides for additional considerations on applying insets.

Deprecated APIs

The following APIs are deprecated but not disabled:

The following APIs are deprecated and disabled:

穩定設定

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:

elegantTextHeight 屬性預設為 true

針對指定 Android 15 (API 級別 35) 的應用程式,elegantTextHeight TextView 屬性預設會變成 true,將預設使用的緊湊字型取代為具有大型垂直指標的某些指令碼,以便更容易閱讀。我們推出了精簡字型,以免版面配置中斷;Android 13 (API 級別 33) 允許文字版面配置利用 fallbackLineSpacing 屬性拉長垂直高度,藉此避免許多這類中斷情形。

在 Android 15 中,系統仍會保留精簡字型,因此應用程式可以將 elegantTextHeight 設為 false,以便取得與先前相同的行為,但未來版本不太可能支援這項功能。因此,如果您的應用程式支援下列文字:阿拉伯文、老撾文、緬甸文、泰米爾文、古吉拉特文、卡納達文、馬拉雅拉姆文、奧里雅文、泰盧固文或泰文,請將 elegantTextHeight 設為 true 來測試應用程式。

elegantTextHeight 指定 Android 14 (API 級別 34) 以下版本為目標版本的應用程式行為。
elegantTextHeight 指定 Android 15 為目標版本的應用程式行為。

複雜字母形狀的 TextView 寬度變化

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" />

EditText 的預設行高會因語言代碼而異

在 Android 先前版本中,文字版面配置會拉伸文字高度,以符合與目前語言代碼相符的字型行高。舉例來說,如果內容是日文,由於日文字型的行高略大於拉丁字型,因此文字高度會稍微變高。不過,儘管行高有這些差異,EditText 元素的大小仍保持一致,不受使用語言代碼影響,如下圖所示:

三個方塊代表 EditText 元素,可包含英文 (en)、日文 (ja) 和緬甸文 (my) 的文字。EditText 的高度相同,即使這些語言的行高不同。

針對指定 Android 15 (API 級別 35) 的應用程式,現在會為 EditText 保留最小行高,以便與指定語言代碼的參考字型相符,如以下圖片所示:

三個方塊代表 EditText 元素,可包含英文 (en)、日文 (ja) 和緬甸文 (my) 的文字。EditText 的高度現在包含空格,可容納這些語言字型預設的行高。

如有需要,應用程式可以將 useLocalePreferredLineHeightForMinimum 屬性指定為 false,藉此還原先前的行為,並使用 Kotlin 和 Java 中的 setMinimumFontMetrics API 設定自訂的垂直最小指標。

相機和媒體

Android 15 對指定 Android 15 以上版本的應用程式,進行了下列攝影機和媒體行為變更。

要求音訊焦點的限制

Apps that target Android 15 (API level 35) must be the top app or running a foreground service in order to request audio focus. If an app attempts to request focus when it does not meet one of these requirements, the call returns AUDIOFOCUS_REQUEST_FAILED.

You can learn more about audio focus at Manage audio focus.

更新非 SDK 限制

基於與 Android 開發人員合作及最新的內部測試,Android 15 包含更新後的受限制非 SDK 介面清單。在限制非 SDK 介面之前,我們盡可能確保公開替代方案的可得性。

如果您的應用程式並不是以 Android 15 為目標版本,則此處所述的某些變更可能不會立即對您造成影響。不過,應用程式視目標 API 級別而定,可能可以存取某些非 SDK 介面,但使用任何非 SDK 方法或欄位時,應用程式停止運作的風險極高。

如果不確定應用程式是否使用非 SDK 介面,可測試應用程式以便確認。如果應用程式仰賴非 SDK 介面,則應開始規劃遷移至 SDK 替代方案。不過我們瞭解,有些應用程式可使用非 SDK 介面運作。如果您除了為應用程式中的某個功能使用非 SDK 介面外,已別無他法,則應要求新的公用 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.