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
andTORCH
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.
音量控制
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, 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 Studio、Jetpack Compose 和 Android 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:
- Quality-of-life improvements around NIO buffers
- Streams
- Additional
math
andstrictmath
methods util
package updates including sequencedcollection
,map
, andset
ByteBuffer
support inDeflater
- Security updates such as
X500PrivateCredential
and security key updates
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 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 improves the usability of the OpenType variable font. You can now
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 new API, this 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:
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.
细化的换行符控件
从 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>
这些字符串的呈现方式差异如下图所示:
应用归档
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 now 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.
图形
Android 15 引入了最新的图形改进,包括 ANGLE 以及对 Canvas 图形系统的补充。
对 Android 的 GPU 访问功能进行现代化改造
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
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, whileclipOutShader
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 includes the all-new ProfilingManager
class, which lets you
collect profiling information from within your app. We're planning to wrap this
with an Android Jetpack API that will simplify construction of profiling
requests, but the core API will allow the collection of 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.
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()
andbeginTransactionWithListenerReadOnly(SQLiteTransactionListener)
to issue read-onlyDEFERRED
transactions. Such transactions can run concurrently with each other, and if the database is in WAL mode, they can run concurrently withIMMEDIATE
orEXCLUSIVE
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, whilegetTotalChangedRowCount()
returns the count on the current connection.getLastInsertRowId()
returns therowid
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 will add new 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 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>
私密空间
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:
- Apps with logic for work profiles that assumes that any installed copies of their app that aren't in the main profile are in the work profile.
- Launcher apps
- App store apps
查询所选照片访问权限的最近用户选择
It is now possible for apps to highlight only the most recently selected photos
and videos when partial access to media permissions is granted. This
feature can improve the user experience for apps that frequently request
access to photos and videos. To use this feature in your app, enable the
QUERY_ARG_LATEST_SELECTION_ONLY
argument when querying MediaStore
through 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) });
Privacy Sandbox on Android
Android 15 包含最新的 Android 广告服务扩展程序,以及最新版 Privacy Sandbox on Android。我们致力于开发新的技术,以便更好地保护用户隐私,并为移动应用打造有效的个性化广告体验。这项新功能是我们的工作的一部分。我们的隐私沙盒页面详细介绍了 Privacy Sandbox on Android 开发者预览版和 Beta 版计划,以帮助您开始使用。
健康数据共享
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:
- Completion goals around calories burned, distance, duration, repetition, and steps.
- Performance goals around as many repetitions as possible (AMRAP), cadence, heart rate, power, perceived rate of exertion, and speed.
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 预览
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.
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:
- At any time, the widget provider calls
setWidgetPreview
. The provided previews are persisted inAppWidgetService
with other provider info. setWidgetPreview
notifies hosts of an updated preview through theAppWidgetHost.onProvidersChanged
callback. In response, the widget host reloads all of its provider information.- When displaying a widget preview, the host checks
AppWidgetProviderInfo.generatedPreviewCategories
, and if the chosen category is available, callsAppWidgetManager.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 new 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 a new state.
With this new UI state, apps targeting Android 15 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
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 toAutomaticZenRule
that describes the conditions on which the rule should become active for the user. - Added
ZenDeviceEffects
toAutomaticZenRule
, allowing rules to trigger things like grayscale display, night mode, or dimming the wallpaper.
为通知渠道设置振动效果
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 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.
更顺畅的 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 fingerprint 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 new 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 QuickAccess tile should go when activated. When the role is set to "None", the QuickAccess tile isn't available and payment category NFC taps are only delivered to the foreground app.
安全性
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:
Context.checkContentUriPermissionFull
: This performs a full permission check on content URIs.Activity
manifest attributerequireContentUriPermissionFromCaller
: This enforces specified permissions on the provided content URIs at activity launch.ComponentCaller
class forActivity
callers: This represents the app that launched the activity.
无障碍功能
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 添加了一些特性和功能,可在以不同语言使用设备时补充用户体验。
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.
字符间理由
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.
自动换行配置
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 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:
新日语 Hentaigana 字体
In Android 15, a new 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.
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.