功能與 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 標誌

dav1d 是 VideoLAN 推出的熱門 AV1 軟體解碼器,適用於不支援硬體 AV1 解碼功能的 Android 裝置。dav1d 的效能比舊版 AV1 軟體解碼器高出 3 倍,可讓更多使用者 (包括部分低階和中階裝置) 播放 HD AV1 影片。

您的應用程式必須透過名稱 "c2.android.av1-dav1d.decoder" 呼叫 dav1d,才能選擇使用 dav1d。在後續更新中,dav1d 將成為預設的 AV1 軟體解碼器。這項支援功能已標準化,並向後移植至接收 Google Play 系統更新的 Android 11 裝置。

開發人員工作效率和工具

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

OpenJDK 17 更新

Android 15 将继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。

其中包含以下主要功能和改进:

这些 API 会通过 Google Play 系统更新在搭载 Android 12(API 级别 31)及更高版本的 10 亿多部设备上更新,以便您以最新的编程功能为目标平台。

PDF 改善項目

Android 15 includes substantial improvements to the PdfRenderer APIs. Apps can incorporate advanced features such as rendering password-protected files, annotations, form editing, searching, and selection with copy. Linearized PDF optimizations are supported to speed local PDF viewing and reduce resource use. The Jetpack PDF library uses these APIs to simplify adding PDF viewing capabilities to your app.

The latest updates to PDF rendering include features such as searching an embedded PDF file.

The PdfRenderer has been moved to a module that can be updated using Google Play system updates independent of the platform release, and we're supporting these changes back to Android 11 (API level 30) by creating a compatible pre-Android 15 version of the API surface, called PdfRendererPreV.

自動切換語言的改良功能

Android 14 在音频中添加了设备端多语言识别功能,并支持在语言之间自动切换,但这可能会导致丢失字词,尤其是当两次语音之间语言切换的间隔时间较短时。Android 15 添加了其他控件,以帮助应用根据其用例调整此切换。EXTRA_LANGUAGE_SWITCH_INITIAL_ACTIVE_DURATION_TIME_MILLIS 会将自动切换限制在音频会话开始时,而 EXTRA_LANGUAGE_SWITCH_MATCH_SWITCHES 会在发生指定次数的切换后停用语言切换。如果您预计会话期间只会使用一种语言,并且该语言应被自动检测到,这些选项会特别有用。

改良 OpenType 變數字型 API

Android 15 改善了 OpenType 變數字型的可用性。您可以建立 來自變數字型的 FontFamily 例項,但未指定粗軸 與 buildVariableFamily API 互動文字轉譯器會覆寫這個值 配合顯示文字。wght 軸。

使用 API 可大幅簡化建立 Typeface 的程式碼:

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();

先前,如要建立相同的 Typeface,您需要使用更多程式碼:

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();

以下範例說明使用舊版和新版 API 建立的 Typeface 如何算繪:

使用新舊 API 時,字型算繪的差異示例

在這個範例中,使用舊版 API 建立的 Typeface 無法為 350、450、550 和 650 Font 例項建立準確的字型粗細,因此轉譯器會改用最接近的粗細。如此 那麼轉譯值會是 300 而不是 350,而是顯示 400,而非 450;且 依此類推相反地,使用新 API 建立的 Typeface 會以動態方式建立 指定權重的 Font 例項,因此會以 350 為單位呈現準確的權重 450、550 和 650。

精細的換行符號控制

从 Android 15 开始,TextView 和底层行断开符可以将给定部分文本保留在同一行中,以提高可读性。您可以通过在字符串资源或 createNoBreakSpan 中使用 <nobreak> 标记来充分利用此换行符自定义功能。同样,您可以使用 <nohyphen> 标记或 createNoHyphenationSpan 来防止对字词进行分词。

例如,以下字符串资源不包含换行符,在呈现时,文本“Pixel 8 Pro”会在不合适的位置换行:

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

相比之下,此字符串资源包含 <nobreak> 标记,该标记会将字词“Pixel 8 Pro”换行,并防止换行:

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

以下图片展示了这些字符串呈现方式的差异:

一行文本的布局,其中显示短语“Pixel 8 Pro.”未使用 <nobreak> 标记换行。
使用 <nobreak> 标记封装“Pixel 8 Pro.”短语的同一行文本的布局。

封存應用程式

