功能與 API 總覽

Android 15 為開發人員推出了強大的功能和 API。以下各節會簡要說明這些功能,協助您開始使用相關 API。

如需新增、修改及移除 API 的詳細清單,請參閱 API 差異比較表。如要進一步瞭解新增的 API,請參閱 Android API 參考資料 - 針對 Android 15,請尋找 API 級別 35 中新增的 API。如要瞭解平台變更可能對應用程式造成的影響,請務必查看指定 Android 15 的應用程式所有應用程式的 Android 15 行為變更。

相機和媒體

Android 15 包含多種功能,可提升相機和媒體體驗,並提供工具和硬體,協助創作者在 Android 上實現願景。

如要進一步瞭解 Android 媒體和相機的最新功能和開發人員解決方案,請參閱 Google I/O 的「打造現代 Android 媒體和相機體驗」演講。

低光源增強

Android 15 introduces Low Light Boost, an auto-exposure mode available to both Camera 2 and the night mode camera extension. Low Light Boost adjusts the exposure of the Preview stream in low-light conditions. This is different from how the night mode camera extension creates still images, because night mode combines a burst of photos to create a single, enhanced image. While night mode works very well for creating a still image, it can't create a continuous stream of frames, but Low Light Boost can. Thus, Low Light Boost enables camera capabilities, such as:

  • Providing an enhanced image preview, so users are better able to frame their low-light pictures
  • Scanning QR codes in low light

If you enable Low Light Boost, it automatically turns on when there's a low light level, and turns off when there's more light.

Apps can record off the Preview stream in low-light conditions to save a brightened video.

For more information, see Low Light Boost.

應用程式內攝影機控制選項

Android 15 adds an extension for more control over the camera hardware and its algorithms on supported devices:

  • Advanced flash strength adjustments enabling precise control of flash intensity in both SINGLE and TORCH modes while capturing images.

HDR 動態範圍控制

Android 15 chooses HDR headroom that is appropriate for the underlying device capabilities and bit-depth of the panel. For pages that have lots of SDR content, such as a messaging app displaying a single HDR thumbnail, this behavior can end up adversely influencing the perceived brightness of the SDR content. Android 15 lets you control the HDR headroom with setDesiredHdrHeadroom to strike a balance between SDR and HDR content.

The brightness of SDR UI elements on the left screen appears to be more uniform than the brightness on the right screen, which simulates possible headroom issues when HDR and SDR content are mixed. By adjusting the HDR headroom, you can achieve a better balance between the SDR and HDR content.

音量控制

Android 15 開始支援 CTA-2075 音量標準,協助您 可避免音訊音量不一致的情況,同時確保使用者不必一直 調整音量。系統會利用輸出裝置 (耳機和喇叭) 的已知特性,以及 AAC 音訊內容提供的音量中繼資料,智慧調整音訊音量和動態範圍壓縮等級。

如要啟用這項功能,請務必確保檔案含有音量中繼資料 您的 AAC 內容,並在應用程式中啟用平台功能。為此,您 透過以下方式將 LoudnessCodecController 物件執行個體化: 呼叫其 create 工廠方法,並與音訊 來自相關聯 AudioTrack 的工作階段 ID;本 系統就會開始自動套用音訊更新您可以傳遞 OnLoudnessCodecUpdateListener,藉此修改或篩選音量參數,再套用至 MediaCodec

// Media contains metadata of type MPEG_4 OR MPEG_D
val mediaCodec = 
val audioTrack = AudioTrack.Builder()
                                .setSessionId(sessionId)
                                .build()
...
// Create new loudness controller that applies the parameters to the MediaCodec
try {
   val lcController = LoudnessCodecController.create(mSessionId)
   // Starts applying audio updates for each added MediaCodec
}

AndroidX media3 ExoPlayer 也會更新,使用 透過 LoudnessCodecController API 完美整合應用程式。

虛擬 MIDI 2.0 裝置

Android 13 added support for connecting to MIDI 2.0 devices using USB, which communicate using Universal MIDI Packets (UMP). Android 15 extends UMP support to virtual MIDI apps, enabling composition apps to control synthesizer apps as a virtual MIDI 2.0 device just like they would with an USB MIDI 2.0 device.

更有效率的 AV1 軟體解碼

dav1d logo

dav1d, the popular AV1 software decoder from VideoLAN is available for Android devices that don't support AV1 decode in hardware. dav1d is up to 3x more performant than the legacy AV1 software decoder, enabling HD AV1 playback for more users, including some low and mid tier devices.

Your app needs to opt-in to using dav1d by invoking it by name "c2.android.av1-dav1d.decoder". dav1d will be made the default AV1 software decoder in a subsequent update. This support is standardized and backported to Android 11 devices that receive Google Play system updates.

開發人員工作效率和工具

