功能和 API 概览

Android 15 面向开发者引入了一些出色的新功能和 API。以下部分总结了这些功能,以帮助您开始使用相关 API。

如需查看新增、修改和移除的 API 的详细列表,请参阅 API 差异报告。如需详细了解新的 API,请访问 Android API 参考文档,新 API 会突出显示以方便查看。此外,如需了解平台变更可能会在哪些方面影响您的应用,请务必查看 Android 15 以 Android 15 为目标平台的应用对应用有影响的行为变更以及影响所有应用(无论 targetSdkVersion 如何)的行为变更

摄像头和媒体

Android 15 包含各种功能,可改善相机和媒体体验,并可让您使用各种工具和硬件来支持创作者在 Android 上将其构想变为现实。

如需详细了解 Android 媒体和相机的最新功能和开发者解决方案,请参阅 Google I/O 大会的打造现代 Android 媒体和相机体验演讲。

弱光增强

Android 15 introduces Low Light Boost, a new 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 new 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 a new 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 introduces support for the CTA-2075 loudness standard to help you avoid audio loudness inconsistencies and ensure users don't have to constantly adjust volume when switching between content. The system leverages known characteristics of the output devices (headphones and speaker) along with loudness metadata available in AAC audio content to intelligently adjust the audio loudness and dynamic range compression levels.

To enable this feature, you need to ensure loudness metadata is available in your AAC content and enable the platform feature in your app. For this, you instantiate a LoudnessCodecController object by calling its create factory method with the audio session ID from the associated AudioTrack; this automatically starts applying audio updates. You can pass an OnLoudnessCodecUpdateListener to modify or filter loudness parameters before they are applied on the 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 will also be updated to use the LoudnessCodecController APIs for a seamless app integration.

虚拟 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 now 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.

For now, 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 continues the work of refreshing Android's core libraries to align with the features in the latest OpenJDK LTS releases.

The following key features and improvements are included:

These APIs are updated on over a billion devices running Android 12 (API level 31) and higher through Google Play System updates, so you can target the latest programming features.

改进了 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 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.

We value your feedback on the enhancements we've made to the PdfRenderer API surface, and we plan to make it even easier to incorporate these APIs into your app with an upcoming Android Jetpack library.

语言切换自动优化

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 Variable Font 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 时 Typeface 渲染有何不同的示例

在此示例中,使用旧 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> 标记进行换行。
同一行文本的布局,其中词组“Pixel 8 Pro”用 <nobreak> 标记封装。

应用归档

Android 和 Google Play 去年宣布支持应用归档,这让用户可以通过从 Google Play 上使用 Android App Bundle 发布的部分不常用的应用来释放空间。Android 15 现在包含对应用归档和取消归档的操作系统级支持,因此所有应用商店都可以更轻松地实现此功能。

具有 REQUEST_DELETE_PACKAGES 权限的应用可以调用 PackageInstaller requestArchive 方法来请求归档已安装的应用软件包,此操作会移除 APK 和所有缓存的文件,但会保留用户数据。已归档的应用会通过 LauncherApps API 作为可显示的应用返回;用户会看到界面处理方式,以突出显示这些应用已归档。如果用户点按已归档的应用,相关安装程序将收到将其取消归档的请求,并且可以通过 ACTION_PACKAGE_ADDED 广播监控恢复过程。

图形

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++.

对 Canvas 的改进

Android 15 continues our modernization of Android's Canvas graphics system with new 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.

详细的应用大小信息

自 Android 8.0(API 级别 26)起,Android 就一直包含 StorageStats.getAppBytes API,该 API 将应用的安装大小汇总为一个字节,这些字节是 APK 大小、从 APK 中提取的文件的大小以及设备上生成的文件(例如预先 (AOT) 编译代码)的总和。就应用的存储空间使用情况而言,此数字并不富有见解。

Android 15 增加了 StorageStats.getAppBytesByDataType([type]) API,可让您深入了解应用如何使用所有空间,包括 APK 文件拆分、AOT 和加速相关代码、dex 元数据、库和引导式配置文件。

应用管理的性能剖析

Android 15 包含全新的 ProfilingManager 类,可让您从应用内收集性能分析信息。我们计划使用 Android Jetpack API 封装该类,这将简化性能分析请求的构建过程,但核心 API 将允许收集堆转储、堆配置文件、堆栈采样等信息。它使用提供的标记为您的应用提供回调,用于标识输出文件,该文件将传递到应用的文件目录。该 API 会限制速率限制,以最大限度地降低对性能的影响。

SQLite 数据库改进

Android 15 introduces new SQLite APIs that expose advanced features from the underlying SQLite engine that target specific performance issues that can manifest in apps.

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: new 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 new <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 new android:query and android:fragment attributes.

Here's an example of the AndroidManifest syntax:

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="http" />
  <data android:scheme="https" />
  <data android:domain="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照片选择器授权应用跨空间访问内容。

用户无法将现有应用及其数据移至私密空间。相反,用户可以在私有空间中选择一个安装选项,使用他们喜欢的任何应用商店安装应用。私密空间中的应用会作为与主空间中的任何应用(同一应用的新副本)的单独副本进行安装。