Android 和 Google Play 去年宣布支援應用程式封存功能,使用者可以在 Google Play 上使用 Android App Bundle 發布的應用程式,從裝置上部分移除不常使用的應用程式,藉此釋出空間。Android 15 提供應用程式封存和解封存的作業系統層級支援功能,讓所有應用程式商店更輕鬆地實作這項功能。

具有 REQUEST_DELETE_PACKAGES 權限的應用程式可以呼叫 PackageInstaller requestArchive 方法,要求封存 已安裝的應用程式套件,會移除 APK 和任何快取檔案,但會保留 使用者資料。系統會透過 LauncherApps API;使用者會看到 UI 樣式,藉此突顯這些 個應用程式已封存。使用者輕觸封存的應用程式時,負責的安裝程式 會收到取消封存的要求,而且還原程序可以 由 ACTION_PACKAGE_ADDED 廣播監控。

使用開發人員選項在裝置上啟用 16 KB 模式

切換「以 16KB 頁面大小啟動」開發人員選項,即可在 16 KB 模式下啟動裝置。

在 Android 15 的 QPR 版本中,您可以使用特定裝置上的開發人員選項,以 16 KB 模式啟動裝置,並執行裝置端測試。使用開發人員選項前,請依序前往「設定」>「系統」>「軟體更新」,並套用所有可用的更新。

下列裝置提供這項開發人員選項:

  • Pixel 8 和 8 Pro (搭載 Android 15 QPR1 以上版本)

  • Pixel 8a (搭載 Android 15 QPR1 以上版本)

  • Pixel 9、Pixel 9 Pro 和 Pixel 9 Pro XL (搭載 Android 15 QPR2 Beta 2 以上版本)

圖形

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

更新 Android 的 GPU 存取權

Vulkan 標誌

與早期核心作業系統會在單一 CPU 上執行,並使用以固定函式管道為基礎的 API 存取 GPU 不同,Android 硬體已大幅進化。自 Android 7.0 (API 級別 24) 起,NDK 就提供 Vulkan® 圖形 API,其中包含低階抽象化功能,可更貼近現代 GPU 硬體、更有效地支援多個 CPU 核心,並減少 CPU 驅動程式額外負擔,進而提升應用程式效能。所有新型遊戲引擎都支援 Vulkan。

Vulkan 是 Android 對 GPU 的偏好介面。因此,Android 15 包含 ANGLE 做為可選的圖層,可在 Vulkan 上執行 OpenGL® ES。改用 ANGLE 可將 Android OpenGL 實作標準化,進而改善相容性,在某些情況下還能提升效能。您可以在 Android 15 上依序前往「設定」->「系統」->「開發人員選項」->「實驗功能:啟用 ANGLE」,啟用開發人員選項,藉此使用 ANGLE 測試 OpenGL ES 應用程式的穩定性和效能。

Android ANGLE 的 Vulkan 時程表

Android GPU API 即將異動的藍圖。

為了簡化 GPU 堆疊,我們日後會在更多新裝置上提供 ANGLE 做為 GL 系統驅動程式,並預期 OpenGL/ES 日後只會透過 ANGLE 提供。不過,我們計劃繼續在所有裝置上支援 OpenGL ES

建議採取的後續步驟

使用開發人員選項選取 OpenGL ES 的 ANGLE 驅動程式,並測試應用程式。對於新專案,我們強烈建議使用 Vulkan 開發 C/C++。

Canvas 改善項目

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

In previous versions of Android, app startup has been a bit of a mystery. It was challenging to determine within your app whether it started from a cold, warm, or hot state. It was also difficult to know how long your app spent during the various launch phases: forking the process, calling onCreate, drawing the first frame, and more. When your Application class was instantiated, you had no way of knowing whether the app started from a broadcast, a content provider, a job, a backup, boot complete, an alarm, or an Activity.

The ApplicationStartInfo API on Android 15 provides all of this and more. You can even choose to add your own timestamps into the flow to help collect timing data in one place. In addition to collecting metrics, you can use ApplicationStartInfo to help directly optimize app startup; for example, you can eliminate the costly instantiation of UI-related libraries within your Application class when your app is starting up due to a broadcast.

應用程式大小詳細資訊

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 包含 ProfilingManager 類別,可讓您從應用程式內收集剖析資訊,例如記憶體快照資料、記憶體快照資料、堆疊取樣等。它會為您的應用程式提供回呼,並提供標記來識別輸出檔案,該檔案會傳送至應用程式的檔案目錄。API 會實施頻率限制,盡可能降低對效能的影響。

