API 级别:21
Android 5.0 (LOLLIPOP) 为用户和应用开发者提供了新的功能。本文档介绍了最值得注意的新 API。
有关新平台功能的扼要介绍,另请参阅 Android Lollipop 集锦。
开始开发
要构建 Android 5.0 版应用,您必须先下载 Android SDK,然后使用 SDK 管理器下载 Android 5.0 SDK 平台和系统映像。
更新您的目标 API 级别
要进一步针对运行 Android 5.0 的设备优化您的应用,请将 targetSdkVersion
设置为 "21"
,在 Android 5.0 系统映像上安装该应用并予以测试,然后将更改后的新版应用发布出去。
您既可以使用 5.0 API,也可以支持旧版本,方法是在代码中构建条件,确保先检查系统 API 级别再执行 minSdkVersion
不支持的 API。要详细了解有关保持向后兼容的信息,请参阅支持不同平台版本。
要详细了解有关各个 API 级别运行方式的信息,请参阅什么是 API 级别?
重要的行为变更
请注意,如果您之前发布了 Android 版应用,那么您的应用可能会受到 Android 5.0 变化的影响。
如果您尚未针对新的 Android 运行时 (ART) 测试您的应用…
第 4.4 版引入了一个全新的实验性功能,即 Android 运行时 (ART)。在第 4.4 版中,ART 是可选的,默认运行时仍为 Dalvik。对于 Android 5.0,默认运行时现在是 ART。
有关 ART 新功能的概述,请参阅 ART 简介。主要包括下面的一些新功能:
- 预先 (AOT) 编译
- 经过改进的垃圾回收 (GC)
- 经过改进的调试支持
大多数 Android 应用应该不用做出任何更改即可直接在 ART 下运行。不过,Dalvik 上运行的部分技术在 ART 上无法运行。要了解最重要的问题,请参阅在 Android 运行时 (ART) 上验证应用行为。请特别注意以下情况:
- 您的应用使用 Java 原生接口 (JNI) 运行 C/C 代码。
- 您使用的开发工具可生成非标准代码(例如某些混淆代码)。
- 您使用的技术与垃圾回收压缩不兼容。(虽然 ART 当前没有实施垃圾回收压缩,但在 Android 开放源代码项目中,垃圾回收压缩正处于开发阶段)。
如果您的应用实施通知…
请确保您的通知能够反映出 Android 5.0 的这些变化。要详细了解如何设计适用于 Android 5.0 及更高版本的通知,请参阅通知设计指南。
Material Design 设计样式
通知是在白色(或颜色非常浅的)背景上绘制的深色文本,以便与新的 Material Design 设计小部件协调一致。请确保所有通知在新的配色方案下都能够正常显示。如果通知无法正常显示,请予以修复:
- 使用
setColor()
在图标图片后面的圆圈中设置一种强调色彩。 - 更新或移除有颜色的资源。系统会忽略操作图标和主通知图标中的所有非 Alpha 通道。您应当假定这些图标仅包含 Alpha 通道。系统会用白色来绘制通知图标,而用深灰色来绘制操作图标。
声音和振动
如果您当前在使用 Ringtone
、MediaPlayer
或 Vibrator
类为通知添加声音和振动,请移除该代码,这样系统才能以优先模式正常呈现通知。若要添加声音和振动,请改用 Notification.Builder
方法。
将设备设置为 RINGER_MODE_SILENT
会导致它进入新的优先模式。如果将设备设置为 RINGER_MODE_NORMAL
或RINGER_MODE_VIBRATE
,则会使其退出优先模式。
以前,Android 将 STREAM_MUSIC
用作主音量流,以此来控制平板电脑设备的音量。在 Android 5.0 中,手机和平板电脑设备的主音量流现已统一,均由 STREAM_RING
或 STREAM_NOTIFICATION
控制。
通知在锁定屏幕上的公开程度
在 Android 5.0 中,通知现在默认显示在用户的锁定屏幕上。用户可以选择不公开敏感信息,这样的话系统会自动修改通知显示文本。要自定义这种经过修改的通知,请使用 setPublicVersion()
。
如果通知不包含个人信息,或者您希望在通知中显示媒体播放控件,请调用 setVisibility()
方法,并将通知的公开程度的级别设置为 VISIBILITY_PUBLIC
。
媒体播放
如果您要实施可呈现媒体播放状态或传输控件的通知,请考虑使用新的 Notification.MediaStyle
模板,而不是自定义RemoteViews.RemoteView
对象。无论您选择使用哪种方法,请务必将通知的公开程度设置为 VISIBILITY_PUBLIC
,以便用户可以在锁定屏幕中使用您的控件。请注意,从 Android 5.0 开始,系统不再在锁定屏幕中显示 RemoteControlClient
对象。有关详情,请参阅如果您的应用使用 RemoteControlClient。
提醒通知
现在,当设备处于活动状态(即设备未锁定且屏幕亮起)时,通知可以显示在小型浮动窗口中(也称为提醒通知)。此类通知采用的显示形式与紧凑型通知采用的形式类似,不同的是提醒通知还会显示操作按钮。用户无需退出当前应用,即可根据提醒通知执行操作或关闭提醒通知。
可以触发提醒通知的情景示例包括:
- 用户在全屏模式下执行操作(应用使用
fullScreenIntent
) - 通知的优先级较高,并且使用铃声或振动
如果您的应用在上述任意一种情景下实施通知,请确保提醒通知能够正常呈现。
如果您的应用使用 RemoteControlClient…
RemoteControlClient
类现已被弃用。请尽快改用全新的 MediaSession
API。
对于 MediaSession
或 RemoteControlClient
,Android 5.0 中的锁定屏幕不会显示传输控件。相反,您的应用可以通过通知在锁定屏幕中提供媒体播放控件。这样,您的应用就能够更好地控制媒体按钮的展现方式,同时还能让用户无论在设备处于锁定还是解锁状态下都可以执行同样的操作。
为此,Android 5.0 引入了一个新的 Notification.MediaStyle
模板。Notification.MediaStyle
将您通过Notification.Builder.addAction()
添加的通知操作转换到在您应用的媒体播放通知中内嵌的紧凑型按钮中。将会话令牌传递到 setSession()
方法,指示系统此通知控制正在进行的媒体会话。
请务必将通知的公开程度设置为 VISIBILITY_PUBLIC
,将通知标为安全通知,以便在任何锁定屏幕(安全屏幕或其他屏幕)上显示。有关详情,请参阅在锁定屏幕上显示通知。
如果您的应用是在 Android TV 或 Wear 平台上运行,请通过实施 MediaSession
类来显示媒体播放控件。如果您的应用需要在 Android 设备上接收媒体按钮事件,您还应当实施 MediaSession
。
如果您的应用使用 getRecentTasks()…
由于 Android 5.0 中引入了并行文档和活动任务这一新功能(请参阅下文中的“最近用过”屏幕中的并行文档和活动),ActivityManager.getRecentTasks()
方法现已被弃用,以更好地保护用户隐私。为了实现向后兼容性,此方法仍会返回它的一小部分数据,包括调用应用自身的任务,同时还可能包括其他一些非敏感任务(例如“首页”)。如果您的应用在使用此方法检索它自身的任务,请改用 getAppTasks()
检索该信息。
如果您使用的是 Android 原生开发工具包 (NDK)…
Android 5.0 支持 64 位系统。64 位增强功能增加了寻址空间并提高了性能,同时仍能全面支持现有的 32 位应用。64 位支持还提高了 OpenSSL 的加密性能。另外,此版本还引入了新的原生媒体 NDK API 以及原生 OpenGL ES (GLES) 3.1 支持。
要利用 Android 5.0 中提供的 64 位支持,请从 Android NDK 页面下载并安装 NDK 10c 版。要详细了解 NDK 的重要变化和错误修复,请参阅 10c 版版本说明。
如果您的应用绑定到某项服务…
Context.bindService()
方法现在要求获取显式 Intent
;如果获取的是隐式 intent,则会引发异常。为了确保您的应用是安全的,请在启动或绑定 Service
时使用显式 intent,并且不要为此服务声明 intent 过滤器。
如果您的应用使用 WebView…
Android 5.0 会更改您应用的默认行为。
- 如果您的应用的目标 API 级别不低于 21:
- 默认情况下,系统会屏蔽混合内容和第三方 Cookie。要让系统不屏蔽混合内容和第三方 Cookie,请分别使用
setMixedContentMode()
和setAcceptThirdPartyCookies()
方法。 - 系统现在可以智能选择要绘制的 HTML 文档部分。这一新的默认行为有助于降低内存占用量并提高性能。如果您要一次性呈现整个文档,请调用
enableSlowWholeDocumentDraw()
停用此优化行为。
- 默认情况下,系统会屏蔽混合内容和第三方 Cookie。要让系统不屏蔽混合内容和第三方 Cookie,请分别使用
- 如果您的应用的目标 API 级别低于 21:系统不会屏蔽混合内容和第三方 Cookie,并且始终会一次性呈现整个文档。
界面
Material Design 设计支持
即将发布的版本新增了对 Android 新 Material Design 设计样式的支持。您可以借助 Material Design 设计样式创建应用,使其呈现动态的视觉效果并为用户提供自然的界面元素过渡效果。此支持包括:
- 素材主题背景
- 视图阴影
RecyclerView
小部件- 可绘制的动画和样式效果
- Material Design 设计动画和活动过渡效果
- 基于视图状态的视图属性动画生成器
- 可自定义的界面小部件和应用栏(含您可以控制的调色板)
- 基于 XML 矢量图形的动画和非动画图形内容
要详细了解如何向您的应用添加 Material Design 设计功能,请参阅 Material Design 设计。
“最近用过”屏幕中的并行文档和活动
在以前的版本中,对于用户最近与之互动的每个应用,“最近用过”屏幕都只能显示一个任务。现在,您的应用可以视需要针对其他并行活动或文档打开多个任务。通过此功能,用户可以在“最近用过”屏幕中快速切换各个活动和文档,并能在所有应用之间获得一致的切换体验,从而实现多任务处理。此类并行任务示例可能包括:网络浏览器应用中打开的标签页、效率类应用中的文档、游戏中的并行对局或信息应用中的聊天。您的应用可以通过 ActivityManager.AppTask
类管理任务。
要插入逻辑中断,以便系统能够将您的活动视为一个新任务,请在通过 startActivity()
启动活动时使用FLAG_ACTIVITY_NEW_DOCUMENT
。您还可以在清单中将 <activity> 元素的 documentLaunchMode
属性设置为 "intoExisting"
或"always"
,从而实现该行为。
为了避免“最近用过”屏幕过于混乱,您可以设置应用能够在该屏幕中显示的任务数上限。为此,请设置 <application> 的android:maxRecents
属性。目前可以指定的上限为,每个用户 50 个任务(对于 RAM 较小的设备,则为每个用户 25 个任务)。
您可以将“最近用过”屏幕中的任务设置为在重新启动过程中保持不变。要控制这一持续行为,请使用android:persistableMode 属性。您也可以通过调用 setTaskDescription()
方法,来更改“最近用过”屏幕中活动的视觉属性,如活动的颜色、标签和图标。
WebView 更新
Android 5.0 将 WebView
实施更新为 Chromium M37,不仅提高了安全性和稳定性,还修复了多项错误。Android 5.0 上运行的 WebView
的默认用户代理字符串已更新为采用 37.0.0.0 作为版本号。
此版本引入了 PermissionRequest
类,该类允许您的应用 getUserMedia() 之类的 Web API 向 WebView
授予对受保护资源(例如摄像头和麦克风)的访问权限。您的应用必须拥有对这些资源的相应 Android 权限,才能向 WebView
授予权限。
借助新的 onShowFileChooser()
方法,您现在不但可以在 WebView
中使用输入表单字段,而且可以启动文件选择器从 Android 设备中选择图片和文件。
另外,此版本还支持 WebAudio、WebGL 和 WebRTC 等开放标准。要详细了解此版本中的新增功能,请参阅Android 版 WebView。
屏幕截图和共享
通过 Android 5.0,您可以使用新的 android.media.projection
API 向您的应用添加屏幕截图和屏幕共享功能。例如,如果您希望在视频会议应用中启用屏幕共享,则会发现此功能非常实用。
通过新的 createVirtualDisplay()
方法,您的应用可以将主屏幕内容(默认显示屏)捕获到 Surface
对象中,然后通过网络发送该对象。该 API 仅允许捕获非安全的屏幕内容,不允许捕获系统音频。要开始屏幕截图,您的应用必须先使用通过createScreenCaptureIntent()
方法获取的 Intent
启动屏幕截图对话框,来请求用户向其授予相应权限。
有关新 API 的使用示例,请参阅示例项目中的 MediaProjectionDemo
类。
通知
锁定屏幕通知
Android 5.0 中的锁定屏幕能够呈现通知。用户可以通过“设置”来选择是否允许在安全的锁定屏幕上显示敏感的通知内容。
您的应用可以控制其通知在安全的锁定屏幕上显示时的具体公开程度。要控制公开程度的级别,请调用 setVisibility()
并指定下列值之一:
VISIBILITY_PRIVATE
:显示基本信息(例如通知图标),但隐藏通知的全部内容。VISIBILITY_PUBLIC
:显示通知的全部内容。VISIBILITY_SECRET
:不显示任何内容,甚至连通知图标也不显示。
如果公开程度级别为 VISIBILITY_PRIVATE
,您还可以提供隐藏了个人详细信息的通知内容修改版本。例如,短信应用的通知可能会显示“您有 3 条新短信”,但隐藏短信内容和发送者。要提供此备用通知,请先使用 Notification.Builder
创建替代通知。当创建不公开的通知对象时,请通过 setPublicVersion()
方法为其附加替代通知。
通知元数据
Android 5.0 使用与您的应用通知关联的元数据更智能地对通知进行排序。要设置元数据,请在构建通知时调用Notification.Builder
中的以下方法:
setCategory()
:告诉系统当设备处于“优先”模式时如何处理您的应用通知(例如,当通知表示来电、即时消息或警报时)。setPriority()
:将通知标记为重要性高于或低于普通通知。如果还带有声音或振动,则优先级字段设置为PRIORITY_MAX
或PRIORITY_HIGH
的通知将出现在一个小的浮动窗口中。addPerson()
:允许您向通知添加一个或多个相关的人员。利用此方法,您的应用可指示系统将来自指定人员的通知归成一组,或者将来自这些人员的通知归类为重要性高于普通通知。
显卡
支持 OpenGL ES 3.1
Android 5.0 针对 OpenGL ES 3.1 添加了 Java 接口和原生支持。OpenGL ES 3.1 中提供的主要新功能包括:
- 对着色器进行计算
- 单独的着色器对象
- 间接绘图命令
- 多样本和模版纹理
- 对着色语言的改进
- 用于高级混合模式和调试的扩展
- 对 OpenGL ES 2.0 和 3.0 的向后兼容性
Android 上 OpenGL ES 3.1 的 Java 接口是通过 GLES31
提供的。当使用 OpenGL ES 3.1 时,请务必在您的清单文件中使用 标记和 android:glEsVersion
属性声明它。例如:
<span class="tag" style="color: rgb(0, 0, 136);"><manifest></span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="tag" style="color: rgb(0, 0, 136);"><uses-feature</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:glEsVersion</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"0x00030001"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);">
...
</span><span class="tag" style="color: rgb(0, 0, 136);"></manifest></span>
有关使用 OpenGL ES 的更多信息,包括如何在运行时检查设备支持的 OpenGL ES 版本,请参阅 OpenGL ES API 指南。
Android 扩展程序包
除了 OpenGL ES 3.1 之外,本版本还提供了一个扩展程序包,该程序包具有适用于高级显卡功能的 Java 接口和原生支持。Android 将这些扩展程序视为一个程序包。(如果存在 ANDROID_extension_pack_es31a
扩展程序,则您的应用可以假定该程序包中的所有扩展都存在,并可通过单个 #extension
语句启用着色语言功能。)
该扩展程序包支持:
- 对着色器存储缓冲区、图片和原子的有保证片段着色器支持(片段着色器支持在 OpenGL ES 3.1 中是可选的。)
- 曲面细分和几何着色器
- ASTC (LDR) 纹理压缩格式
- 按样本插值和着色
- 为帧缓冲区中的每个颜色附件使用不同的混合模式
该扩展程序包的 Java 接口是通过 GLES31Ext
提供的。在您的应用清单中,您可以声明您的应用必须仅安装在支持该扩展程序包的设备上。例如:
<span class="tag" style="color: rgb(0, 0, 136);"><manifest></span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="tag" style="color: rgb(0, 0, 136);"><uses-feature</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:name</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">“android.hardware.opengles.aep”</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="atn" style="color: rgb(136, 34, 136);">android:required</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"true"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);">
...
</span><span class="tag" style="color: rgb(0, 0, 136);"></manifest></span>
媒体
用于高级摄像头功能的摄像头 API
Android 5.0 引入了新的 android.hardware.camera2 API 来帮助执行精细的照片拍摄和图片处理。您现在可以通过getCameraIdList()
以编程方式访问可供系统使用的摄像头设备,并通过 openCamera()
连接到特定设备。要开始拍摄图片,请创建一个 CameraCaptureSession
并指定 Surface
对象来发送所拍摄的图片。您可以将 CameraCaptureSession
配置为单拍或连拍。
要想在拍摄了新图片时收到通知,请实施 CameraCaptureSession.CaptureCallback
监听器并将其设置在您的拍摄请求中。现在,当系统完成图片拍摄请求时,您的 CameraCaptureSession.CaptureCallback
监听器将收到对 onCaptureCompleted()
的调用,在 CaptureResult
中向您提供图片拍摄元数据。
CameraCharacteristics
类允许您的应用检测设备上有哪些摄像头功能可用。对象的 INFO_SUPPORTED_HARDWARE_LEVEL
属性表示摄像头的功能级别。
- 所有设备都至少支持
INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
硬件级别,该级别的功能大致等同于已弃用的Camera
API 的功能。 - 支持
INFO_SUPPORTED_HARDWARE_LEVEL_FULL
硬件级别的设备不仅能让用户手动控制拍摄和后期处理,而且能够以高帧速率拍摄高分辨率图片。
要了解如何使用更新后的摄像头 API,请参考本版本中的 Camera2Basic
和 Camera2Video
实施样本。
音频播放
此版本对 AudioTrack
进行了以下更改:
- 您的应用现在能够以浮点格式 (
ENCODING_PCM_FLOAT
) 提供音频数据。这允许更大的动态范围、更一致的精度以及更大的动态余量。浮点算法在中间计算期间尤其有用。播放端点为音频数据使用整数格式,并且具有较低的位深度。(在 Android 5.0 中,内部管线的某些部分尚未采用浮点格式。) - 您的应用现在可以将音频数据提供为
ByteBuffer
,所用格式与MediaCodec
提供的格式相同。 WRITE_NON_BLOCKING
选项可以简化某些应用的缓冲和多线程处理。
媒体播放控件
使用新的通知和媒体 API,可确保系统界面能够了解您的媒体播放并提取和显示专辑封面。而借助新的 MediaSession
和MediaController
类,您现在则可更轻松地跨界面和服务控制媒体播放。
新的 MediaSession
类替代了被弃用的 RemoteControlClient
类,并且提供了一组用于处理传输控件和媒体按钮的回调方法。如果您的应用提供媒体播放并且在 Android TV 或 Wear 平台上运行,请使用 MediaSession
类和相同的回调方法来处理您的传输控件。
您现在可以通过新的 MediaController
类构建您自己的媒体控制器应用。此类提供了一种线程安全方法,可让您通过自己的应用界面流程来监控媒体播放。在创建控制器时,请指定一个 MediaSession.Token
对象,以便您的应用可以与给定的MediaSession
进行互动。通过使用 MediaController.TransportControls
方法,您可以发送诸如 play()
、stop()
、skipToNext()
和 setRating()
之类的命令来控制该会话中的媒体播放。创建好控制器之后,您还可以注册一个 MediaController.Callback
对象来监听该会话中的元数据和状态更改。
此外,您还可以通过新的 Notification.MediaStyle
类创建允许将播放控件关联到媒体会话的丰富通知。
媒体浏览
Android 5.0 通过新的 android.media.browse API 引入了允许应用浏览其他应用的媒体内容库的功能。要公开您的应用中的媒体内容,请扩展 MediaBrowserService
类。您的 MediaBrowserService
实施应当提供对 MediaSession.Token
的访问权限,以便应用可以播放通过您的服务提供的媒体内容。
要与媒体浏览器服务进行互动,请使用 MediaBrowser
类。在创建 MediaBrowser
实例时,请为 MediaSession
指定组件名称。然后,您的应用可以使用该浏览器实例连接到关联的服务,并获取 MediaSession.Token
对象来播放通过该服务公开的内容。
存储
目录选择
Android 5.0 对存储访问框架进行了扩展,允许用户选择整个目录子树,并向应用授予对其中包含的所有文档的读/写访问权限(无需请求用户逐项确认)。
要选择目录子树,请构建并发送 OPEN_DOCUMENT_TREE
intent。系统将显示支持子树选择的所有 DocumentsProvider
实例,允许用户进行浏览并选择目录。返回的 URI 表示对所选子树的访问权限。然后,您可以使用 buildChildDocumentsUriUsingTree()
和 buildDocumentUriUsingTree()
以及 query()
来深入了解此子树。
新的 createDocument()
方法允许您在子树下的任何位置创建新的文档或目录。要管理现有文档,请使用 renameDocument()
和deleteDocument()
。在发出这些调用之前,请检查 COLUMN_FLAGS
以验证服务提供方是否支持这些调用。
如果您在实施 DocumentsProvider
并希望支持子树选择,请实施 isChildDocument()
并在您的 COLUMN_FLAGS
中添加FLAG_SUPPORTS_IS_CHILD
。
Android 5.0 还在共享的存储空间内引入了程序包专用的新目录,您的应用可将要添加到 MediaStore
中的媒体文件放置在这些目录中。新的 getExternalMediaDirs()
将返回这些目录在所有共享的存储设备上的路径。与 getExternalFilesDir()
类似,您的应用不需要额外的权限即可访问所返回的路径。平台将定期扫描这些目录中的新媒体,但您也可使用MediaScannerConnection
对新内容进行显式扫描。
无线和连接
多个网络连接
Android 5.0 提供了新的多网络 API,它们允许您的应用动态扫描具有特定功能的可用网络,然后与这些网络建立连接。如果您的应用需要一个专用网络(例如 SUPL、MMS 或运营商计费的网络),或者如果您希望使用某种特定类型的传输协议来发送数据,则此功能非常有用。
要从您的应用动态选择并连接到某个网络,请执行以下步骤:
- 创建一个
ConnectivityManager
。 - 使用
NetworkRequest.Builder
类创建一个NetworkRequest
对象并指定您的应用感兴趣的网络功能和传输类型。 - 要扫描合适的网络,请调用
requestNetwork()
或registerNetworkCallback()
,并传入NetworkRequest
对象和一个ConnectivityManager.NetworkCallback
实施。如果希望在检测到合适的网络后主动切换到该网络,请使用requestNetwork()
方法;如果希望仅接收网络扫描结果通知而不主动切换,请使用registerNetworkCallback()
方法。
当系统检测到合适的网络时,它将连接到该网络并调用 onAvailable()
回调。您可以在回调中使用 Network
对象来获取关于该网络的更多信息,或者指示通信使用选定的网络。
低功耗蓝牙
Android 4.3 中作为重头戏引入了对低功耗蓝牙(“低功耗蓝牙”)的平台支持。在 Android 5.0 中,Android 设备现在可以用作低功耗蓝牙外围设备。应用可以使用此功能使附近的设备知道它的存在。例如,您可以构建相应的应用来允许设备用作计步器或健康检测器并与另一低功耗蓝牙设备交换其数据。
新的 android.bluetooth.le
API 允许您的应用对公告进行广播,扫描响应,以及与附近的低功能蓝牙设备建立连接。要使用新的公告和扫描功能,请在您的清单中添加 BLUETOOTH_ADMIN
权限。当用户从 Play 商店更新或下载您的应用时,会要求他们向您的应用授予以下权限:“蓝牙连接信息:允许应用控制蓝牙,包括向附近的蓝牙设备进行广播以及获取关于这些设备的信息。”
要开始低功耗蓝牙公告以便其他设备可以发现您的应用,请调用 startAdvertising()
并传入 AdvertiseCallback
类的一个实施。回调对象将收到关于公告操作成功或失败的报告。
Android 5.0 引入了 ScanFilter
类,以便您的应用可以仅扫描它感兴趣的特定类型的设备。要开始扫描低功耗蓝牙设备,请调用 startScan()
并传入一个过滤器列表。在该方法调用中,您还必须提供 ScanCallback
的一个实施以便在发现低功耗蓝牙公告时进行报告。
NFC 增强功能
Android 5.0 添加了以下增强功能以实现更广泛和更灵活的 NFC 使用:
- “分享”菜单中现在提供了 Android Beam。
- 您的应用可以通过调用
invokeBeam()
在用户的设备上调用 Android Beam 来分享数据。这不需要用户对着另一个具有 NFC 功能的设备手动点按设备即可完成数据传输。 - 您可以使用新的
createTextRecord()
方法来创建包含 UTF-8 文本数据的 NDEF 记录。 - 如果您在开发支付应用,则您现在能够通过调用
registerAidsForService()
动态注册 NFC 应用 ID (AID)。您还可以使用setPreferredService()
设置当某个特定的活动处于前台时应当使用的首选卡仿真服务。
Project Volta
除了新功能之前,Android 5.0 还重点对电池寿命进行了改进。可以使用新的 API 和工具来了解并优化您的应用的功耗。
调度作业
Android 5.0 提供了一个新的 JobScheduler
API,它允许您通过为系统定义要在以后的某个时间或在指定的条件下(例如,当设备在充电时)异步运行的作业来优化电池寿命。作业调度在下列情况下非常有用:
- 应用具有您可以推迟的非面向用户的工作。
- 应用具有当插入设备时您希望优先执行的工作。
- 应用具有需要访问网络或 Wi-Fi 连接的任务。
- 应用具有您希望作为一个批次定期运行的许多任务。
工作单元由一个 JobInfo
对象进行封装。此对象指定了调度条件。
使用 JobInfo.Builder
类配置调度的任务应当如何运行。您可以将任务调度为在特定的条件下运行,例如:
- 当设备充电时启动
- 当设备连接到不限流量网络时启动
- 当设备空闲时启动
- 在特定的截止期限之前或以最小的延迟完成
例如,您可以添加如下代码以在不限流量网络上运行您的任务:
代码语言:javascript复制<span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pln" style="color: rgb(0, 0, 0);"> uploadTask </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">Builder</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mJobId</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
mServiceComponent </span><span class="com">/* JobService component */</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">setRequiredNetworkCapabilities</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">NetworkType</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">UNMETERED</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">build</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="typ" style="color: rgb(102, 0, 102);">JobScheduler</span><span class="pln" style="color: rgb(0, 0, 0);"> jobScheduler </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">JobScheduler</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">getSystemService</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">Context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">JOB_SCHEDULER_SERVICE</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
jobScheduler</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">schedule</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">uploadTask</span><span class="pun" style="color: rgb(102, 102, 0);">);</span>
如果设备具有稳定的电源(也就是说,它已插入了 2 分钟以上并且电池处于健康水平),则系统将运行任何已就绪可运行的已调度作业,即使作业的截止期限尚未到期也是如此。
要查看有关如何使用 JobScheduler
API 的示例,请参考本版本中的 JobSchedulerSample
实施样本。
用于查询耗电量信息的开发者工具
新的 dumpsys batterystats
命令将生成关于设备上耗电量信息的有趣统计数据,该数据按唯一用户 ID (UID) 进行组织。该统计信息包括:
- 与电池相关的事件的历史记录
- 设备的全局统计信息
- 每个 UID 和系统组件的大致用电量
- 每个数据包的每个手机应用毫秒数
- 系统 UID 汇总统计信息
- 应用 UID 汇总统计信息
可使用 --help
选项了解用于对输出进行自定义的各种选项。例如,要输出自设备上次充电后给定应用包的耗电量统计信息,请运行以下命令:
<span class="pln" style="color: rgb(0, 0, 0);">$ adb shell dumpsys batterystats </span><span class="pun" style="color: rgb(102, 102, 0);">--</span><span class="pln" style="color: rgb(0, 0, 0);">charged </span><span class="pun" style="color: rgb(102, 102, 0);"><</span><span class="kwd" style="color: rgb(0, 0, 136);">package</span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">></span>
您可以对 dumpsys
命令的输出使用 Battery Historian 工具从日志中生成与电量相关的事件的 HTML 可视形式。此信息使您可以更轻松地了解和诊断任何与电池相关的问题。
办公场所和教育环境中的 Android
托管配置
Android 5.0 提供了用于在企业环境内运行应用的新功能。如果用户具有现有的个人帐户,则设备管理员可以启动托管配置流程来向设备添加一个共存但单独的“托管配置文件”。与托管配置文件关联的应用将与非托管应用一起出现在用户的启动器、“最近用过”屏幕以及通知中。
要启动托管配置流程,请在 Intent
中发送 ACTION_PROVISION_MANAGED_PROFILE
。如果调用成功,则系统将触发onProfileProvisioningComplete()
回调。然后,您可以调用 setProfileEnabled()
来启用此托管配置文件。
默认情况下,在托管配置文件中只会启用一小部分应用。您可以通过调用 enableSystemApp()
在托管配置文件中安装额外的应用。
如果您在开发启动器应用,则可以使用新的 LauncherApps
类来获取当前用户的可启动活动的列表以及任何关联的托管配置文件。您的启动器可以通过向图标绘图添加一个工作标记,使托管应用更加惹人注目。要检索带标记的图标,请调用getUserBadgedIcon()
。
要查看如何使用此新功能,请参考本版本中的 BasicManagedProfile
实施样本。
设备所有者
Android 5.0 引入了部署设备所有者应用的功能。“设备所有者”是一类特殊的设备管理员,具有在设备上创建和移除辅助用户以及配置全局设置的额外能力。您的设备所有者应用可以使用 DevicePolicyManager
类中的方法来对托管设备上的配置、安全性和应用进行精细控制。一个设备在任一时刻只能有一个处于活动状态的设备所有者。
要部署并激活设备所有者,您必须在设备处于未配置状态时执行从编程应用到设备的 NFC 数据传输。此数据传输发送的信息与托管配置中描述的配置 intent 中的信息相同。
屏幕固定
Android 5.0 引入了一个新的屏幕固定 API,它允许您暂时防止用户离开您的任务或被通知打扰。例如,如果您在开发一个教育应用以在 Android 或单用途或资讯服务应用上支持高风险评估需求,则可以使用此功能。一旦您的应用激活了屏幕固定,则用户将无法看到通知、访问其他应用或者返回到主屏幕,直到您的应用退出该模式。
有两种方法用来激活屏幕固定:
- 手动:用户可以在“设置”>“安全性”>“屏幕固定”中启用屏幕固定,并通过在“最近用过”屏幕上点触屏幕固定图标来选择他们要固定的任务。
- 以编程方式:要以编程方式激活屏幕固定,请在您的应用中调用
startLockTask()
。如果请求方应用不是设备所有者,则会提示用户确认。设备所有者应用可以调用setLockTaskPackages()
方法来使应用成为可固定的,不需要经历用户确认步骤。
当任务锁定处于活动状态时,会发生以下行为:
- 状态栏为空,并且用户通知和状态信息被隐藏。
- 首页和“最近的应用”按钮被隐藏。
- 其他应用无法启动新活动。
- 当前应用可以启动新活动,只要这样做不会创建新任务即可。
- 当屏幕固定是由设备所有者调用的时,用户将保持锁定到您的应用,直到该应用调用
stopLockTask()
。 - 如果屏幕固定是由设备所有者之外另一应用或者是由用户直接调用的活动时,用户可以通过同时按住“返回”和“最近”按钮退出。
打印框架
使用位图来呈现 PDF 文件
您现在可以使用新的 PdfRenderer
类将 PDF 文档页呈现为位图图片以便打印。您必须指定系统将可打印内容写入其中的一个可查找的(也就是说,可以随机访问内容)ParcelFileDescriptor
。您的应用可以通过 openPage()
获取页面进行呈现,然后调用 render()
将已打开的 PdfRenderer.Page
转变为位图。如果您只希望将文档的一部分转变为位图图片(例如,要实施平铺渲染以放大文档),则还可以设置其他参数。
有关如何使用新 API 的示例,请参阅 PdfRendererBasic
样本。
系统
应用使用情况统计信息
您现在可以通过新的 android.app.usage
API 访问 Android 设备上的应用使用情况历史记录。此 API 提供了比被弃用的getRecentTasks()
方法更详细的使用情况信息。要使用此 API,必须先在您的清单中声明"android.permission.PACKAGE_USAGE_STATS"
权限。用户还必须通过“设置”>“安全性”>“应用”使用“使用情况访问”启用对此应用的访问权限。
系统将以每个应用为单位收集使用情况数据,并按每天、每周、每月和每年时间间隔对数据进行汇总。系统保留此数据的最大持续时间如下所述:
- 每天数据:7 天
- 每周数据:4 周
- 每月数据:6 个月
- 每年数据:2 年
对于每个应用,系统将记录以下数据:
- 上次使用应用的时间
- 应用在该时间间隔内(按天、周、月或年)处于前台的总时间长度
- 组件(由程序包和活动名称予以标识)在一天中移动到前台或后台时的时间戳捕获
- 设备配置更改时(例如当设备配置因为旋转而更改时)的时间戳捕获
测试和辅助功
测试和辅助功能改进
Android 5.0 对测试和辅助功能增加了以下支持:
- 新的
getWindowAnimationFrameStats()
和getWindowContentFrameStats()
方法将捕获窗口动画和内容的帧统计信息。这些方法允许您编写仪器测试来评估某个应用是否在以足够的刷新频率来呈现帧以提供流畅的用户体验。 - 新的
executeShellCommand()
方法允许您通过仪器测试执行 shell 命令。命令执行类似于从连接到设备的主机运行adb shell
,允许您使用基于 shell 的工具,例如dumpsys
、am
content
和pm
。 - 使用辅助功能 API(例如
UiAutomator
)的辅助服务和测试工具现在可以检索有视力的用户可以与之进行互动的屏幕上窗口的属性的详细信息。要检索AccessibilityWindowInfo
对象的列表,请调用新的getWindows()
方法。 - 新的
AccessibilityNodeInfo.AccessibilityAction
类允许您定义可以对AccessibilityNodeInfo
执行的标准或自定义操作。新的AccessibilityNodeInfo.AccessibilityAction
类替换了以前在AccessibilityNodeInfo
中提供的与操作相关的 API。 - Android 5.0 对您的应用中的文本到语音合成提供了更细粒度的控制。新的
Voice
类允许您的应用使用与特定区域设置、质量和延迟评级以及特定于文本到语音引擎的参数关联的语音配置文件。
IME
更轻松地在输入语言之间切换
从 Android 5.0 开始,用户可以更轻松地在该平台支持的所有输入法编辑器 (IME) 之间进行切换。执行指定的切换操作(通常是触摸软键盘上的一个地球图标)将循环经过所有此类 IME。此行为更改是由 shouldOfferSwitchingToNextInputMethod()
方法实施的。
此外,框架现在还将检查下一个 IME 究竟是否包括切换机制(并因此检查该 IME 是否支持切换到它之后的 IME)。具有切换机制的 IME 不会切换到没有切换机制的 IME。此行为更改是由 switchToNextInputMethod()
方法实施的。
要查看有关如何使用更新的 IME 切换 API 的示例,请参考本版本中更新的软键盘实施样本。要详细了解如何实施 IME 切换,请参阅创建输入法。
清单声明
声明必需的功能
元素中现在支持下列值,因此,您可以确保您的应用仅安装在提供了您的应用所需功能的设备上。
FEATURE_AUDIO_OUTPUT
FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING
FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR
FEATURE_CAMERA_CAPABILITY_RAW
FEATURE_CAMERA_LEVEL_FULL
FEATURE_GAMEPAD
FEATURE_LIVE_TV
FEATURE_MANAGED_USERS
FEATURE_LEANBACK
FEATURE_OPENGLES_EXTENSION_PACK
FEATURE_SECURELY_REMOVES_USERS
FEATURE_SENSOR_AMBIENT_TEMPERATURE
FEATURE_SENSOR_HEART_RATE_ECG
FEATURE_SENSOR_RELATIVE_HUMIDITY
FEATURE_VERIFIED_BOOT
FEATURE_WEBVIEW
用户权限
元素中现在支持以下权限来声明您的应用访问特定 API 时所需的权限。
BIND_DREAM_SERVICE
:当针对 API 级别 21 和更高级别时,Daydream 服务需要此权限来确保只有系统可以绑定到它