lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Android P 功能和 API

Android P 为用户和开发者引入众多新特性和新功能。

本文重点介绍面向开发者的新功能。 要了解新 API,请阅读 API 差异报告或访问 Android API 参考 — 为醒目起见,将突出显示新 API。 请务必查阅 Android P 行为变更以了解平台变更可能给您的应用带来哪些方面的影响。

利用 Wi-Fi RTT 进行室内定位

全新 RTT API 支持在应用中进行室内定位。

Android P 添加了对 IEEE 802.11mc Wi-Fi 协议(也称为 Wi-Fi Round-Trip-Time (RTT))的平台支持,从而让您的应用可以利用室内定位功能。

在提供硬件支持的 Android P 设备上,应用可以使用全新的 RTT API 来测量与附近支持 RTT 的 Wi-Fi 接入点 (AP) 的距离。 设备必须已启用定位并开启了 Wi-Fi 扫描(在 Settings > Location 下),同时您的应用必须具有 ACCESS_FINE_LOCATION 权限。 设备不需要连接至 AP 即可使用 RTT。 为保证隐私性,只有手机可以确定与 AP 的距离;AP 不具备该信息。

如果您的设备测量与 3 个或更多 AP 的距离,您可以使用一个多点定位算法来预估与这些测量值最相符的设备位置。 结果通常精准至 1 至 2 米。

通过这种精确性,您可以打造新的体验,例如楼内导航、基于精细位置的服务,如无歧义语音控制(例如,“打开这盏灯”),以及基于位置的信息(如 “此产品是否有特别优惠?”)。

屏幕缺口支持

显示各种凹口屏幕尺寸的开发者选项界面

通过使用模拟器测试凹口屏幕。

Android P 支持最新的全面屏以及为摄像头和扬声器预留空间的凹口屏幕。 通过全新的 DisplayCutout 类,可以确定非功能区域的位置和形状,这些区域不应显示内容。 要确定这些凹口屏幕区域是否存在及其位置,请使用 getDisplayCutout() 函数。

全新的窗口布局属性 layoutInDisplayCutoutMode 让您的应用可以为设备凹口屏幕周围的内容进行布局。 您可以将此属性设为下列值之一:

您可以按如下方法在任何运行 Android P 的设备或模拟器上模拟屏幕缺口:

  1. 启用开发者选项
  2. Developer options 屏幕中,向下滚动至 Drawing 部分并选择 Simulate a display with a cutout
  3. 选择凹口屏幕的大小。

注:我们建议您通过使用运行 Android P 的设备或模拟器测试凹口屏幕周围的内容显示。

通知

Android P 引入了多个通知增强功能,可供以 Android P 及更高版本作为目标平台的开发者使用。

短信通知

附带了照片的 MessagingStyle。

短信通知

含回复和对话的 MessagingStyle。

提升短信体验

从 Android 7.0(API 级别 24)开始,您可以添加一个操作以回复短信或直接从通知中输入其他文本。 Android P 通过下列增强提升了该功能:

  • 支持图像:现在,Android P 可在手机的“短信通知”中显示图像。 您可以使用短信中的 setData() 来显示图像。

  • 简化了针对对话参与者的支持:全新的 Notification.Person 类可用于识别参与对话的人员,包括他们的头像和 URI。 现在,许多其他 API(如 addMessage())均可利用 Person 类,而不是 CharSequence

  • 将回复另存为草稿:当用户无意中关闭一个短信通知时,您的应用可以检索系统发送的 EXTRA_REMOTE_INPUT_DRAFT。 您可以使用此 extra 预填充应用中的文本字段,以便用户可以完成他们的回复。

  • 确定对话是否为群组对话。您可以使用 setGroupConversation() 以明确确定对话是否为群组对话。

  • 为 Intent 设置语义操作:setSemanticAction() 函数允许您为操作提供语义含义,如标记为已读、删除、回复等。

  • SmartReply:Android P 支持您的短信应用中提供的建议回复。 使用 RemoteInput.setChoices() 为用户提供一组标准回复。

渠道设置、广播和请勿打扰

Android O 引入了通知渠道,从而允许您为要显示的每种通知类型创建可由用户自定义的渠道。