我們致力於提升開發人員的工作效率,因此大部分工作都圍繞著 Android StudioJetpack ComposeAndroid Jetpack 程式庫等工具進行,但我們也不斷尋找平台上的各種方法,協助您更輕鬆地實現願景。

OpenJDK 17 更新

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

這次更新包含以下重點功能和改善項目:

這些 API 會透過 Google Play 系統更新,在搭載 Android 12 (API 級別 31) 以上版本的 10 億部裝置上進行更新,因此您可以指定最新的程式設計功能。

PDF 改善項目

Android 15 對 PdfRenderer 進行了大幅改善。 相互整合應用程式可導入轉譯等進階功能 受密碼保護的檔案、註解、表單編輯搜尋選取副本。支援線性化 PDF 最佳化功能,可加快本機 PDF 檢視速度並減少資源使用量。Jetpack PDF 程式庫會使用這些 API,簡化在應用程式中新增 PDF 檢視功能的程序。

以下是最新的 PDF 轉譯功能更新項目,這些功能包括: 搜尋內嵌的 PDF 檔案

PdfRenderer 已移至可透過 Google Play 系統更新進行更新的模組,不受平台版本影響。我們會透過建立與 Android 15 以下版本相容的 API 途徑 (稱為 PdfRendererPreV),將這些變更回溯至 Android 11 (API 級別 30)。

自動切換語言的改良功能

Android 14 added on-device, multi-language recognition in audio with automatic switching between languages, but this can cause words to get dropped, especially when languages switch with less of a pause between the two utterances. Android 15 adds additional controls to help apps tune this switching to their use case. EXTRA_LANGUAGE_SWITCH_INITIAL_ACTIVE_DURATION_TIME_MILLIS confines the automatic switching to the beginning of the audio session, while EXTRA_LANGUAGE_SWITCH_MATCH_SWITCHES deactivates the language switching after a defined number of switches. These options are particularly useful if you expect that there will be a single language spoken during the session that should be autodetected.

改良 OpenType 變數字型 API

Android 15 improves the usability of the OpenType variable font. You can create a FontFamily instance from a variable font without specifying weight axes with the buildVariableFamily API. The text renderer overrides the value of wght axis to match the displaying text.

Using the API simplifies the code for creating a Typeface considerably:

Kotlin

val newTypeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(assets, "RobotoFlex.ttf").build())
                    .buildVariableFamily())
    .build()

Java

Typeface newTypeface = Typeface.CustomFallbackBuilder(
            new FontFamily.Builder(
                new Font.Builder(assets, "RobotoFlex.ttf").build())
                    .buildVariableFamily())
    .build();

Previously, to create the same Typeface, you would need much more code:

Kotlin

val oldTypeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(assets, "RobotoFlex.ttf")
                    .setFontVariationSettings("'wght' 400")
                    .setWeight(400)
                    .build())
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 100")
                        .setWeight(100)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 200")
                        .setWeight(200)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 300")
                        .setWeight(300)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 500")
                        .setWeight(500)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 600")
                        .setWeight(600)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 700")
                        .setWeight(700)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 800")
                        .setWeight(800)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 900")
                        .setWeight(900)
                        .build()
                ).build()
        ).build()

Java

Typeface oldTypeface = new Typeface.CustomFallbackBuilder(
    new FontFamily.Builder(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 400")
            .setWeight(400)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 100")
            .setWeight(100)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 200")
            .setWeight(200)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 300")
            .setWeight(300)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 500")
            .setWeight(500)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 600")
            .setWeight(600)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 700")
            .setWeight(700)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 800")
            .setWeight(800)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 900")
            .setWeight(900)
            .build()
    )
    .build()
).build();

Here's an example of how a Typeface created with both the old and new APIs renders:

An example of how Typeface rendering differs using new and old
APIs

In this example, the Typeface created with the old API doesn't have the capability to create accurate font weights for the 350, 450, 550 and 650 Font instances, so the renderer falls back to the closest weight. So in this case, 300 is rendered instead of 350, 400 is rendered instead of 450, and so on. By contrast, the Typeface created with the new APIs dynamically creates a Font instance for a given weight, so accurate weights are rendered for 350, 450, 550, and 650 as well.

精細的換行符號控制

Starting in Android 15, a TextView and the underlying line breaker can preserve the given portion of text in the same line to improve readability. You can take advantage of this line break customization by using the <nobreak> tag in string resources or createNoBreakSpan. Similarly, you can preserve words from hyphenation by using the <nohyphen> tag or createNoHyphenationSpan.

For example, the following string resource doesn't include a line break, and renders with the text "Pixel 8 Pro." breaking in an undesirable place:

<resources>
    <string name="pixel8pro">The power and brains behind Pixel 8 Pro.</string>
</resources>

In contrast, this string resource includes the <nobreak> tag, which wraps the phrase "Pixel 8 Pro." and prevents line breaks:

