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 引入了低光增强,这是一种自动曝光模式,可用于Camera 2和夜间模式相机扩展。低光增强可在低光照条件下调整预览流的曝光。这与夜间模式相机扩展创建静态图像的方式不同,因为夜间模式会组合一系列照片以创建单个增强图像。虽然夜间模式非常适合创建静态图像,但它无法创建连续的帧流,而低光增强可以。因此,低光增强可实现相机功能,例如:
- 提供增强的图像预览,以便用户能够更好地取景低光照照片
- 在低光照条件下扫描二维码
如果启用低光增强,它会在低光照级别时自动开启,在光线充足时自动关闭。
应用可以在低光照条件下从预览流录制,以保存增亮的视频。
有关更多信息,请参阅低光增强。
应用内相机控制
Android 15 为在受支持的设备上更好地控制相机硬件及其算法添加了扩展
HDR 动态范围控制
Android 15 会选择适合底层设备功能和面板位深的 HDR 动态范围。对于包含大量 SDR 内容的页面(例如显示单个 HDR 缩略图的消息应用),此行为最终可能会对 SDR 内容的感知亮度产生不利影响。Android 15 允许您使用setDesiredHdrHeadroom
控制 HDR 动态范围,以在 SDR 和 HDR 内容之间取得平衡。
响度控制
Android 15 引入了对CTA-2075 响度标准的支持,以帮助您避免音频响度不一致,并确保用户在切换内容时无需不断调整音量。系统利用输出设备(耳机和扬声器)的已知特性以及 AAC 音频内容中可用的响度元数据,智能地调整音频响度和动态范围压缩级别。
要启用此功能,您需要确保 AAC 内容中提供响度元数据,并在您的应用中启用平台功能。为此,您可以通过调用其 LoudnessCodecController
对象的 create 工厂方法(使用关联的 AudioTrack
的音频会话 ID)来实例化一个 LoudnessCodecController
对象;这会自动开始应用音频更新。您可以传递一个 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 添加了对使用 USB 连接 MIDI 2.0 设备 的支持,这些设备使用通用 MIDI 数据包 (UMP) 进行通信。Android 15 将 UMP 支持扩展到虚拟 MIDI 应用,使作曲应用能够像使用 USB MIDI 2.0 设备一样控制合成器应用作为虚拟 MIDI 2.0 设备。
更高效的 AV1 软件解码
来自 VideoLAN 的流行 AV1 软件解码器 dav1d 可用于不支持硬件 AV1 解码的 Android 设备。dav1d 的性能比旧版 AV1 软件解码器高出 3 倍,使更多用户能够播放高清 AV1 视频,包括一些低端和中端设备。
您的应用需要通过名称 "c2.android.av1-dav1d.decoder"
调用它来选择使用 dav1d。在后续更新中,dav1d 将成为默认的 AV1 软件解码器。此支持已标准化并向接收 Google Play 系统更新的 Android 11 设备回传。
开发者生产力和工具
虽然我们大部分提高您生产力的工作都围绕着 Android Studio、Jetpack Compose 和 Android Jetpack 库等工具展开,但我们一直在寻找平台上的方法来帮助您更轻松地实现您的愿景。
OpenJDK 17 更新
Android 15 继续刷新 Android 的核心库的工作,使其与最新 OpenJDK LTS 版本中的功能保持一致。
包含以下关键功能和改进
- 围绕 NIO 缓冲区 的用户体验改进
- 流
- 附加的
math
和strictmath
方法 util
包更新,包括有序collection
、map
和set
ByteBuffer
在Deflater
中的支持- 安全更新,例如
X500PrivateCredential
和 安全密钥更新
这些 API 通过 Google Play 系统更新在 运行 Android 12(API 级别 31)及更高版本的十多亿台设备上更新,因此您可以定位最新的编程功能。
PDF 改进
Android 15 包含对 PdfRenderer
API 的重大改进。应用可以合并高级功能,例如渲染 受密码保护的文件、注释、表单编辑、搜索 和带有复制功能的 选择。支持线性化 PDF 优化,以加快本地 PDF 查看速度并减少资源使用。Jetpack PDF 库 使用这些 API 来简化向您的应用添加 PDF 查看功能。
PdfRenderer
已移至一个模块,该模块可以使用 Google Play 系统更新独立于平台版本进行更新,并且我们通过创建 API 表面的兼容 Android 15 之前的版本 PdfRendererPreV
来支持这些更改回传到 Android 11(API 级别 30)。
自动语言切换改进
Android 14 在音频中添加了设备上的多语言识别,并支持在语言之间自动切换,但这可能会导致单词丢失,尤其是在两种语言之间切换时暂停时间较短的情况下。Android 15 添加了其他控件,以帮助应用根据其用例调整此切换。EXTRA_LANGUAGE_SWITCH_INITIAL_ACTIVE_DURATION_TIME_MILLIS
将自动切换限制在音频会话的开头,而 EXTRA_LANGUAGE_SWITCH_MATCH_SWITCHES
在定义的切换次数后停用语言切换。如果您预计会话期间只会说一种应自动检测的语言,则这些选项特别有用。
改进的 OpenType 可变字体 API
Android 15 提高了 OpenType 可变字体的可用性。您可以使用 buildVariableFamily
API 从可变字体创建 FontFamily
实例,无需指定权重轴。文本渲染器会覆盖 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
无法为 350、450、550 和 650 Font
实例创建准确的字体权重,因此渲染器会回退到最接近的权重。因此,在这种情况下,会渲染 300 而不是 350,渲染 400 而不是 450,依此类推。相比之下,使用新版 API 创建的 Typeface
会为给定权重动态创建 Font
实例,因此也会为 350、450、550 和 650 渲染准确的权重。
细粒度的换行控制
从 Android 15 开始,TextView
和底层换行器可以保留文本的给定部分在同一行中,以提高可读性。您可以通过在字符串资源中使用 <nobreak>
标记或 createNoBreakSpan
来利用此换行自定义。类似地,您可以通过使用 <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>
这些字符串的渲染方式差异如下图所示
应用归档
Android 和 Google Play 去年宣布支持应用归档,允许用户通过从设备中部分删除使用 Android 应用包在 Google Play 上发布的不经常使用的应用来释放空间。Android 15 包含对应用归档和取消归档的操作系统级支持,使所有应用商店更容易实现它。
具有 REQUEST_DELETE_PACKAGES
权限的应用可以调用 PackageInstaller
的 requestArchive
方法来请求归档已安装的应用包,这将删除 APK 和任何缓存文件,但会保留用户数据。归档的应用通过 LauncherApps
API 作为可显示的应用返回;用户将看到一个 UI 处理,以突出显示这些应用已归档。如果用户点击归档的应用,相应的安装程序将收到一个请求来 取消归档 它,并且可以通过 ACTION_PACKAGE_ADDED
广播监控恢复过程。
图形
Android 15 带来了最新的图形改进,包括 ANGLE 和对 Canvas 图形系统的补充。
现代化 Android 的 GPU 访问
Android 硬件与早期核心操作系统在单个 CPU 上运行且使用基于固定功能管道的 API 访问 GPU 的情况相比已经发生了很大变化。Vulkan® 图形 API 自 Android 7.0(API 级别 24)以来就已在 NDK 中可用,它具有更低级别的抽象,更能反映现代 GPU 硬件,更好地扩展以支持多个 CPU 内核,并降低了 CPU 驱动程序开销,从而提高了应用性能。Vulkan 受所有现代游戏引擎的支持。
Vulkan 是 Android 首选的 GPU 接口。因此,Android 15 包括 ANGLE 作为在 Vulkan 之上运行 OpenGL® ES 的可选层。转向 ANGLE 将使 Android OpenGL 实现标准化,从而提高兼容性,并在某些情况下提高性能。您可以通过启用开发人员选项来测试 OpenGL ES 应用的稳定性和性能:在 Android 15 上的**设置 -> 系统 -> 开发人员选项 -> 实验性:启用 ANGLE**。
基于 Vulkan 的 Android ANGLE 路线图
作为简化 GPU 堆栈的一部分,未来我们将继续在更多新设备上将 ANGLE 作为 GL 系统驱动程序提供,未来预计 OpenGL/ES 将仅通过 ANGLE 提供。也就是说,我们计划**继续支持所有设备上的 OpenGL ES**。
推荐的后续步骤
使用开发人员选项为 OpenGL ES 选择 ANGLE 驱动程序并测试您的应用。对于新项目,我们强烈建议使用 Vulkan(针对 C/C++)。
Canvas 的改进
Android 15 继续对 Android 的 Canvas 图形系统进行现代化改造,并增加了更多功能。
Matrix44
提供了一个 4x4 矩阵,用于转换坐标,当您想要在 3D 环境下操作画布时应该使用它。clipShader
将当前剪裁区域与指定的着色器相交,而clipOutShader
将剪裁区域设置为当前剪裁区域与着色器的差集,两者都将着色器视为 alpha 遮罩。这支持高效绘制复杂形状。
性能和电池
Android 继续专注于帮助您提高应用的性能和质量。Android 15 引入了 API,有助于提高应用中任务的执行效率、优化应用性能以及收集有关应用的见解。
有关电池效率最佳实践、调试网络和电源使用情况以及我们如何改进 Android 15 和最新 Android 版本中后台工作的电池效率的详细信息,请参阅 Google I/O 的 改进 Android 上后台工作的电池效率 演讲。
ApplicationStartInfo API
在之前的 Android 版本中,应用启动一直有点神秘。很难在应用内确定它是从冷启动、温启动还是热启动状态启动的。也很难知道应用在各个启动阶段(例如,创建进程、调用 onCreate
、绘制第一帧等)花费了多长时间。当您的 Application
类实例化时,您无法知道应用是从广播、内容提供程序、作业、备份、启动完成、闹钟还是 Activity
启动的。
Android 15 上的 ApplicationStartInfo
API 提供了所有这些信息以及更多内容。您甚至可以选择将自己的时间戳添加到流程中,以帮助在一个地方收集计时数据。除了收集指标外,您还可以使用 ApplicationStartInfo
直接优化应用启动;例如,当应用因广播而启动时,您可以消除在 Application
类中实例化与 UI 相关的库的高昂成本。
详细的应用大小信息
自 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
类,它允许您从应用内收集性能分析信息,例如堆转储、堆配置文件、堆栈采样等。它向您的应用提供带有提供的标签的回调以标识输出文件,该文件将传递到您的应用的文件目录。该 API 会进行速率限制,以最大限度地减少性能影响。
为了简化在应用中构建性能分析请求,我们建议使用相应的 Profiling
AndroidX API,该 API 可在 Core 1.15.0-rc01 或更高版本中使用。
SQLite 数据库改进
Android 15 引入了 SQLite API,这些 API 公开了底层 SQLite 引擎的高级功能,这些功能针对应用中可能出现的特定性能问题。这些 API 包含在 SQLite 更新到 3.44.3 版本 中。
开发人员应查阅 SQLite 性能最佳实践 以充分利用其 SQLite 数据库,尤其是在处理大型数据库或运行延迟敏感查询时。
- **只读延迟事务:** 当发出只读事务(不包含写语句)时,使用
beginTransactionReadOnly()
和beginTransactionWithListenerReadOnly(SQLiteTransactionListener)
来发出只读DEFERRED
事务。此类事务可以彼此并发运行,如果数据库处于 WAL 模式,则它们可以与IMMEDIATE
或EXCLUSIVE
事务并发运行。 - **行数和 ID:** 添加了 API 来检索已更改的行数或最后插入的行 ID,无需发出其他查询。
getLastChangedRowCount()
返回当前事务中最新的 SQL 语句插入、更新或删除的行数,而getTotalChangedRowCount()
返回当前连接上的计数。getLastInsertRowId()
返回当前连接上插入的最后一行rowid
。 - **原始语句:** 发出原始 SQlite 语句,绕过便捷包装器以及它们可能产生的任何额外处理开销。
Android 动态性能框架更新
Android 15 继续投资 Android 动态性能框架 (ADPF),这是一个 API 集,允许游戏和性能密集型应用更直接地与 Android 设备的电源和热系统进行交互。在支持的设备上,Android 15 添加了 ADPF 功能。
- 提示会话的 节能模式 用于指示其关联线程应优先考虑省电而不是性能,非常适合长时间运行的后台工作负载。
- GPU 和 CPU 工作持续时间都可以在提示会话中 报告,允许系统同时调整 CPU 和 GPU 频率以最佳满足工作负载需求。
- 热裕量阈值 用于根据裕量预测来解释可能的热节流状态。
要了解如何在您的应用和游戏中使用 ADPF,请访问文档。
隐私
Android 15 包含各种功能,可帮助应用开发人员保护用户隐私。
屏幕录制检测
Android 15 添加了 对应用的支持,以检测它们是否正在被录制。每当应用在屏幕录制中可见或不可见之间转换时,都会调用回调。如果注册进程的 UID 拥有的活动正在被录制,则应用被认为是可见的。这样,如果您的应用正在执行敏感操作,您可以告知用户他们正在被录制。
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 通过 UriRelativeFilterGroup
内置了对更精确 Intent
解析的支持,它包含一组 UriRelativeFilter
对象,这些对象构成一组必须每个都满足的 Intent
匹配规则,包括 URL 查询参数、URL 片段以及阻止或排除规则。
这些规则可以在 AndroidManifest
XML 文件中使用 <uri-relative-filter-group>
标签定义,该标签可以选择包含 android:allow
标签。这些标签可以包含使用现有数据标签属性以及 android:query
和 android:fragment
属性的 <data>
标签。
这是一个 AndroidManifest
语法的示例
<intent-filter>
<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: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>
私密空间
私密空间允许用户在其设备上创建一个单独的空间,他们可以在其中将敏感应用与窥探的眼睛隔离开来,并增加一层身份验证。私密空间使用单独的用户配置文件。用户可以选择使用设备锁或单独的锁因子来保护私密空间。
私密空间中的应用在启动器中显示在单独的容器中,并在私密空间锁定后隐藏在最近使用的视图、通知、设置和其他应用中。用户生成和下载的内容(例如媒体或文件)以及帐户在私密空间和主空间之间是分开的。当私密空间解锁时,可以使用 系统共享表 和 照片选择器 来允许应用访问跨空间的内容。
用户无法将现有应用及其数据移动到私密空间。相反,用户可以选择私密空间中的安装选项,使用他们喜欢的任何应用商店安装应用。私密空间中的应用是从主空间中的任何应用安装的单独副本(同一应用的新副本)。
当用户锁定私密空间时,配置文件将停止。在配置文件停止时,私密空间中的应用将不再活动,并且无法执行前台或后台活动,包括显示通知。
我们建议您使用私有空间测试您的应用,以确保其按预期运行,尤其是在您的应用属于以下类别之一的情况下
- 具有工作配置文件逻辑的应用,这些应用假设其任何未安装在主配置文件中的副本都位于工作配置文件中。
- 医疗应用
- 启动器应用
- 应用商店应用
查询最近用户选择的“已选择照片”访问权限
当授予对媒体权限的部分访问权限时,应用现在可以仅突出显示最近选择的图片和视频。此功能可以改善频繁请求访问照片和视频的应用的用户体验。要在您的应用中使用此功能,请在通过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上的隐私沙盒
Android 15包含最新的Android广告服务扩展,其中包含最新版本的Android上的隐私沙盒。此新增功能是我们开发技术的组成部分,这些技术可以提高用户隐私,并为移动应用提供有效且个性化的广告体验。我们的隐私沙盒页面提供了有关Android隐私沙盒开发者预览版和测试版程序的更多信息,以帮助您入门。
健康连接
Android 15集成了围绕Android的健康连接的最新扩展,这是一个安全且集中的平台,用于管理和共享应用收集的健康和健身数据。此更新增加了对健身、营养、皮肤温度、训练计划等更多数据类型的支持。
皮肤温度跟踪允许用户从可穿戴设备或其他跟踪设备存储和共享更准确的温度数据。
训练计划是有结构的锻炼计划,可帮助用户实现其健身目标。训练计划支持包括各种完成和性能目标。
要了解有关Android中健康连接最新更新的更多信息,请参阅Google I/O上的使用Android Health构建自适应体验主题演讲。
部分屏幕共享
Android 15支持部分屏幕共享,因此用户可以共享或录制应用程序窗口而不是整个设备屏幕。此功能(首次在Android 14 QPR2中启用)包括MediaProjection
回调,允许您的应用自定义部分屏幕共享体验。请注意,对于目标为Android 14(API级别34)或更高的应用,每次MediaProjection
捕获会话都需要用户同意。
用户体验和系统UI
Android 15让应用开发者和用户可以更灵活地控制和配置其设备以满足其需求。
要了解有关如何使用Android 15中的最新改进以改善您的应用用户体验的更多信息,请参阅Google I/O上的改进您的Android应用的用户体验主题演讲。
使用生成的预览 API 提供更丰富的窗口小部件预览
在Android 15之前,提供窗口小部件选择器预览的唯一方法是指定静态的图像或布局资源。这些预览通常与窗口小部件放置在主屏幕上的实际外观差异很大。此外,静态资源无法使用Jetpack Glance创建,因此Glance开发者必须对其窗口小部件进行截图或创建XML布局才能拥有窗口小部件预览。
Android 15增加了对生成预览的支持。这意味着应用窗口小部件提供程序可以生成RemoteViews
用作选择器预览,而不是静态资源。
推送API
应用可以通过推送API提供生成的预览。应用可以在其生命周期的任何时间点提供预览,并且不会收到主机的显式请求来提供预览。预览会保存在AppWidgetService
中,主机可以按需请求它们。以下示例加载XML窗口小部件布局资源并将其设置为预览。
AppWidgetManager.getInstance(appContext).setWidgetPreview(
ComponentName(
appContext,
SociaLiteAppWidgetReceiver::class.java
),
AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
RemoteViews("com.example", R.layout.widget_preview)
)
预期的流程是
- 在任何时候,窗口小部件提供程序都会调用
setWidgetPreview
。提供的预览会与其他提供程序信息一起保存在AppWidgetService
中。 setWidgetPreview
通过AppWidgetHost.onProvidersChanged
回调通知主机已更新的预览。作为响应,窗口小部件主机将重新加载其所有提供程序信息。- 在显示窗口小部件预览时,主机会检查
AppWidgetProviderInfo.generatedPreviewCategories
,如果选择的类别可用,则调用AppWidgetManager.getWidgetPreview
来返回此提供程序的已保存预览。
何时调用setWidgetPreview
由于没有提供预览的回调,因此应用可以选择在其运行的任何时间点发送预览。更新预览的频率取决于窗口小部件的使用情况。
以下列表描述了预览使用案例的两个主要类别
- 在窗口小部件预览中显示真实数据的提供程序,例如个性化信息或最近的信息。这些提供程序可以在用户登录或在其应用中完成初始配置后设置预览。在此之后,他们可以设置定期任务以按照其选择的节奏更新预览。此类窗口小部件的示例可能是照片、日历、天气或新闻窗口小部件。
- 在预览中显示静态信息或不显示任何数据的快速操作窗口小部件的提供程序。这些提供程序可以在应用首次启动时设置预览。此类窗口小部件的示例包括驱动器快速操作窗口小部件或Chrome快捷方式窗口小部件。
某些提供程序可能会在中心模式选择器中显示静态预览,但在主屏幕选择器中显示真实信息。这些提供程序应遵循这两个用例的指南来设置预览。
画中画
Android 15对画中画 (PiP) 进行了更改,确保在进入PiP模式时过渡更加流畅。这对于在主UI之上叠加UI元素的应用进入PiP模式将非常有益。
开发者使用onPictureInPictureModeChanged
回调来定义切换叠加UI元素可见性的逻辑。此回调会在PiP进入或退出动画完成后触发。从Android 15开始,PictureInPictureUiState
类包含另一个状态。
使用此UI状态,目标为Android 15(API级别35)的应用将在PiP动画开始时观察到Activity#onPictureInPictureUiStateChanged
回调被调用,其中isTransitioningToPip()
为true。当应用处于PiP模式时,许多UI元素与应用无关,例如包含建议、即将播放的视频、评分和标题等信息的视图或布局。当应用进入PiP模式时,使用onPictureInPictureUiStateChanged
回调隐藏这些UI元素。当应用从PiP窗口进入全屏模式时,使用onPictureInPictureModeChanged
回调显示这些元素,如下例所示。
override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
if (pipState.isTransitioningToPip()) {
// Hide UI elements
}
}
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
if (isInPictureInPictureMode) {
// Unhide UI elements
}
}
这种无关UI元素(对于PiP窗口)的快速可见性切换有助于确保更流畅且无闪烁的PiP进入动画。
改进的请勿打扰规则
AutomaticZenRule
允许应用自定义注意力管理(请勿打扰)规则并决定何时激活或停用它们。Android 15极大地增强了这些规则,目标是改善用户体验。包含以下增强功能:
- 向
AutomaticZenRule
添加类型,允许系统对某些规则应用特殊处理。 - 向
AutomaticZenRule
添加图标,有助于使模式更易于识别。 - 向
AutomaticZenRule
添加triggerDescription
字符串,描述规则应为用户激活的条件。 - 向
AutomaticZenRule
添加了ZenDeviceEffects
,允许规则触发诸如灰度显示、夜间模式或调暗壁纸等操作。
为通知渠道设置VibrationEffect
Android 15 支持使用 NotificationChannel.setVibrationEffect
为每个渠道的来电通知设置丰富的振动效果,以便用户无需查看设备即可区分不同类型的通知。
媒体投射状态栏芯片和自动停止
媒体投射可能会泄露用户的隐私信息。新的醒目状态栏芯片会提醒用户当前是否有屏幕投射正在进行。用户可以点击该芯片停止屏幕投射、共享或录制。此外,为了提供更直观的用户体验,当设备屏幕锁定后,任何正在进行的屏幕投射都会自动停止。
大屏幕和多种设备形态
Android 15 为您的应用提供了充分利用 Android 设备形态的支持,包括大屏幕、翻盖式和折叠式设备。
改进的大屏幕多任务处理
Android 15 为用户提供了在大屏幕设备上进行多任务处理的更好方法。例如,用户可以保存他们最喜欢的分屏应用组合以方便快速访问,并可将任务栏固定在屏幕上以便快速切换应用。这意味着确保您的应用具有自适应性比以往任何时候都更重要。
Google I/O 提供了关于 构建自适应 Android 应用 和 使用 Material 3 自适应库构建 UI 的会议,我们的文档还提供了更多帮助您 为大屏幕设计 的信息。
保护屏幕支持
您的应用可以 声明一个属性,Android 15 使用该属性允许您的 Application
或 Activity
在支持的翻盖式设备的小型保护屏幕上显示。这些屏幕太小,无法被视为 Android 应用运行的兼容目标,但您的应用可以选择支持它们,从而使您的应用可在更多地方使用。
连接
Android 15 更新了平台,使您的应用能够访问通信和无线技术的最新进展。
卫星支持
Android 15 继续扩展对卫星连接的平台支持,并包含一些 UI 元素以确保在卫星连接环境中提供一致的用户体验。
应用可以使用 ServiceState.isUsingNonTerrestrialNetwork()
检测设备何时连接到卫星,从而使其更了解为什么完整网络服务可能不可用。此外,Android 15 还支持短信和彩信应用以及预加载的 RCS 应用使用卫星连接发送和接收消息。
更流畅的 NFC 体验
Android 15 致力于使“轻触支付”体验更无缝、更可靠,同时继续支持 Android 强大的 NFC 应用生态系统。在支持的设备上,应用可以请求 NfcAdapter
进入 观察模式,在该模式下,设备会监听但不会响应 NFC 读卡器,并将应用的 NFC 服务 PollingFrame
对象 发送到处理程序。 PollingFrame
对象可用于在与 NFC 读卡器进行首次通信之前进行身份验证,在许多情况下允许一次轻触完成交易。
此外,应用可以在支持的设备上 注册过滤器,以便它们可以收到轮询循环活动的通知,从而允许与多个支持 NFC 的应用程序顺利运行。
钱包角色
Android 15 引入了一个钱包角色,允许与用户的首选钱包应用更紧密地集成。此角色取代了 NFC 默认的非接触式支付设置。用户可以通过导航到**设置 > 应用 > 默认应用**来管理钱包角色持有者。
此角色用于在为支付类别中注册的 AID 路由 NFC 轻触时使用。轻触操作始终会传递给钱包角色持有者,除非另一个为同一 AID 注册的应用正在前台运行。
此角色还用于确定激活时钱包快速访问磁贴的位置。当角色设置为“无”时,快速访问磁贴不可用,并且支付类别 NFC 轻触操作仅传递给前台应用。
安全
Android 15 可帮助您增强应用的安全性,保护应用数据,并为用户提供更多关于其数据的透明度和控制权。请参阅 Google I/O 上关于 保护 Android 上的用户安全 的演讲,以了解我们为改进用户保护措施并保护您的应用免受新的威胁所做的更多努力。
将凭据管理器与自动填充集成
从 Android 15 开始,开发人员可以 将特定视图(如用户名或密码字段)与凭据管理器请求链接,从而更轻松地在登录过程中提供量身定制的用户体验。当用户将焦点放在这些视图之一上时,相应的请求将发送到凭据管理器。生成的凭据将在提供商之间进行汇总,并在自动填充后备 UI(例如内联建议或下拉建议)中显示。Jetpack androidx.credentials 库是开发人员首选的端点,并且很快就会可用,以进一步增强 Android 15 及更高版本中的此功能。
将单点登录和单点注册与生物识别提示集成
凭据管理器 将生物识别提示集成到凭据创建和登录过程中,无需提供商管理生物识别提示。因此,凭据提供商只需要关注创建和获取流程的结果,并增加生物识别流程的结果。此简化流程创建了更高效、更精简的凭据创建和检索流程。
端到端加密的关键管理
我们在 Android 15 中引入了 E2eeContactKeysManager
,它通过提供用于存储加密公钥的操作系统级 API 来促进 Android 应用中的端到端加密 (E2EE)。
E2eeContactKeysManager
旨在与平台联系人应用集成,为用户提供集中管理和验证其联系人公钥的方法。
内容 URI 的权限检查
Android 15 引入了一组 API,用于对内容 URI 执行权限检查。
Context.checkContentUriPermissionFull
:这会对内容 URI 执行完整的权限检查。Activity
清单属性requireContentUriPermissionFromCaller
:这会在活动启动时对提供的内容 URI 强制执行指定的权限。ComponentCaller
类 用于Activity
调用者:这代表启动该活动的应用。
辅助功能
Android 15 添加了可改善用户辅助功能的功能。
更好的盲文支持
在 Android 15 中,我们使 TalkBack 可以支持通过 USB 和安全蓝牙使用 HID 标准的盲文显示器。
与鼠标和键盘使用的标准类似,此标准将有助于 Android 随着时间的推移支持更广泛的盲文显示器。
国际化
Android 15 添加了一些功能和特性,可以提升设备在不同语言环境下的用户体验。
中日韩 (CJK) 可变字体
从 Android 15 开始,中文、日文和韩文 (CJK) 语言的字体文件 NotoSansCJK 现在是可变字体。可变字体为 CJK 语言的创意排版提供了更多可能性。设计师可以探索更广泛的样式,并创建以前难以实现或无法实现的视觉效果引人注目的布局。
字间对齐
从 Android 15 开始,可以使用 JUSTIFICATION_MODE_INTER_CHARACTER
通过使用字母间距来对齐文本。字间对齐功能最早在 Android 8.0(API 级别 26)中推出,字间对齐为使用空格字符进行分段的语言(如中文、日文等)提供了类似的功能。
自动换行配置
Android 从 Android 13(API 级别 33)开始支持基于短语的日文和韩文换行。但是,虽然基于短语的换行可以提高短文本行的可读性,但它们并不适用于长文本行。在 Android 15 中,应用可以使用 LINE_BREAK_WORD_STYLE_AUTO
选项仅为短文本行应用基于短语的换行。此选项将为文本选择最佳的单词样式选项。
对于短文本行,使用基于短语的换行符,其功能与LINE_BREAK_WORD_STYLE_PHRASE
相同,如下图所示
对于长文本行,LINE_BREAK_WORD_STYLE_AUTO
使用无换行符样式,其功能与LINE_BREAK_WORD_STYLE_NONE
相同,如下图所示
新增日文片假名字体
Android 15 默认捆绑了一个旧日文平假名(称为片假名)的字体文件。片假名字符独特的形状可以为艺术作品或设计增添独特的风格,同时也有助于准确地传递和理解古代日文文档。
VideoLAN 圆锥体版权所有 (c) 1996-2010 VideoLAN。任何人都可以使用或修改此徽标或其修改版本来指代 VideoLAN 项目或 VideoLAN 团队开发的任何产品,但这并不表示该项目认可。
Vulkan 和 Vulkan 徽标是 Khronos Group Inc. 的注册商标。
OpenGL 是注册商标,OpenGL ES 徽标是 Hewlett Packard Enterprise 的商标,经 Khronos 许可使用。