Android P 通过下列变更简化通知渠道设置:

  • 屏蔽渠道组:现在,用户可以针对某个应用在通知设置中屏蔽整个渠道组。 您可以使用 isBlocked() 函数确定何时屏蔽一个渠道组,从而不会向该组中的渠道发送任何通知。

    此外,您的应用可以使用全新的 getNotificationChannelGroup() 函数查询当前渠道组设置。

  • 全新的广播 Intent 类型:现在,当通知渠道和渠道组的屏蔽状态发生变更时,Android 系统将发送广播 Intent。 拥有已屏蔽的渠道或渠道组的应用可以侦听这些 Intent 并做出相应的回应。 有关这些 Intent 操作和 extra 的更多信息,请参阅 NotificationManager 参考中更新的常量列表。 有关响应广播 Intent 的信息,请参阅广播

  • 新的“请勿打扰”优先级类别: NotificationManager.Policy 具有两个新的策略常量:PRIORITY_CATEGORY_ALARMS(确定闹铃优先级)和 PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER(确定媒体、系统和游戏声音优先级)。

多摄像头支持和摄像头更新

现在,在运行 Android P 的设备上,您可以通过两个或更多物理摄像头来同时访问多个视频流。 在配备双前置摄像头或双后置摄像头的设备上,您可以创建只配备单摄像头的设备所不可能实现的创新功能,例如无缝缩放、虚化和立体成像。 通过此 API,您还可以调用逻辑或融合的摄像头视频流,该视频流可在两个或更多摄像头之间自动切换。

摄像头方面的其他改进还包括新的会话参数和 Surface 共享,前者有助于降低首次拍照期间的延迟,而后者则让摄像头客户端能够处理各种用例,而无需停止并启动摄像头视频流。 我们还针对基于显示屏的 flash 支持OIS 时间戳访问新增了一些 API,用以实现应用级的图像稳定化和特效。

在受支持的设备上,Android P 还支持外置 USB/UVC 摄像头

适用于位图和可绘制对象的 ImageDecoder

Android P 引入 ImageDecoder ,以提供现代化的图像解码方法。 您应使用 ImageDecoder 来解码图像,而不是使用 BitmapFactoryBitmapFactory.Options API。

ImageDecoder 让您可以从字节缓冲区、文件或 URI 来创建 DrawableBitmap。 要解码图像,请首先以编码图像的来源为参数,调用 createSource()。 然后,通过传递 ImageDecoder.Source 对象来调用 decodeBitmap()decodeDrawable() ,从而创建 BitmapDrawable。 要更改默认设置,请将 OnHeaderDecodedListener 传递给 decodeBitmap()decodeDrawable()ImageDecoder 以图像的默认宽度和高度(若已知的话)为参数,调用onHeaderDecoded()。 如果编码图像是动画 GIF 或 WebP,decodeDrawable() 将返回 Drawable,后者是 AnimatedImageDrawable 类的一个实例。

您可以使用不同的方法来设置图像属性。 这些方法包括:

  • 要将解码的图像缩放到精确尺寸,请以目标尺寸为参数,调用 setResize()。 您也可以使用样图尺寸来缩放图像。 将样图尺寸直接传递给 setResize(),或者调用getSampledSize() 以查看 ImageDecoder 能够最高效地获取何种尺寸的样图。
  • 要在缩放图像的范围内裁剪图像,请调用 setCrop()
  • 要创建可变的 Bitmap,请调用 setMutable(true)

通过 ImageDecoder,您还可以为圆角或圆形遮罩之类的图像添加复杂的定制效果。 以 PostProcessor 类的一个实例作为参数,使用 setPostProcessor() 来执行您希望绘制命令执行的任何工作。 当您对 AnimatedImageDrawable 进行后处理时,这些效果会作用与所有框。

动画

Android P 引入了一个新的 AnimatedImageDrawable 类,用于绘制和显示 GIF 和 WebP 动画图像。 AnimatedImageDrawable 的工作方式 AnimatedVectorDrawable 的相似之处在于,都是 RenderThread 驱动 AnimatedImageDrawable 的动画。 RenderThread 还使用工作线程进行解码,因此,解码不会干扰 RenderThread。 这种实现机制允许您的应用在使用动画图像时不必管理其更新,也不会干扰应用的界面线程。

可使用新的 ImageDecoder 解码 AnimagedImageDrawable。 以下代码段演示如何使用 ImageDecoder 来解码 AnimatedImageDrawable

Drawable d = ImageDecoder.decodeDrawable(...);
if (d instanceof AnimatedImageDrawable) {
    ((AnimatedImageDrawable) d).start();   // Prior to start(), the first frame is displayed
}