<resources>
    <string name="pixel8pro">The power and brains behind <nobreak>Pixel 8 Pro.</nobreak></string>
</resources>

The difference in how these strings are rendered is shown in the following images:

Layout for a line of text where the phrase "Pixel 8 Pro." isn't wrapped using a <nobreak> tag.
Layout for the same line of text where the phrase "Pixel 8 Pro." is wrapped using a <nobreak> tag.

封存應用程式

Android and Google Play announced support for app archiving last year, allowing users to free up space by partially removing infrequently used apps from the device that were published using Android App Bundle on Google Play. Android 15 includes OS level support for app archiving and unarchiving, making it easier for all app stores to implement it.

Apps with the REQUEST_DELETE_PACKAGES permission can call the PackageInstaller requestArchive method to request archiving an installed app package, which removes the APK and any cached files, but persists user data. Archived apps are returned as displayable apps through the LauncherApps APIs; users will see a UI treatment to highlight that those apps are archived. If a user taps on an archived app, the responsible installer will get a request to unarchive it, and the restoration process can be monitored by the ACTION_PACKAGE_ADDED broadcast.

Enable 16 KB mode on a device using developer options

Toggle the Boot with 16KB page size developer option to boot a device in 16 KB mode.

Starting with Android 15 QPR1, you can use the developer option that's available on certain devices to boot the device in 16 KB mode and perform on-device testing. Before using the developer option, go to Settings > System > Software updates and apply any updates that are available.

This developer option is available on the following devices:

  • Pixel 8 and 8 Pro (with Android 15 QPR1 or higher)

  • Pixel 8a (with Android 15 QPR1 or higher)

  • Pixel 9, 9 Pro, and 9 Pro XL (with Android 15 QPR2 Beta 2 or higher)

圖形

Android 15 帶來最新的圖像改善項目,包括 ANGLE 和 Canvas 圖像系統的增強功能。

更新 Android 的 GPU 存取權

Vulkan logo

Android hardware has evolved quite a bit from the early days where the core OS would run on a single CPU and GPUs were accessed using APIs based on fixed-function pipelines. The Vulkan® graphics API has been available in the NDK since Android 7.0 (API level 24) with a lower-level abstraction that better reflects modern GPU hardware, scales better to support multiple CPU cores, and offers reduced CPU driver overhead — leading to improved app performance. Vulkan is supported by all modern game engines.

Vulkan is Android's preferred interface to the GPU. Therefore, Android 15 includes ANGLE as an optional layer for running OpenGL® ES on top of Vulkan. Moving to ANGLE will standardize the Android OpenGL implementation for improved compatibility, and, in some cases, improved performance. You can test out your OpenGL ES app stability and performance with ANGLE by enabling the developer option in Settings -> System -> Developer Options -> Experimental: Enable ANGLE on Android 15.

The Android ANGLE on Vulkan roadmap

Roadmap of upcoming changes to the Android GPU APIs.

As part of streamlining our GPU stack, going forward we will be shipping ANGLE as the GL system driver on more new devices, with the future expectation that OpenGL/ES will be only available through ANGLE. That being said, we plan to continue support for OpenGL ES on all devices.

Recommended next steps

Use the developer options to select the ANGLE driver for OpenGL ES and test your app. For new projects, we strongly encourage using Vulkan for C/C++.

畫布改善項目

Android 15 continues our modernization of Android's Canvas graphics system with additional capabilities:

  • Matrix44 provides a 4x4 matrix for transforming coordinates that should be used when you want to manipulate the canvas in 3D.
  • clipShader intersects the current clip with the specified shader, while clipOutShader sets the clip to the difference of the current clip and the shader, each treating the shader as an alpha mask. This supports the drawing of complex shapes efficiently.

效能和電池

Android 持續致力於協助您提升應用程式的效能和品質。Android 15 導入的 API 可協助您更有效率地執行應用程式中的工作、提升應用程式效能,以及收集應用程式的洞察資訊。

如要瞭解省電最佳做法、如何偵錯網路和耗電量,以及我們如何在 Android 15 和近期 Android 版本中提升背景作業的省電效率,請參閱 Google I/O 的「提升 Android 背景作業的省電效率」演講。

ApplicationStartInfo API

在先前的 Android 版本中,應用程式啟動過程一直是個謎。在應用程式中判斷應用程式是否從冷、暖或熱狀態啟動,是一項挑戰。您也難以瞭解應用程式在各個啟動階段 (分支程序、呼叫 onCreate、繪製第一個影格等) 花費的時間。在 Application 類別例項化時,您無法得知應用程式是從廣播、內容供應器、工作、備份、啟動完成、鬧鐘或 Activity 啟動。

