北京时间 8 月 7 日上午,Google 正式发布 Android 9.0 正式版系统,并宣布系统版本 Android P 被正式命名为代号「Pie」。
目前,Google 已向全球 Pixel 设备推送了 Android 9.0 正式版的更新。
作为忠实Android用户,也同样作为一名Android开发人员,每一个版本的发布都是业内大事,当天的关注必不可少,但也很惭愧时隔将近一个月才来总结,接下来,我将把我看到的东西慢慢分享。
这个手捧着红豆派的小可爱,主打全新的人工智能系统,号称让手机变得更智能、更快,而且“越用越懂你”,其核心闪光点也就是对时下最流行的神经网络机器学习算法的融合,将系统打造成为一款能通过大量频繁的使用来预测和计算用户行为习惯,并为之做出最舒适调整方案的系统。
那么Android 9.0(API级别28)到底都提供了哪些功能呢?(接下来是一段官方摘录)
利用 Wi-Fi RTT 进行室内定位
Android 9 添加了对 IEEE 802.11mc Wi-Fi 协议(也称为 Wi-Fi Round-Trip-Time (RTT))的平台支持,从而让您的应用可以利用室内定位功能。
在运行 Android 9 且具有硬件支持的设备上,应用可以使用 RTT API 来测量与附近支持 RTT 的 Wi-Fi 接入点 (AP) 的距离。 设备必须已启用位置服务并开启 Wi-Fi 扫描(在 Settings > Location 下),同时您的应用必须具有 ACCESS_FINE_LOCATION
权限。
设备无需连接到接入点即可使用 RTT。 为了保护隐私,只有手机可以确定与接入点的距离;接入点无此信息。
如果您的设备测量与 3 个或更多接入点的距离,您可以使用一个多点定位算法来预估与这些测量值最相符的设备位置。 结果通常精准至 1 至 2 米。
通过这种精确性,您可以打造新的体验,例如楼内导航、基于精细位置的服务,如无歧义语音控制(例如,“打开这盏灯”),以及基于位置的信息(如 “此产品是否有特别优惠?”)。
显示屏缺口支持
通过使用模拟器测试屏幕缺口。
Android 9 支持最新的全面屏,其中包含为摄像头和扬声器预留空间的屏幕缺口。 通过 DisplayCutout
类可确定非功能区域的位置和形状,这些区域不应显示内容。 要确定这些屏幕缺口区域是否存在及其位置,请使用 getDisplayCutout()
函数。
全新的窗口布局属性 layoutInDisplayCutoutMode
让您的应用可以为设备屏幕缺口周围的内容进行布局。 您可以将此属性设为下列值之一:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
可以按以下方法在任何运行 Android 9 的设备或模拟器上模拟屏幕缺口:
- 启用开发者选项。
- 在 Developer options 屏幕中,向下滚动至 Drawing 部分并选择 Simulate a display with a cutout。
- 选择屏幕缺口的大小。
注:我们建议您通过使用运行 Android 9 的设备或模拟器测试屏幕缺口周围的内容显示。
Android 9 引入了多个通知增强功能,可供以 API 级别 28 及以上版本作为目标平台的开发者使用。
附带了照片的 MessagingStyle。
含回复和对话的 MessagingStyle。
提升短信体验
从 Android 7.0(API 级别 24)开始,您可以添加一个操作以回复短信或直接从通知中输入其他文本。 Android 9 通过下列增强提升了该功能:
-
简化了针对对话参与者的支持:
Person
类可用于识别参与对话的人员,包括他们的头像和 URI。 现在,许多其他 API(如addMessage()
)均可利用 [Person
] 类而不是CharSequence
。Person
类也支持构建器设计模式。 -
支持图像:现在,Android 9 可在手机的“短信通知”中显示图像。 您可以使用对短信使用
setData()
来显示图像。 以下代码段演示了如何创建Person
和包含图像的短信。
Kotlin
// Create new Person.
val sender = Person()
.setName(name)
.setUri(uri)
.setIcon(null)
.build()
// Create image message.
val message = Message("Picture", time, sender)
.setData("image/", imageUri)
val style = Notification.MessagingStyle(getUser())
.addMessage("Check this out!", 0, sender)
.addMessage(message)
Java
// Create new Person.
Person sender = new Person()
.setName(name)
.setUri(uri)
.setIcon(null)
.build();
// Create image message.
Message message = new Message("Picture", time, sender)
.setData("image/", imageUri);
Notification.MessagingStyle style = new Notification.MessagingStyle(getUser())
.addMessage("Check this out!", 0, sender)
.addMessage(message);
-
将回复另存为草稿:当用户无意中关闭一个短信通知时,您的应用可以检索系统发送的
EXTRA_REMOTE_INPUT_DRAFT
。 您可以使用此 extra 预填充应用中的文本字段,以便用户可以完成他们的回复。 -
确定对话是否为群组对话。您可以使用
setGroupConversation()
以明确确定对话是否为群组对话。 -
为 Intent 设置语义操作:
setSemanticAction()
函数允许您为操作提供语义含义,如“标记为已读”、“删除”和“回复”等。 -
SmartReply:Android 9 支持在您的短信应用中提供相同的建议回复。 使用
RemoteInput.setChoices()
为用户提供一组标准回复。
渠道设置、广播和请勿打扰
Android 8.0 引入了通知渠道,允许您为要显示的每种通知类型创建可由用户自定义的渠道。 Android 9 通过下列变更简化通知渠道设置:
-
屏蔽渠道组:现在,用户可以针对某个应用在通知设置中屏蔽整个渠道组。 您可以使用
isBlocked()
函数确定何时屏蔽一个渠道组,从而不会向该组中的渠道发送任何通知。此外,您的应用可以使用全新的
getNotificationChannelGroup()
函数查询当前渠道组设置。 -
全新的广播 Intent 类型:现在,当通知渠道和渠道组的屏蔽状态发生变更时,Android 系统将发送广播 Intent。 拥有已屏蔽的渠道或渠道组的应用可以侦听这些 Intent 并做出相应的回应。 有关这些 Intent 操作和 extra 的更多信息,请参阅
NotificationManager
参考中更新的常量列表。 有关响应广播 Intent 的信息,请参阅广播。 -
NotificationManager.Policy
有 3 种新的“请勿打扰”优先级类别:PRIORITY_CATEGORY_ALARMS
优先处理警报。PRIORITY_CATEGORY_MEDIA
优先处理媒体源的声音,如媒体和语音导航。PRIORITY_CATEGORY_SYSTEM
优先处理系统声音。
-
NotificationManager.Policy
还有 7 种新的“请勿打扰”常量,可以用来抑制视觉中断:SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
防止通知启动全屏 Activity。SUPPRESSED_EFFECT_LIGHTS
屏蔽通知灯。SUPPRESSED_EFFECT_PEEK
防止通知短暂进入视图(“滑出”)。SUPPRESSED_EFFECT_STATUS_BAR
防止通知显示在支持状态栏的设备的状态栏中。SUPPRESSED_EFFECT_BADGE
在支持标志的设备上屏蔽标志。 如需了解详细信息,请参阅修改通知标志。SUPPRESSED_EFFECT_AMBIENT
在支持微光显示的设备上屏蔽通知。SUPPRESSED_EFFECT_NOTIFICATION_LIST
防止通知显示在支持列表视图(如通知栏或锁屏)的设备的列表视图中。
多摄像头支持和摄像头更新
在运行 Android 9 的设备上,您可以通过两个或更多物理摄像头来同时访问多个视频流。] 在配备双前置摄像头或双后置摄像头的设备上,您可以创建只配备单摄像头的设备所不可能实现的创新功能,例如无缝缩放、背景虚化和立体成像。 通过该 API,您还可以调用逻辑或融合的摄像头视频流,该视频流可在两个或更多摄像头之间自动切换。
摄像头方面的其他改进还包括附加会话参数和 Surface 共享,前者有助于降低首次拍照期间的延迟,而后者则让摄像头客户端能够处理各种用例,而无需停止并启动摄像头视频流。 我们还针对基于显示屏的 flash 支持和 OIS 时间戳访问新增了一些 API,用以实现应用级的图像稳定化和特效。
在 Android 9 中,多摄像头 API支持单色摄像头,适用于具有 FULL
或 LIMITED
功能的设备。 单色输出通过 YUV_420_888
格式实现,Y 为灰度,U (Cb) 为 128,V (Cr) 为 128。
在受支持的设备上,Android 9 还支持外置 USB/UVC 摄像头。
适用于可绘制对象和位图的 ImageDecoder
Android 9 引入了 ImageDecoder
类,可提供现代化的图像解码方法。 使用该类取代 BitmapFactory
和 BitmapFactory.Options
API。
ImageDecoder
让您可通过字节缓冲区、文件或 URI 来创建 Drawable
或 Bitmap
。 要解码图像,请首先以编码图像的来源为参数,调用 createSource()
。 然后,通过传递 ImageDecoder.Source
对象来调用 decodeDrawable()
或 decodeBitmap()
,从而创建 Drawable
] 或 Bitmap
。 要更改默认设置,请将 OnHeaderDecodedListener
传递给 decodeDrawable()
或 decodeBitmap()
。 ImageDecoder
调用 onHeaderDecoded()
,以图像的默认宽度和高度(若已知)为参数。 如果编码图像是动画 GIF 或 WebP,decodeDrawable()
将返回 Drawable
,它是 AnimatedImageDrawable
类的一个实例。
您可以使用不同的方法来设置图像属性:
- 要将解码的图像缩放到精确尺寸,请将目标尺寸传递给
setTargetSize()
。 您也可以使用样图尺寸来缩放图像。 将样图尺寸直接传递给setTargetSampleSize()
。 - 要在缩放图像的范围内裁剪图像,请调用
setCrop()
。 - 要创建可变位图,请将
true
传递给setMutableRequired()
。
通过 ImageDecoder
还可以为圆角或圆形遮罩之类的图像添加复杂的定制效果。 以 PostProcessor
类的一个实例作为参数使用 setPostProcessor()
,执行您所需的任何绘图命令。
注:对 AnimatedImageDrawable
进行后处理时,效果会出现在动画的所有帧中。
动画
Android 9 引入了 AnimatedImageDrawable
类,用于绘制和显示 GIF 和 WebP 动画图像。 AnimatedImageDrawable
的工作方式与 AnimatedVectorDrawable
的相似之处在于,都是渲染线程驱动 AnimatedImageDrawable
的动画。 渲染线程还使用工作线程进行解码,因此,解码不会干扰渲染线程的其他操作。 这种实现机制允许您的应用在显示动画图像时,无需管理其更新,也不会干扰应用界面线程上的其他事件。
可使用 ImageDecoder
的实例对 AnimatedImageDrawable
进行解码。 以下代码段演示如何使用 ImageDecoder
来解码 AnimatedImageDrawable
:
Kotlin
@Throws(IOException::class)
private fun decodeImage() {
val decodedAnimation = ImageDecoder.decodeDrawable(
ImageDecoder.createSource(resources, R.drawable.my_drawable))
// Prior to start(), the first frame is displayed.
(decodedAnimation as? AnimatedIma