ImageDecoder 有几种方法可用来进一步修改图像。 例如,您可以使用 setPostProcessor() 函数来修改图像的外观,例如应用圆形遮罩或圆角。

HDR VP9 视频、HEIF 图像压缩和 Media API

Android P 新增对 High Dynamic Range (HDR) VP9 Profile 2 的内置支持,因此,现在您可以在支持 HDR 的设备上为用户提供来自 YouTube、Play Movies 和其他来源的采用 HDR 的影片。

Android P 为平台增加了对 HEIF (heic) 图像编码的支持。 MediaMuxerMediaExtractor 类中可支持 HEIF 静态图像示例 HEIF 改进了压缩,可节省存储空间和网络数据流量。 借助 Android P 设备上的平台支持,从后端服务器发送和使用 HEIF 图像轻而易举。 确保应用兼容这种便于共享和显示的数据格式后,尝试在应用中使用 HEIF 作为图像存储格式。 您可以使用 ImageDecoderBitmapFactory 进行 jpeg 到 heicto 的转换,以通过 jpeg 获取位图,并且可以使用全新支持库 alpha 版中的 HeifWriter 编写来自 YUV 字节缓冲区、Surface 或 Bitmap 的 HEIF 静态图像。

另外,Android P 还引入了 MediaPlayer2。 此播放器支持使用 DataSourceDesc 构建的播放列表。 要创建 MediaPlayer2 的实例,请使用 MediaPlayer2.create()

现在,还可通过 AudioTrackAudioRecordMediaDrm 类获取媒体指标。

Android P 向 MediaDRM 类添加了新函数以获取指标、高带宽数字内容保护 (HDCP) 级别、安全级别和会话数,并对安全性级别和安全停止进行更多控制。 如需了解更多详情,请参阅 API 差异报告

JobScheduler 中的数据成本敏感度

Android P 中对 JobScheduler 进行了改进,使其可以更好地为用户处理网络相关的作业,从而与运营商独立提供的网络状态信号相协调。

现在,作业可以声明其预估的数据大小、信号预提取,并指定具体的网络要求,而运营商可以报告网络拥塞无限流量。 然后,JobScheduler 根据网络状态管理工作。 例如,当网络拥塞时,JobScheduler 可能会延迟较大的网络请求。 如果使用的是无限流量网络,则 JobScheduler 可运行预提取作业以提升用户体验(例如预提取标题)。

添加作业时,确保使用 setEstimatedNetworkBytes()setIsPrefetch()setRequiredNetwork()(如果适用),以帮助 JobScheduler 正确处理工作。 在执行作业时,请确保使用 JobParameters.getNetwork() 返回的 Network 对象。 否则,您将隐式使用设备的默认网络,其可能不符合您的要求,从而导致意外的流量消耗

Neural Networks API 1.1

Android 8.1(API 级别 27)中引入了 Neural Networks API 以加快 Android 设备上机器学习的速度。 Android P 扩展并改进了该 API,从而增加了对 Pad、BatchToSpaceND、SpaceToBatchND、Transpose、Strided Slice、Mean、Div、Sub 和 Squeeze 九个新运算的支持。

自动填充框架

Android 8.0(API 级别 26)引入了自动填充框架,简化了应用中的表单填写。 Android P 引入了多项改进,自动填充服务可以利用这些改进进一步增强用户填写表单时的体验。 如需了解更多详情,请参阅自动填充框架页面。

安全增强功能

Android P 引入了许多新的安全功能,包括统一的指纹身份验证对话框和针对敏感交易的高可信度用户确认。 如需了解更多详情,请参阅安全性更新页面。

Android 备份的客户端加密

Android P 支持使用客户端密钥加密 Android 备份。 由于此隐私措施,在从用户设备制作的备份恢复数据时,会要求提供设备的 PIN 码、图案或密码。 如需详细了解这项新功能背后的技术,请参阅 Google 云密钥保险柜服务白皮书。

如需了解有关在 Android 设备上备份数据的详细信息,请参阅数据备份概览

无障碍功能

Android P 引入一些操作、属性和函数,让您可以更轻松地使用无障碍功能框架,从而改善针对用户的无障碍服务。

如需了解有关如何让您的应用更便于访问以及如何构建无障碍服务的更多信息,请参阅无障碍功能