Android 15 的 ApplicationStartInfo API 提供上述所有功能,甚至更多。您甚至可以選擇在流程中加入自己的時間戳記,方便集中收集時間資料。除了收集指標,您也可以使用 ApplicationStartInfo 直接改善應用程式啟動效能。舉例來說,如果應用程式因廣播而啟動,您可以避免在 Application 類別中執行與 UI 相關的程式庫例項,以免造成不必要的負擔。

應用程式大小詳細資訊

Since Android 8.0 (API level 26), Android has included the StorageStats.getAppBytes API that summarizes the installed size of an app as a single number of bytes, which is a sum of the APK size, the size of files extracted from the APK, and files that were generated on the device such as ahead-of-time (AOT) compiled code. This number is not very insightful in terms of how your app is using storage.

Android 15 adds the StorageStats.getAppBytesByDataType([type]) API, which lets you get insight into how your app is using up all that space, including APK file splits, AOT and speedup related code, dex metadata, libraries, and guided profiles.

應用程式管理的剖析

Android 15 includes the ProfilingManager class, which lets you collect profiling information from within your app such as heap dumps, heap profiles, stack sampling, and more. It provides a callback to your app with a supplied tag to identify the output file, which is delivered to your app's files directory. The API does rate limiting to minimize the performance impact.

To simplify constructing profiling requests in your app, we recommend using the corresponding Profiling AndroidX API, available in Core 1.15.0-rc01 or higher.

SQLite 資料庫改善項目

Android 15 introduces SQLite APIs that expose advanced features from the underlying SQLite engine that target specific performance issues that can manifest in apps. These APIs are included with the update of SQLite to version 3.44.3.