如要簡化應用程式中的剖析要求建構程序,建議您使用對應的 Profiling AndroidX API (適用於 Core 1.15.0-rc01 以上版本)。

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 继续投资于 Android 动态性能框架 (ADPF),这是一组 API,可让游戏和性能密集型应用更为直接地与 Android 设备的电源和散热系统进行互动。在受支持的设备上,Android 15 添加了 ADPF 功能:

  • 针对提示会话的节能模式,用于指明其关联的线程应优先节能而非性能,非常适合长时间运行的后台工作负载。
  • 系统可以在提示会话中报告 GPU 和 CPU 工作时长,以便同时调整 CPU 和 GPU 频率,以最佳方式满足工作负载需求。
  • 热余量阈值,用于根据余量预测来解读可能的热节流状态。

如需详细了解如何在应用和游戏中使用 ADPF,请参阅相关文档

隱私權

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>

私人空間

The private space can be unlocked and locked to show or hide sensitive apps on a device.

Private space lets users create a separate space on their device where they can keep sensitive apps away from prying eyes, under an additional layer of authentication. The private space uses a separate user profile. The user can choose to use the device lock or a separate lock factor for the private space.

Apps in the private space show up in a separate container in the launcher, and are hidden from the recents view, notifications, settings, and from other apps when the private space is locked. User-generated and downloaded content (such as media or files) and accounts are separated between the private space and the main space. The system sharesheet and the photo picker can be used to give apps access to content across spaces when the private space is unlocked.

Users can't move existing apps and their data into the private space. Instead, users select an install option in the private space to install an app using whichever app store they prefer. Apps in the private space are installed as separate copies from any apps in the main space (new copies of the same app).

When a user locks the private space, the profile is stopped. While the profile is stopped, apps in the private space are no longer active and can't perform foreground or background activities, including showing notifications.

We recommend that you test your app with private space to make sure your app works as expected, especially if your app falls into one of the following categories:

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

现在,如果应用获得了部分访问权限,则只能突出显示最近选择的照片和视频。此功能可以改善频繁请求访问照片和视频的应用的用户体验。如需在应用中使用此功能,请在通过 ContentResolver 查询 MediaStore 时启用 QUERY_ARG_LATEST_SELECTION_ONLY 参数。

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 支持应用屏幕共享,因此用户可以仅共享或录制应用窗口,而不是整个设备屏幕。此功能首次在 Android 14 QPR2 中启用,包含 MediaProjection 回调,可让您的应用自定义应用屏幕共享体验。请注意,对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,每个 MediaProjection 捕获会话都需要征得用户同意

使用者體驗和系統 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 introduces changes in Picture-in-Picture (PiP) ensuring an even smoother transition when entering into PiP mode. This will be beneficial for apps having UI elements overlaid on top of their main UI, which goes into PiP.

Developers use the onPictureInPictureModeChanged callback to define logic that toggles the visibility of the overlaid UI elements. This callback is triggered when the PiP enter or exit animation is completed. Beginning in Android 15, the PictureInPictureUiState class includes another state.

With this UI state, apps targeting Android 15 (API level 35) will observe the Activity#onPictureInPictureUiStateChanged callback being invoked with isTransitioningToPip() as soon as the PiP animation starts. There are many UI elements that are not relevant for the app when it is in PiP mode, for example views or layout that include information such as suggestions, upcoming video, ratings, and titles. When the app goes to PiP mode, use the onPictureInPictureUiStateChanged callback to hide these UI elements. When the app goes to full screen mode from the PiP window, use onPictureInPictureModeChanged callback to unhide these elements, as shown in the following examples:

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

This quick visibility toggle of irrelevant UI elements (for a PiP window) helps ensure a smoother and flicker-free PiP enter animation.

更完善的「零打擾」規則

AutomaticZenRule 允许应用自定义注意力机制 管理(勿扰)规则,并确定何时启用或停用 。Android 15 极大地增强了这些规则,旨在提高 用户体验。其中包含以下增强功能:

  • AutomaticZenRule 添加类型,让系统能够应用特殊类型 对某些规则的处理
  • AutomaticZenRule 添加图标,使模式更加丰富 易于识别。
  • triggerDescription 字符串添加到 AutomaticZenRule,用于描述 规则应当对用户生效的条件。
  • 已添加 ZenDeviceEffects 更改为AutomaticZenRule,从而允许规则触发灰度等操作 显示、夜间模式或调暗壁纸。