导航语义

我们新增了一些属性,可用来改善从屏幕的某个部分导航到另一个部分的体验。 您可以使用这些属性来帮助用户在应用的文本内部移动并将用户快速导航至应用界面的某个区域。

例如,在购物应用中,屏幕阅读器可以将用户直接从某个交易类别导航至下一个交易类别,而不必经过这些类别内部的每一项交易。

无障碍功能窗格标题

在 Android P 之前,无障碍服务无法轻松确定屏幕的某个区域是否经过更新,例如在 Fragment 过渡期间。

在 Android P 中,各个窗格区域的标题现在采用 accessibility pane titles 的格式。 无障碍服务可以收到这些标题的变更,从而能够提供关于所做变更的更精细信息。

要指定某个区域的标题,请使用新的 android:accessibilityPaneTitle 属性。 您也可以更新您在运行时使用 setAccessibilityPaneTitle() 替换的某个界面区域的标题。 例如,您可以为某个 Fragment 对象的内容区域提供标题。

基于标题的导航

如果您的应用显示的内容包含具有逻辑含义的标题,则对于表示这些标题的 View 实例,将新的 android:accessibilityHeading 属性设置为 true。 这样,用户可以从一个标题导航至下一个标题。 在用户操作屏幕阅读器时,这种导航过程尤其方便。

群组导航和输出

传统上,屏幕阅读器一直使用 android:focusable 属性来确定应该将屏幕的哪些区域作为一个整体进行读取。 有时,这些屏幕阅读器需要将几个 View 对象的内容视作一个整体。 这样,用户就可以了解,这些视图在逻辑上彼此相关。

在 Android P 之前,您需要将每个内部 View 对象标记为不可聚焦的对象并且将包含这些对象的群组标记为可聚焦。 这种安排导致 View 的某些实例被标记为可聚焦,这使得键盘导航变得更为繁琐。

在 Android P 中,在将 View 对象标记为可聚焦会造成不想要的负面作用时,您可以使用新的 android:screenReaderFocusable 属性代替 android:focusable 属性。 屏幕阅读器应当聚焦在所有将 android:screenReaderFocusableandroid:focusable 设置为 true 的元素上。

便捷操作

Android P 新增了一些方便用户执行操作的支持功能:

访问提示: 无障碍框架中的新功能让您可在应用界面中访问提示。 使用 getTooltipText() 读取提示文本,使用新的 ACTION_SHOW_TOOLTIPACTION_HIDE_TOOLTIP 来指示 View 的实例显示或隐藏提示。

新的全局操作: Android P 在 AccessibilityService 类中引入了对两个新设备操作的支持。 您的 Service 现在可以帮助用户分别使用 GLOBAL_ACTION_LOCK_SCREENGLOBAL_ACTION_TAKE_SCREENSHOT 操作锁定其设备并进行屏幕截图。

窗口变更详情

Android P 让您可以在应用同时重绘多个窗口时,更轻松地跟踪应用窗口的更新。 当发生 TYPE_WINDOWS_CHANGED 事件时,可使用 getWindowChanges() API 来确定窗口发生的变更。 现在,在多窗口更新期间,每个窗口都会生成自己的一组事件。 getSource() 函数返回与每个事件相关联的窗口的根视图。

如果应用已为其 View 对象定义无障碍功能窗格标题,您的 Service 将可以识别应用界面何时进行更新。 当发生 TYPE_WINDOW_STATE_CHANGED 事件时,可使用 getContentChangeTypes() 所返回的新类型来确定窗口发生的变更。 例如,框架现在可以检测窗格何时有新标题或者窗格何时消失。

旋转

为避免无意的旋转,我们新增了一个模式,哪怕设备位置发生变化,也会固定在当前屏幕方向上。 必要时用户可以通过按系统栏上的一个新增按钮手动触发旋转。

在大多数情况下,对应用的兼容性影响应该微不足道。 不过,如果您的应用有任何自定义旋转行为,或使用了任何机密的屏幕方向设置,则可能会遇到以前用户旋转首选项始终设置为纵向时被忽视的问题。 我们鼓励您审视一下您的应用所有关键 Activity 中的旋转行为,并确保您的所有屏幕方向设置仍可提供最佳体验。

如需了解更多详情,请参阅关联的行为变更

一个新的旋转模式允许用户在必要时利用系统栏上的一个按钮手动触发旋转。