Developers should consult best practices for SQLite performance to get the most out of their SQLite database, especially when working with large databases or when running latency-sensitive queries.

  • Read-only deferred transactions: when issuing transactions that are read-only (don't include write statements), use beginTransactionReadOnly() and beginTransactionWithListenerReadOnly(SQLiteTransactionListener) to issue read-only DEFERRED transactions. Such transactions can run concurrently with each other, and if the database is in WAL mode, they can run concurrently with IMMEDIATE or EXCLUSIVE transactions.
  • Row counts and IDs: APIs were added to retrieve the count of changed rows or the last inserted row ID without issuing an additional query. getLastChangedRowCount() returns the number of rows that were inserted, updated, or deleted by the most recent SQL statement within the current transaction, while getTotalChangedRowCount() returns the count on the current connection. getLastInsertRowId() returns the rowid of the last row to be inserted on the current connection.
  • Raw statements: issue a raw SQlite statement, bypassing convenience wrappers and any additional processing overhead that they may incur.

Android 動態效能架構更新

Android 15 continues our investment in the Android Dynamic Performance Framework (ADPF), a set of APIs that allow games and performance intensive apps to interact more directly with power and thermal systems of Android devices. On supported devices, Android 15 adds ADPF capabilities:

  • A power-efficiency mode for hint sessions to indicate that their associated threads should prefer power saving over performance, great for long-running background workloads.
  • GPU and CPU work durations can both be reported in hint sessions, allowing the system to adjust CPU and GPU frequencies together to best meet workload demands.
  • Thermal headroom thresholds to interpret possible thermal throttling status based on headroom prediction.

To learn more about how to use ADPF in your apps and games, head over to the documentation.

隱私權

Android 15 包含多種功能,可協助應用程式開發人員保護使用者隱私權。

螢幕錄影偵測

Android 15 adds support for apps to detect that they are being recorded. A callback is invoked whenever the app transitions between being visible or invisible within a screen recording. An app is considered visible if activities owned by the registering process's UID are being recorded. This way, if your app is performing a sensitive operation, you can inform the user that they're being recorded.

val mCallback = Consumer<Int> { state ->
  if (state == SCREEN_RECORDING_STATE_VISIBLE) {
    // We're being recorded
  } else {
    // We're not being recorded
  }
}

override fun onStart() {
   super.onStart()
   val initialState =
      windowManager.addScreenRecordingCallback(mainExecutor, mCallback)
   mCallback.accept(initialState)
}

override fun onStop() {
    super.onStop()
    windowManager.removeScreenRecordingCallback(mCallback)
}

擴充 IntentFilter 功能

Android 15 builds in support for more precise Intent resolution through UriRelativeFilterGroup, which contains a set of UriRelativeFilter objects that form a set of Intent matching rules that must each be satisfied, including URL query parameters, URL fragments, and blocking or exclusion rules.

These rules can be defined in the AndroidManifest XML file with the <uri-relative-filter-group> tag, which can optionally include an android:allow tag. These tags can contain <data> tags that use existing data tag attributes as well as the android:query and android:fragment attributes.

Here's an example of the AndroidManifest syntax:

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:scheme="http" />
  <data android:scheme="https" />
  <data android:host="astore.com" />
  <uri-relative-filter-group>
    <data android:pathPrefix="/auth" />
    <data android:query="region=na" />
  </uri-relative-filter-group>
  <uri-relative-filter-group android:allow="false">
    <data android:pathPrefix="/auth" />
    <data android:query="mobileoptout=true" />
  </uri-relative-filter-group>
  <uri-relative-filter-group android:allow="false">
    <data android:pathPrefix="/auth" />
    <data android:fragmentPrefix="faq" />
  </uri-relative-filter-group>
</intent-filter>

私人空間

私人空間可解鎖及鎖定,以便在裝置上顯示或隱藏敏感應用程式。

使用者可透過私人空間在裝置上建立獨立空間,在多一層驗證機制下,隱藏敏感應用程式,防止他人窺探。私人空間會使用個別的使用者設定檔。使用者可以選擇使用裝置鎖定或專屬的鎖定因素來解鎖私人空間。

私人空間中的應用程式會顯示在啟動器的獨立容器中,並在私人空間鎖定時,隱藏在近期使用畫面、通知、設定和其他應用程式中。使用者產生和下載的內容 (例如媒體或檔案) 和帳戶會在私人空間和主空間之間分開。在私人空間解鎖後,您可以使用系統 Sharesheet相片挑選工具,讓應用程式存取不同空間的內容。

使用者無法將現有應用程式和相關資料移至私人空間。相反地,使用者可在私人空間中選取安裝選項,然後使用所需的應用程式商店安裝應用程式。私人空間中的應用程式會以個別副本的形式安裝,與主要空間中的任何應用程式不同 (同一個應用程式的新副本)。

使用者鎖定私人空間時,系統會停止設定檔。設定檔停止時,私人空間中的應用程式就會停止運作,無法執行前景或背景活動,包括顯示通知。

建議您使用私人空間測試應用程式,確保應用程式能正常運作,尤其是如果您的應用程式屬於下列任一類別:

查詢「所選相片存取權」的最新使用者選取項目

現在應用程式只能醒目顯示最近選取的相片和影片 授予媒體的部分存取權。這項功能可改善經常要求存取相片和影片存取權的應用程式使用者體驗。如要在應用程式中使用這項功能,請啟用 查詢 MediaStore 時有 QUERY_ARG_LATEST_SELECTION_ONLY 引數 透過 ContentResolver 關閉通知。

Kotlin

val externalContentUri = MediaStore.Files.getContentUri("external")

val mediaColumns = arrayOf(
   FileColumns._ID,
   FileColumns.DISPLAY_NAME,
   FileColumns.MIME_TYPE,
)

val queryArgs = bundleOf(
   // Return only items from the last selection (selected photos access)
   QUERY_ARG_LATEST_SELECTION_ONLY to true,
   // Sort returned items chronologically based on when they were added to the device's storage
   QUERY_ARG_SQL_SORT_ORDER to "${FileColumns.DATE_ADDED} DESC",
   QUERY_ARG_SQL_SELECTION to "${FileColumns.MEDIA_TYPE} = ? OR ${FileColumns.MEDIA_TYPE} = ?",
   QUERY_ARG_SQL_SELECTION_ARGS to arrayOf(
       FileColumns.MEDIA_TYPE_IMAGE.toString(),
       FileColumns.MEDIA_TYPE_VIDEO.toString()
   )
)

Java

Uri externalContentUri = MediaStore.Files.getContentUri("external");

String[] mediaColumns = {
    FileColumns._ID,
    FileColumns.DISPLAY_NAME,
    FileColumns.MIME_TYPE
};

Bundle queryArgs = new Bundle();
queryArgs.putBoolean(MediaStore.QUERY_ARG_LATEST_SELECTION_ONLY, true);
queryArgs.putString(MediaStore.QUERY_ARG_SQL_SORT_ORDER, FileColumns.DATE_ADDED + " DESC");
queryArgs.putString(MediaStore.QUERY_ARG_SQL_SELECTION, FileColumns.MEDIA_TYPE + " = ? OR " + FileColumns.MEDIA_TYPE + " = ?");
queryArgs.putStringArray(MediaStore.QUERY_ARG_SQL_SELECTION_ARGS, new String[] {
    String.valueOf(FileColumns.MEDIA_TYPE_IMAGE),
    String.valueOf(FileColumns.MEDIA_TYPE_VIDEO)
});

Android 版 Privacy Sandbox

Android 15 includes the latest Android Ad Services extensions, incorporating the latest version of the Privacy Sandbox on Android. This addition is part of our work to develop technologies that improve user privacy and enable effective, personalized advertising experiences for mobile apps. Our privacy sandbox page has more information about the Privacy Sandbox on Android developer preview and beta programs to help you get started.

Health Connect

Android 15 整合了 Health Connect by Android 的最新擴充功能,這是一個安全且集中式的平台,可用於管理及分享應用程式收集的健康與健身資料。這次更新新增了健身營養、皮膚溫度、訓練計畫等其他資料類型的支援。

皮膚溫度追蹤功能可讓使用者透過穿戴式裝置或其他追蹤裝置,儲存及分享更準確的溫度資料。

訓練計畫是結構化的運動計畫,可協助使用者達成健身目標。訓練計畫支援各種完成和表現目標:

如要進一步瞭解 Android 中的 Health Connect 最新更新,請觀看 Google I/O 大會的 透過 Android 健康資料建構可調整的體驗演講。

應用程式分享螢幕畫面

Android 15 supports app screen sharing so users can share or record just an app window rather than the entire device screen. This feature, first enabled in Android 14 QPR2, includes MediaProjection callbacks that allow your app to customize the app screen sharing experience. Note that for apps targeting Android 14 (API level 34) or higher, user consent is required for each MediaProjection capture session.

使用者體驗和系統 UI

Android 15 可讓應用程式開發人員和使用者進一步控管及彈性設定裝置,以符合自身需求。

如要進一步瞭解如何運用 Android 15 的最新改良功能,提升應用程式的使用者體驗,請觀看 Google I/O 的「改善 Android 應用程式的使用者體驗」演講。

使用 Generated Previews API 取得更豐富的小工具預覽畫面

Before Android 15, the only way to provide widget picker previews was to specify a static image or layout resource. These previews often differ significantly from the look of the actual widget when it is placed on the home screen. Also, static resources can't be created with Jetpack Glance, so a Glance developer had to screenshot their widget or create an XML layout to have a widget preview.

Android 15 adds support for generated previews. This means that app widget providers can generate RemoteViews to use as the picker preview, instead of a static resource.

Apps can provide Remote Views to the Widget Picker, so they can update the content in the picker to be more representative of what the user will see.

Push API

Apps can provide generated previews through a push API. Apps can provide previews at any point in their lifecycle, and don't receive an explicit request from the host to provide previews. Previews are persisted in AppWidgetService, and hosts can request them on-demand. The following example loads an XML widget layout resource and sets it as the preview:

AppWidgetManager.getInstance(appContext).setWidgetPreview(
   ComponentName(
       appContext,
       SociaLiteAppWidgetReceiver::class.java
   ),
   AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
   RemoteViews("com.example", R.layout.widget_preview)
)

The expected flow is:

  1. At any time, the widget provider calls setWidgetPreview. The provided previews are persisted in AppWidgetService with other provider info.
  2. setWidgetPreview notifies hosts of an updated preview through the AppWidgetHost.onProvidersChanged callback. In response, the widget host reloads all of its provider information.
  3. When displaying a widget preview, the host checks AppWidgetProviderInfo.generatedPreviewCategories, and if the chosen category is available, calls AppWidgetManager.getWidgetPreview to return the saved preview for this provider.

When to call setWidgetPreview

Because there is no callback to provide previews, apps can choose to send previews at any point when they are running. How often to update the preview depends on the widget's use case.

The following list describes the two main categories of preview use cases:

  • Providers that show real data in their widget previews, such as personalized or recent information. These providers can set the preview once the user has signed in or has done initial configuration in their app. After this, they can set up a periodic task to update the previews at their chosen cadence. Examples of this type of widget could be a photo, calendar, weather or news widget.
  • Providers that show static information in previews or quick-action widgets that don't display any data. These providers can set previews once, when the app first launches. Examples of this type of widget include a drive quick actions widget or chrome shortcuts widget.

Some providers might show static previews on the hub mode picker, but real information on the homescreen picker. These providers should follow the guidance for both of these use cases to set previews.

子母畫面

Android 15 引進了子母畫面 (PiP) 的變更,確保進入 PiP 模式時的轉換更加流暢。這對在主要 UI 上疊加 UI 元素的應用程式而言十分有用,因為這些元素會進入 PiP。

開發人員使用 onPictureInPictureModeChanged 回呼來定義邏輯 可切換重疊 UI 元素的顯示設定。這個回呼為 子母畫面進入或離開動畫播放完畢時觸發。開始時間倒數計時 Android 15 的 PictureInPictureUiState 類別包含其他狀態。

透過此 UI 狀態,指定 Android 15 (API 級別 35) 的應用程式將觀察 透過以下方式叫用 Activity#onPictureInPictureUiStateChanged 回呼: isTransitioningToPip()。另有 在子母畫面模式下,許多與應用程式無關的 UI 元素, 包含建議、即將推出 影片、評分和標題當應用程式進入子母畫面模式時,請使用 使用 onPictureInPictureUiStateChanged 回呼隱藏這些 UI 元素。當 應用程式從子母畫面視窗進入全螢幕模式,並使用 用來取消隱藏這些元素的 onPictureInPictureModeChanged 回呼,如 下列範例:

override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
        if (pipState.isTransitioningToPip()) {
          // Hide UI elements
        }
    }
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
        if (isInPictureInPictureMode) {
          // Unhide UI elements
        }
    }