為通知管道設定 VibrationEffect

Android 15 支持为传入的通知设置丰富的振动,方法是 频道使用的是NotificationChannel.setVibrationEffect,因此 您的用户可以区分不同类型的通知 不需要看他们的设备

媒體投影狀態列圖示和自動停止

媒体投放可能会泄露用户的私密信息。一个醒目的新状态栏条状标签可让用户了解任何正在进行的屏幕投影。用户可以点按该条状标签停止投屏、共享或录制屏幕。此外,为了提供更直观的用户体验,当设备屏幕锁定后,所有正在进行的屏幕投影都会自动停止。

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

大螢幕和板型規格

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.

支援封面螢幕

您的应用可以声明一个属性,Android 15 会使用该属性来允许您的 ApplicationActivity 显示在受支持的可翻转设备的小封面屏幕上。这些屏幕太小,无法被视为适合运行 Android 应用的兼容目标平台,但您的应用可以选择支持它们,从而让您的应用在更多平台上可用。

連線能力

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

衛星支援

Android 15 continues to extend platform support for satellite connectivity and includes some UI elements to ensure a consistent user experience across the satellite connectivity landscape.

Apps can use ServiceState.isUsingNonTerrestrialNetwork() to detect when a device is connected to a satellite, giving them more awareness of why full network services might be unavailable. Additionally, Android 15 provides support for SMS and MMS apps as well as preloaded RCS apps to use satellite connectivity for sending and receiving messages.

A notification appears when the device connects to a satellite.

更流暢的 NFC 體驗

Android 15 is working to make the tap to pay experience more seamless and reliable while continuing to support Android's robust NFC app ecosystem. On supported devices, apps can request the NfcAdapter to enter observe mode, where the device listens but doesn't respond to NFC readers, sending the app's NFC service PollingFrame objects to process. The PollingFrame objects can be used to auth ahead of the first communication to the NFC reader, allowing for a one tap transaction in many cases.

In addition, apps can register a filter on supported devices so they can be notified of polling loop activity, which allows for smooth operation with multiple NFC-aware applications.

錢包角色

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) 的可变字体在不同字体宽度下的显示效果。

字元間對齊

從 Android 15 開始,系統可根據字母間距,使用字母間距 使用 JUSTIFICATION_MODE_INTER_CHARACTER。有多字的理由 Android 8.0 (API 級別 26) 首次推出的功能,以及跨字元 對於使用 空白字元做為區隔,例如中文、日文等。

使用 JUSTIFICATION_MODE_NONE 設定日文內容的版面配置。
使用 JUSTIFICATION_MODE_NONE 設定英文內容的版面配置。


使用 JUSTIFICATION_MODE_INTER_WORD 設定日文內容的版面配置。
使用 JUSTIFICATION_MODE_INTER_WORD 的英文文字版面配置。


使用 JUSTIFICATION_MODE_INTER_CHARACTER 的日文文字版面配置。
使用 JUSTIFICATION_MODE_INTER_CHARACTER 為英文內容的版面配置。

自動換行設定

Android started supporting phrase-based line breaks for Japanese and Korean in Android 13 (API level 33). However, while phrase-based line breaks improve the readability of short lines of text, they don't work well for long lines of text. In Android 15, apps can apply phrase-based line breaks only for short lines of text, using the LINE_BREAK_WORD_STYLE_AUTO option. This option selects the best word style option for the text.

For short lines of text, phrase-based line breaks are used, functioning the same as LINE_BREAK_WORD_STYLE_PHRASE, as shown in the following image:

For short lines of text, LINE_BREAK_WORD_STYLE_AUTO applies phrase-based line breaks to improve the readability of the text. This is the same as applying LINE_BREAK_WORD_STYLE_PHRASE.

For longer lines of text, LINE_BREAK_WORD_STYLE_AUTO uses a no line-break word style, functioning the same as LINE_BREAK_WORD_STYLE_NONE, as shown in the following image:

For long lines of text, LINE_BREAK_WORD_STYLE_AUTO applies no line-break word style to improve the readability of the text. This is the same as applying 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.