当用户锁定私密空间后,相应个人资料会停止。配置文件停止后,私密空间中的应用将不再处于活跃状态,并且无法执行前台或后台 activity,包括显示通知。

我们建议您使用私有空间测试应用,以确保应用按预期运行,尤其是当您的应用属于以下类别之一时:

查询所选照片访问权限的最近用户选择

现在,授予媒体权限的部分访问权限后,应用可以仅突出显示最近选择的照片和视频。此功能可以改善频繁请求访问照片和视频的应用的用户体验。如需在您的应用中使用此功能,请在通过 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)
});

Privacy Sandbox on Android

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 new 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.

健康数据共享

Android 15 integrates the latest extensions around Health Connect by Android, a secure and centralized platform to manage and share app-collected health and fitness data. This update adds support for new data types across fitness, nutrition, skin temperature, training plans, and more.

Skin temperature tracking allows users to store and share more accurate temperature data from a wearable or other tracking device.

Training plans are structured workout plans to help a user achieve their fitness goals. Training plans support includes a variety of completion and performance goals:

Learn more about the latest updates to Health Connect in Android in the Building adaptable experiences with Android Health talk from Google I/O.

局部屏幕共享

Android 15 supports partial 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 partial screen sharing experience. Note that for apps targeting Android 14 (API level 34) or higher, user consent is now required for each MediaProjection capture session.

用户体验和系统界面

Android 15 为应用开发者和用户提供了更大的控制力和灵活性,让他们能够根据自己的需求配置设备。

如需详细了解如何利用 Android 15 的最新改进来提升应用的用户体验,请参阅 Google I/O 大会上的提升 Android 应用的用户体验演讲。

使用 Generated Previews API 提供更丰富的 widget 预览

在 Android 15 之前,提供 widget 选择器预览的唯一方法是指定静态图片或布局资源。这些预览通常会与实际 widget 放置在主屏幕上时的外观有明显差异。此外,无法使用 Jetpack Glance 创建静态资源,因此 Glance 开发者必须对其 widget 进行屏幕截图或创建 XML 布局,才能具有 widget 预览。

Android 15 增加了对生成的预览的支持。这意味着,应用 widget 提供程序可以生成 RemoteViews(而不是静态资源)来用作选择器预览。

应用可以为 widget 选择器提供远程视图,以便更新选择器中的内容,使其更能代表用户将看到的内容。

推送 API

应用可以通过推送 API 提供生成的预览。应用可以在其生命周期的任何时间点提供预览,而不会收到主机发送的关于提供预览的明确请求。预览会保留在 AppWidgetService 中,并且主机可以按需请求预览。以下示例会加载 XML widget 布局资源,并将其设置为预览:

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

预期的流程为:

  1. 任何时候,widget 提供程序都会调用 setWidgetPreview。提供的预览与其他提供程序信息一起保留在 AppWidgetService 中。
  2. setWidgetPreview 通过 AppWidgetHost.onProvidersChanged 回调将预览更新后通知主机。作为响应,widget 主机会重新加载其所有提供程序信息。
  3. 显示 widget 预览时,托管应用会检查 AppWidgetProviderInfo.generatedPreviewCategories,如果所选类别可用,则调用 AppWidgetManager.getWidgetPreview 以返回此提供程序的已保存预览。

何时调用 setWidgetPreview

由于没有用于提供预览的回调,因此应用在运行时可以选择随时发送预览。预览的更新频率取决于 widget 的用例。

以下列表介绍了预览用例的两大主要类别:

  • 在 widget 预览中显示真实数据(例如个性化或最新信息)的提供程序。用户登录应用或在应用中完成初始配置后,这些提供程序就可以设置预览。之后,他们可以设置一个定期任务,按所选频率更新预览。此类 widget 的示例包括照片、日历、天气或新闻 widget。
  • 在预览中显示静态信息的提供程序或不显示任何数据的快速操作 widget。这些提供程序可在应用首次启动时设置一次预览。此类微件的示例包括云端硬盘“快速操作”微件或 Chrome 快捷方式微件。

某些提供程序可能会在基座接入模式选择器上显示静态预览,但在主屏幕选择器上显示真实信息。这些提供程序应遵循针对这两种用例的指南来设置预览。

画中画

Android 15 引入了对画中画 (PiP) 功能的新变更,可确保在进入画中画模式时能够更顺畅地过渡。这对于将界面元素叠加在其主界面之上的应用(将进入画中画模式)非常有用。

开发者使用 onPictureInPictureModeChanged 回调来定义用于切换叠加界面元素的可见性的逻辑。此回调会在画中画进入或退出动画播放完毕时触发。从 Android 15 开始,PictureInPictureUiState 类包含一个新状态。

借助这种新的界面状态,以 Android 15 为目标平台的应用会在画中画动画开始时立即观察到使用 isTransitioningToPip() 调用的 Activity#onPictureInPictureUiStateChanged 回调。在应用处于画中画模式时,有许多界面元素与应用无关,例如,包含建议、即将播出的视频、评分和标题等信息的视图或布局。当应用进入画中画模式时,使用 onPictureInPictureUiStateChanged 回调隐藏这些界面元素。当应用从画中画窗口进入全屏模式时,可以使用 onPictureInPictureModeChanged 回调来取消隐藏这些元素,如以下示例所示:

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