針對 PiP 視窗,快速切換不相關的 UI 元素可確保 PiP 進入動畫更流暢,且不會閃爍。

更完善的「零打擾」規則

AutomaticZenRule lets apps customize Attention Management (Do Not Disturb) rules and decide when to activate or deactivate them. Android 15 greatly enhances these rules with the goal of improving the user experience. The following enhancements are included:

  • Adding types to AutomaticZenRule, allowing the system to apply special treatment to some rules.
  • Adding an icon to AutomaticZenRule, helping to make the modes be more recognizable.
  • Adding a triggerDescription string to AutomaticZenRule that describes the conditions on which the rule should become active for the user.
  • Added ZenDeviceEffects to AutomaticZenRule, allowing rules to trigger things like grayscale display, night mode, or dimming the wallpaper.

為通知管道設定 VibrationEffect

Android 15 supports setting rich vibrations for incoming notifications by channel using NotificationChannel.setVibrationEffect, so your users can distinguish between different types of notifications without having to look at their device.

媒體投影狀態列晶片和自動停止

媒體投影功能可能會揭露使用者的私人資訊。新的醒目狀態列方塊可讓使用者瞭解任何正在進行的螢幕投影作業。使用者可以輕觸方塊停止投放、分享或錄製螢幕畫面。此外,為了提供更直覺的使用者體驗,現在裝置螢幕鎖定時,任何進行中的螢幕投影作業都會自動停止。