这种可快速切换不相关界面元素(适用于画中画窗口)的可见性切换有助于确保画中画进入动画更加流畅且无闪烁。

改进了“勿扰”规则

AutomaticZenRule 可让应用自定义注意力管理(勿扰)规则,并决定何时启用或停用这些规则。Android 15 大幅增强了这些规则,以改善用户体验。其中包含以下增强功能:

  • 将类型添加到 AutomaticZenRule,允许系统对某些规则应用特殊处理。
  • AutomaticZenRule 添加了图标,有助于使模式更易于识别。
  • AutomaticZenRule 添加 triggerDescription 字符串,用于描述应在哪些条件下为用户启用规则。
  • AutomaticZenRule 添加了 ZenDeviceEffects,以允许规则触发灰度显示、夜间模式或调暗壁纸等功能。

为通知渠道设置振动效果

Android 15 支持使用 NotificationChannel.setVibrationEffect 按渠道为传入的通知设置丰富的振动,以便用户可以区分不同类型的通知,而无需看自己的设备。

大屏设备和外形规格

Android 15 支持您的应用充分利用 Android 设备类型,包括大屏设备、可翻转设备和可折叠设备。

改进了大屏幕多任务处理

Android 15 为用户提供了更好的在大屏设备上进行多任务处理的方式。例如,用户可以保存他们喜欢的分屏应用组合以快速访问,还可以固定屏幕上的任务栏以在应用之间快速切换。这意味着,确保应用具有自适应能力比以往任何时候都更加重要。

Google I/O 大会举办了有关构建自适应 Android 应用使用 Material 3 自适应库构建界面的会议,这对您有所帮助。我们的文档中包含更多可以帮助您针对大屏幕进行设计的文档。

封面屏幕支持

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 继续扩展对卫星连接的平台支持,并添加了一些界面元素,以确保在卫星连接环境中提供一致的用户体验。

应用可以使用 ServiceState.isUsingNonTerrestrialNetwork() 检测设备何时连接到卫星,从而更好地了解为什么全网络服务不可用。此外,Android 15 支持短信和彩信应用以及预加载的 RCS 应用,以便使用卫星连接收发信息。

设备连接到卫星时显示通知。

更顺畅的 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 now 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 引入了一个新的钱包角色,可让您与用户首选的钱包应用更紧密地集成。此角色取代了 NFC 默认的感应式付款设置。用户可以通过导航到设置 > 应用 > 默认应用来管理 Google 钱包角色持有者。

在为付款类别中注册的 AID 路由 NFC 触碰时,可使用“钱包”角色。除非已在前台运行为同一 AID 注册的另一个应用,否则点按操作会始终转到钱包角色持有者。

此角色还可用于确定钱包“快速访问”功能块在启用后应转到的位置。当角色设置为“无”时,“快速访问”功能块不可用,并且付款类别 NFC 触碰仅会传送到前台应用。

安全性

Android 15 可帮助您增强应用的安全性,保护应用的数据,并让用户更好地了解和控制其数据。请参阅 Google I/O 大会上的在 Android 设备上保护用户安全演讲,详细了解我们为改进用户保护措施并保护您的应用免受新威胁的工作。

适用于端到端加密的密钥管理

We are introducing the E2eeContactKeysManager in Android 15, which facilitates end-to-end encryption (E2EE) in your Android apps by providing an OS-level API for the storage of cryptographic public keys.

The E2eeContactKeysManager is designed to integrate with the platform contacts app to give users a centralized way to manage and verify their contacts' public keys.

针对内容 URI 的权限检查

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

无障碍功能

Android 15 添加了一些功能来改进用户的无障碍功能。

改进盲文功能

在 Android 15 中,TalkBack 可以支持通过 USB 和安全蓝牙使用 HID 标准的盲文显示屏。

此标准与鼠标和键盘使用的标准非常相似,有助于 Android 随着时间的推移而支持更广泛的盲文显示屏。

国际化

Android 15 添加了一些特性和功能,可在以不同语言使用设备时补充用户体验。

CJK 可变字体

Starting with Android 15, the font file for Chinese, Japanese, and Korean (CJK) languages, NotoSansCJK, is now a variable font. Variable fonts open up new possibilities for creative typography in CJK languages. Designers can explore a broader range of styles and create visually striking layouts that were previously difficult or impossible to achieve.

How the variable font for Chinese, Japanese, and Korean (CJK) languages appears with different font widths.

字符间理由

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 new JUSTIFICATION_MODE_INTER_CHARACTER.
Layout for English text using the new 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 now 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.

新日语 Hentaigana 字体

在 Android 15 中,默认情况下捆绑了旧版日语平假名(称为 Hentaigana)的新字体文件。形态独特的 Hentaigana 角色可为艺术作品或设计增添独特的风格,同时有助于准确传达和理解古代日本文献。

日语 Hentaigana 字体的字符和文字样式。

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.