用於螢幕分享、投放和錄製的狀態列方塊。

大螢幕和板型規格

Android 15 可讓應用程式充分運用 Android 的板型規格,包括大螢幕、可翻轉和折疊式裝置。

改善大螢幕多工處理功能

Android 15 gives users better ways to multitask on large screen devices. For example, users can save their favorite split-screen app combinations for quick access and pin the taskbar on screen to quickly switch between apps. This means that making sure your app is adaptive is more important than ever.

Google I/O has sessions on Building adaptive Android apps and Building UI with the Material 3 adaptive library that can help, and our documentation has more to help you Design for large screens.

支援封面螢幕

Your app can declare a property that Android 15 uses to allow your Application or Activity to be presented on the small cover screens of supported flippable devices. These screens are too small to be considered as compatible targets for Android apps to run on, but your app can opt in to supporting them, making your app available in more places.

連線能力

Android 15 更新了平台,讓您的應用程式能使用通訊和無線技術的最新進展。

衛星支援

Android 15 持續擴大平台支援範圍,包括衛星連線,以及 包含一些 UI 元素,確保 衛星連線環境。

應用程式可以使用 ServiceState.isUsingNonTerrestrialNetwork() 執行下列操作: 會偵測裝置是否與衛星連線 可能無法使用完整網路服務的原因此外,Android 15 支援簡訊和多媒體訊息應用程式,以及預先載入的 RCS 應用程式 可以收發訊息的衛星連線。

裝置連線至衛星時,系統會顯示通知。

更流暢的 NFC 體驗

Android 15 正在努力讓輕觸付款體驗更流暢可靠,同時繼續支援 Android 強大的 NFC 應用程式生態系統。在支援的裝置上,應用程式可以要求 NfcAdapter 進入觀察模式,在該模式下,裝置會聆聽但不會回應 NFC 讀卡器,並傳送應用程式的 NFC 服務 PollingFrame 物件進行處理。PollingFrame 物件可用於在首次與 NFC 讀取器通訊前進行驗證,在許多情況下可支援單按鈕交易。

此外,應用程式可以在支援的裝置上註冊篩選器,以便在檢查迴圈活動發生時收到通知,進而與多個支援 NFC 的應用程式順利運作。

錢包角色

Android 15 introduces a Wallet role that allows tighter integration with the user's preferred wallet app. This role replaces the NFC default contactless payment setting. Users can manage the Wallet role holder by navigating to Settings > Apps > Default Apps.

The Wallet role is used when routing NFC taps for AIDs registered in the payment category. Taps always go to the Wallet role holder unless another app that is registered for the same AID is running in the foreground.

This role is also used to determine where the Wallet Quick Access tile should go when activated. When the role is set to "None", the Quick Access tile isn't available and payment category NFC taps are only delivered to the foreground app.

安全性

Android 15 可協助您提升應用程式安全性、保護應用程式資料,並讓使用者進一步瞭解及掌控自己的資料。如要進一步瞭解我們如何強化使用者防護措施,以及保護應用程式免於新威脅侵擾,請觀看 Google I/O 的這場演講

整合 Credential Manager 與自動填入功能

Starting with Android 15, developers can link specific views like username or password fields with Credential Manager requests, making it easier to provide a tailored user experience during the sign-in process. When the user focuses on one of these views, a corresponding request is sent to Credential Manager. The resulting credentials are aggregated across providers and displayed in autofill fallback UIs, such as inline suggestions or drop-down suggestions. The Jetpack androidx.credentials library is the preferred endpoint for developers to use and will soon be available to further enhance this feature in Android 15 and higher.

整合單鍵註冊和登入功能與生物特徵辨識提示功能

Credential Manager integrates biometric prompts into the credential creation and sign-in processes, eliminating the need for providers to manage biometric prompts. As a result, credential providers only need to focus on the results of the create and get flows, augmented with the biometric flow result. This simplified process creates a more efficient and streamlined credential creation and retrieval process.

端對端加密的金鑰管理

我們在 Android 15 中推出 E2eeContactKeysManager,這項功能可提供 OS 層級 API 來儲存加密編譯公用金鑰,方便在 Android 應用程式中進行端對端加密 (E2EE)。

E2eeContactKeysManager 旨在整合平台聯絡人應用程式,為使用者提供集中式方式,管理及驗證聯絡人的公開金鑰。

內容 URI 的權限檢查

Android 15 introduces a set of APIs that perform permission checks on content URIs:

無障礙設定

Android 15 新增了多項功能,可提升使用者無障礙體驗。

更優質的點字體驗

In Android 15, we've made it possible for TalkBack to support Braille displays that are using the HID standard over both USB and secure Bluetooth.

This standard, much like the one used by mice and keyboards, will help Android support a wider range of Braille displays over time.

國際化

Android 15 新增了多項功能,可提升使用者在不同語言環境下的裝置使用體驗。

中日韓變數字型

從 Android 15 開始,適用於中文、日文和韓文 (CJK) 的字型檔案 NotoSansCJK,現在已變成可變字型。變數字型為中日韓語言開啟了創意排版的可能性。設計人員可以探索更多樣式,並製作出以往難以或無法達成的視覺效果強烈版面配置。

中文、日文和韓文 (CJK) 變數字型的字型寬度變化情形。

字元間對齊

Starting with Android 15, text can be justified utilizing letter spacing by using JUSTIFICATION_MODE_INTER_CHARACTER. Inter-word justification was first introduced in Android 8.0 (API level 26), and inter-character justification provides similar capabilities for languages that use the whitespace character for segmentation, such as Chinese, Japanese, and others.

Layout for Japanese text using JUSTIFICATION_MODE_NONE.
Layout for English text using JUSTIFICATION_MODE_NONE.


Layout for Japanese text using JUSTIFICATION_MODE_INTER_WORD.
Layout for English text using JUSTIFICATION_MODE_INTER_WORD.


Layout for Japanese text using the JUSTIFICATION_MODE_INTER_CHARACTER.
Layout for English text using the JUSTIFICATION_MODE_INTER_CHARACTER.

自動換行設定

Android 已開始在下列國家/地區支援日文和韓文的詞組換行符號: Android 13 (API 級別 33)。不過,雖然使用詞組的分行符號改善了 簡短的文字易讀性,對長行文字的效果不佳。 在 Android 15 中,應用程式只能針對短行套用以詞組為準的換行符號 方法是使用 LINE_BREAK_WORD_STYLE_AUTO 如果有需要 SQL 指令的分析工作負載 則 BigQuery 可能是最佳選擇這個選項可為文字選取最合適的字詞樣式選項。

以短行文字來說,使用以詞組為基準的換行符號,運作方式也相同 如 LINE_BREAK_WORD_STYLE_PHRASE,如 如下圖片:

如果是簡短的文字,LINE_BREAK_WORD_STYLE_AUTO 套用詞組換行,讓文字更清晰易讀。 這與套用 LINE_BREAK_WORD_STYLE_PHRASE

對於較長的文字,LINE_BREAK_WORD_STYLE_AUTO 會使用 no 斷行文字樣式,功能與 LINE_BREAK_WORD_STYLE_NONE,如 如下圖片:

對於長行文字,LINE_BREAK_WORD_STYLE_AUTO 套用不換行的文字樣式,讓文字更清晰易讀。 這與套用 LINE_BREAK_WORD_STYLE_NONE

額外日文變體假名字型

In Android 15, a font file for old Japanese Hiragana (known as Hentaigana) is bundled by default. The unique shapes of Hentaigana characters can add a distinctive flair to artwork or design while also helping to preserve accurate transmission and understanding of ancient Japanese documents.

Character and text style for the Japanese Hentaigana font.

VideoLAN cone Copyright (c) 1996-2010 VideoLAN. This logo or a modified version may be used or modified by anyone to refer to the VideoLAN project or any product developed by the VideoLAN team, but does not indicate endorsement by the project.

Vulkan and the Vulkan logo are registered trademarks of the Khronos Group Inc.

OpenGL is a registered trademark and the OpenGL ES logo is a trademark of Hewlett Packard Enterprise used by permission by Khronos.