Android 4.0 API

API 级别14

Android 4.0 (ICE_CREAM_SANDWICH) 是一个主要平台版本,为用户和应用开发者添加了各种新功能。除了下面讨论的所有新功能和 API 之外,Android 4.0 是一个重要的平台版本,因为它将大量 API 和全息主题从 Android 3.x 引入到小屏幕上。作为应用开发者,您现在拥有单一平台和统一的 API 框架,可让您使用单个 APK 开发和发布应用,从而在运行相同版本的 Android(Android 4.0(API 级别 14)或更高版本)时为手机、平板电脑等提供优化的用户体验。

对于开发者而言,Android 4.0 平台可作为 Android SDK 的可下载组件提供。可下载平台包含 Android 库、系统映像,以及一组模拟器皮肤等。如需开始针对 Android 4.0 进行开发或测试,请使用 Android SDK 管理器将该平台下载到您的 SDK 中。

API 概览

下文对 Android 4.0 中的新 API 进行了技术概览。

联系人提供程序中的社交 API

ContactsContract 提供程序定义的联系人 API 已经过扩展,以支持新的面向社交的功能,例如设备所有者的个人资料以及允许用户邀请个人联系人加入设备上安装的社交网络的功能。

用户个人资料

Android 现在包含代表设备所有者(如 ContactsContract.Profile 表所定义)的个人资料。维护用户身份的社交应用可以通过在 ContactsContract.Profile 中创建新的 ContactsContract.RawContacts 条目来提供用户个人资料数据。也就是说,代表设备用户的原始联系人不属于由 ContactsContract.RawContacts URI 定义的传统原始联系人表;相反,您必须在表中的 CONTENT_RAW_CONTACTS_URI 中添加个人资料原始联系人。然后,这个表中的原始联系人会汇总到名为“我”的单个用户可见个人资料中。

为个人资料添加新的原始联系人需要 android.Manifest.permission#WRITE_PROFILE 权限。同样,如需从配置文件表中读取数据,您必须请求 android.Manifest.permission#READ_PROFILE 权限。不过,大多数应用都不需要读取用户个人资料,即使在向个人资料贡献数据时也是如此。读取用户个人资料是一项敏感权限,因此用户应该对请求该权限的应用持怀疑态度。

邀请意图

INVITE_CONTACT intent 操作允许应用调用一项操作,指明用户想要将联系人添加到社交网络。接收应用的应用使用它来邀请指定联系人加入该社交网络。大多数应用将位于此操作的接收端。例如,当用户为联系人详细信息中列出的特定社交应用选择“添加连接”时,内置的“联系人”应用会调用邀请 intent。

为了让您的应用在“添加连接”列表中可见,您的应用必须提供一个同步适配器,用于同步您社交网络中的联系人信息。然后,您必须向应用的同步配置文件添加 inviteContactActivity 属性,并使用系统在发送邀请 intent 时启动的 activity 的完全限定名称,向系统表明您的应用会响应 INVITE_CONTACT intent。然后,启动的 activity 可以从 intent 的数据中检索相关联系人的 URI,并执行必要的工作,以邀请该联系人加入网络或将此人添加到用户的连接。

大照片

Android 现在支持为联系人提供高分辨率照片。现在,当您将照片推送到联系人记录中时,系统会将照片同时处理为 96x96 缩略图(和之前一样)和存储在新文件式照片存储区中的 256x256“显示照片”(系统选择的确切尺寸将来可能会发生变化)。您可以向联系人添加大照片,方法是将大照片放入数据行的常规 PHOTO 列中,然后系统会将其处理为相应的缩略图并显示照片记录。

联系人使用情况反馈

新的 ContactsContract.DataUsageFeedback API 可帮助您跟踪用户使用特定方法联系用户的频率,例如用户使用每个电话号码或电子邮件地址的频率。此信息有助于提高与每个人相关的每种联系方式的排名,并提供更好的关于联系每个人的建议。

日历提供程序

借助新的日历 API,您可以读取、添加、修改和删除存储在日历提供程序中的日历、活动、参加者、提醒和提醒。

各类应用和微件可以使用这些 API 来读取和修改日历活动。然而,一些最引人注目的用例是同步适配器,它可将用户的日历与其他日历服务同步,从而为用户的所有活动提供统一的位置。例如,Google 日历活动会通过 Google 日历同步适配器与日历提供程序同步,以便通过 Android 的内置日历应用查看这些活动。

日历提供程序中日历和事件相关信息的数据模型由 CalendarContract 定义。用户的所有日历数据存储在 CalendarContract 的各种子类所定义的多个表中:

  • CalendarContract.Calendars 表包含日历特定信息。此表中的每一行都包含一个日历的详细信息,例如名称、颜色、同步信息等。
  • CalendarContract.Events 表包含特定于事件的信息。此表中的每一行都包含单个活动的信息,例如活动标题、地点、开始时间、结束时间等。事件可以发生一次,也可以多次重复。参加者、提醒和扩展属性存储在单独的表中,并使用活动的 _ID 将其与活动相关联。
  • CalendarContract.Instances 表包含事件发生的开始时间和结束时间。此表中的每一行都表示一次出现。对于一次性事件,实例与事件是一对一的映射关系。对于周期性事件,系统会自动生成多个行,以对应于该事件的多次发生。
  • CalendarContract.Attendees 表包含事件参加者或邀请对象信息。每一行代表事件的一位邀请对象。它指定了邀请对象的类型以及对活动的响应。
  • CalendarContract.Reminders 表包含提醒/通知数据。每一行代表事件的一个提醒。一个活动可以有多个提醒。每个活动的提醒数量在 MAX_REMINDERS 中指定,由拥有给定日历的同步适配器设置。提醒以事件安排前的分钟数形式指定,用于指定闹钟方法,例如使用提醒、电子邮件或短信提醒用户。
  • CalendarContract.ExtendedProperties 表存储同步适配器使用的不透明数据字段。提供方不会对此表中的内容采取任何操作,除非是在相关事件被删除时将其删除。

如需使用日历提供程序访问用户的日历数据,您的应用必须请求 READ_CALENDAR 权限(读取权限)和 WRITE_CALENDAR(写入权限)。

事件意图

如果您只想在用户的日历中添加事件,则可以将 ACTION_INSERT intent 与 Events.CONTENT_URI 定义的数据结合使用,以便在日历应用中启动一个可创建新事件的 activity。使用 intent 不需要任何权限,并且您可以使用以下 extra 指定事件详细信息:

语音信箱提供商

新的语音信箱提供程序允许应用向设备添加语音信息,从而通过单个可视化演示文稿呈现用户的所有语音信息。例如,用户可能会有多个语音信箱来源,例如一个来自电话服务提供商,另一个来自 VoIP 或其他替代语音服务。这些应用可以使用 Voicemail Provider API 将其语音信息添加到设备中。然后,内置的“电话”应用会以统一的演示方式向用户显示所有语音信息。虽然系统的“电话”应用是唯一可以读取所有语音信息的应用,但每个提供语音信息的应用都可以读取它已添加到系统中的语音信息(但不能读取其他服务中的语音信息)。

由于这些 API 目前不允许第三方应用读取系统中的所有语音信息,因此只有那些有语音信息要发送给用户的第三方应用才应使用语音信箱 API。

VoicemailContract 类定义语音信箱 Provder 的内容提供程序。子类 VoicemailContract.VoicemailsVoicemailContract.Status 提供了多个表,应用可在其中插入语音信息数据以在设备上存储。如需查看语音信箱提供程序应用的示例,请参阅语音信息提供程序演示

多媒体

Android 4.0 为与照片、视频和音乐等媒体交互的应用添加了几个新的 API。

媒体效果

借助新的媒体效果框架,您可以对图片和视频应用各种视觉效果。例如,借助图片效果,您可以轻松修正红眼、将图片转换为灰度模式、调整亮度、调整饱和度、旋转图片、应用鱼眼效果等。系统会在 GPU 上执行所有效果处理,以获得最佳性能。

为实现最佳性能,效果会直接应用于 OpenGL 纹理,因此您的应用必须具有有效的 OpenGL 上下文,才能使用这些效果 API。应用效果的纹理可能来自位图、视频甚至相机。不过,纹理必须满足以下特定限制:

  1. 它们必须绑定到一个 GL_TEXTURE_2D 纹理图片
  2. 它们必须包含至少一个 mipmap 级别

Effect 对象定义了一种可应用于图片帧的媒体效果。创建 Effect 的基本工作流如下:

  1. 从 OpenGL ES 2.0 上下文中调用 EffectContext.createWithCurrentGlContext()
  2. 使用返回的 EffectContext 调用 EffectContext.getFactory(),后者会返回 EffectFactory 的实例。
  3. 调用 createEffect(),并向其传递来自 @link android.media.effect.EffectFactory} 的效果名称,例如 EFFECT_FISHEYEEFFECT_VIGNETTE

您可以通过调用 setParameter() 并传递参数名称和参数值来调整效果的参数。每种效果类型都接受不同的参数,这些参数会随效果名称一起记录。例如,EFFECT_FISHEYE 有一个用于失真 scale 的参数。

如需对纹理应用效果,请对 Effect 调用 apply() 并传入输入纹理、其宽度和高度以及输出纹理。输入纹理必须绑定到 GL_TEXTURE_2D 纹理图片(通常通过调用 glTexImage2D() 函数完成)。您可以提供多个 mipmap 级别。如果输出纹理尚未绑定到纹理图片,则效果会自动将其绑定为 GL_TEXTURE_2D 且具有一个 mipmap 级别 (0),该级别的大小与输入相同。

我们保证支持 EffectFactory 中列出的所有效果。不过,并非所有设备都支持外部库提供的一些额外效果,因此您必须先通过调用 isEffectSupported() 检查是否支持来自外部库的所需效果。

遥控器客户端

新的 RemoteControlClient 允许媒体播放器从远程控制客户端(例如设备锁定屏幕)启用播放控件。媒体播放器还可以显示与当前播放的媒体有关的信息,以显示在遥控器上,例如曲目信息和专辑封面。

如需为您的媒体播放器启用远程控制客户端,请使用其构造函数实例化 RemoteControlClient,并向其传递用于广播 ACTION_MEDIA_BUTTONPendingIntent。intent 还必须在应用中声明用于处理 ACTION_MEDIA_BUTTON 事件的显式 BroadcastReceiver 组件。

如需声明您的播放器可以处理的媒体控件输入,您必须对 RemoteControlClient 调用 setTransportControlFlags(),并传递一组 FLAG_KEY_MEDIA_* 标志,例如 FLAG_KEY_MEDIA_PREVIOUSFLAG_KEY_MEDIA_NEXT

然后,您必须通过将 RemoteControlClient 传递给 MediaManager.registerRemoteControlClient() 来注册它。注册后,您在实例化 RemoteControlClient 时声明的广播接收器将在遥控器上按下按钮时收到 ACTION_MEDIA_BUTTON 事件。您收到的 intent 包含按下媒体键的 KeyEvent,您可以使用 getParcelableExtra(Intent.EXTRA_KEY_EVENT) 从 intent 中检索该 intent。

如需在遥控器上显示有关媒体播放的信息,请调用 editMetaData() 并将元数据添加到返回的 RemoteControlClient.MetadataEditor 中。您可以为媒体图片、数字信息(如已播放时间)以及文本信息(如曲目标题)提供位图。如需了解可用键,请参阅 MediaMetadataRetriever 中的 METADATA_KEY_* 标志。

如需查看示例实现,请参阅随机音乐播放器。该播放器提供的兼容性逻辑使得它能够在 Android 4.0 设备上启用遥控器客户端,同时继续支持搭载 Android 2.1 的设备。

媒体播放器

  • 现在需要 INTERNET 权限,才能通过 MediaPlayer 在线播放在线媒体。如果您使用 MediaPlayer 播放来自互联网的内容,请务必向清单中添加 INTERNET 权限,否则从 Android 4.0 开始,媒体播放将无法正常运行。
  • setSurface() 允许您定义一个 Surface,使其充当视频接收器。
  • setDataSource() 允许您随请求发送其他 HTTP 标头,这对于 HTTP(S) 实时流式传输非常有用
  • HTTP(S) 直播现在会跨请求遵循 HTTP Cookie

媒体类型

Android 4.0 增加了对以下内容的支持:

  • HTTP/HTTPS 实时流式传输协议版本 3
  • ADTS 原始 AAC 音频编码
  • WEBP 图片
  • Matroska 视频

如需了解详情,请参阅支持的媒体格式

相机

Camera 类现在包含用于检测人脸以及控制对焦和测光区域的 API。

人脸检测

相机应用现在可以使用 Android 的人脸检测 API 来增强其功能,这些 API 不仅可以检测拍摄对象的面部,还可以检测特定的面部特征,例如眼睛和嘴巴。

如需在相机应用中检测人脸,您必须通过调用 setFaceDetectionListener() 来注册 Camera.FaceDetectionListener。然后,您可以启动相机 Surface 并通过调用 startFaceDetection() 开始检测人脸。

当系统在相机场景中检测到一个或多个人脸时,它会在您的 Camera.FaceDetectionListener 实现(包括 Camera.Face 对象数组)中调用 onFaceDetection() 回调。

Camera.Face 类的实例提供有关检测到的人脸的各种信息,包括:

  • 一个 Rect,用于指定人脸相对于镜头当前视野的边界
  • 一个介于 1 到 100 之间的整数,表示系统对于相应对象是人脸的置信度
  • 具有唯一 ID,便于您跟踪多个面孔
  • 指示眼睛和嘴巴所在位置的多个 Point 对象

注意:某些设备可能不支持人脸检测,因此您应通过调用 getMaxNumDetectedFaces() 进行检查,并确保返回值大于零。此外,某些设备可能不支持识别眼睛和嘴巴,在这种情况下,Camera.Face 对象中的这些字段将为 null。

对焦和测光区域

相机应用现在可以控制相机用于对焦以及测光白平衡和自动曝光的区域。这两项功能都使用新的 Camera.Area 类来指定镜头当前视图中的应对焦或按流量计费的区域。Camera.Area 类的实例使用 Rect 和区域的权重来定义区域的边界,该区域表示该区域相对于所考虑的其他区域的重要性级别(使用整数)。

在设置对焦区域或测光区域之前,您应先分别调用 getMaxNumFocusAreas()getMaxNumMeteringAreas()。如果这些信号返回 0,则表示设备不支持相应的功能。

如需指定要使用的对焦或测光区域,只需调用 setFocusAreas()setMeteringAreas() 即可。每个对象都接受 Camera.Area 对象的 List,这些对象指示要考虑对焦或测光的区域。例如,您可以实现一项功能,使用户能够通过轻触预览区域来设置对焦区域,然后您会将该区域转换为 Camera.Area 对象,并请求相机将焦点放在场景中的该区域。该区域的焦点或曝光会随着该区域的场景发生变化而不断更新。

为照片连续自动对焦

您现在可以在拍照时启用连续自动对焦 (CAF)。如需在相机应用中启用 CAF,请将 FOCUS_MODE_CONTINUOUS_PICTURE 传递给 setFocusMode()。准备好拍摄照片后,调用 autoFocus()。您的 Camera.AutoFocusCallback 会立即收到一个回调,以表明是否已获得焦点。如需在收到回调后恢复 CAF,您必须调用 cancelAutoFocus()

注意:使用 API 级别 9 中的 FOCUS_MODE_CONTINUOUS_VIDEO 拍摄视频时,系统也支持连续自动对焦功能。

其他相机功能

摄像头广播 intent

  • Camera.ACTION_NEW_PICTURE:这表示用户拍摄了一张新照片。内置的相机应用会在拍摄照片后调用此广播,而第三方相机应用也应在拍摄照片后广播此 intent。
  • Camera.ACTION_NEW_VIDEO:这表示用户拍摄了新视频。内置的相机应用会在视频录制完成后调用此广播,并且第三方相机应用也应在拍摄视频后广播此 intent。

Android Beam(使用 NFC 进行 NDEF 推送)

Android Beam 是一项新的 NFC 功能,可让您将 NDEF 消息从一个设备发送到另一个设备(此过程也称为“NDEF 推送”)。当两台支持 Android Beam 的 Android 设备相距很近(约 4 厘米)时(通常是其背面相接触),即会启动数据传输。NDEF 消息内的数据可包含您想在设备之间共享的任何数据。例如,“联系人”应用使用 Android Beam 分享联系人,YouTube 分享视频,浏览器分享网址。

如需使用 Android Beam 在设备之间传输数据,您需要创建一个 NdefMessage,其中包含您希望在 activity 位于前台时分享的信息。然后,必须通过以下两种方式之一将 NdefMessage 传递给系统:

如果您想在系统成功将 NDEF 消息传送到其他设备后运行某些特定的代码,可以实现 NfcAdapter.OnNdefPushCompleteCallback 并使用 setNdefPushCompleteCallback() 进行设置。然后,系统会在消息传递后调用 onNdefPushComplete()

在接收设备上,系统会发送 NDEF 推送消息,方式与常规 NFC 标签类似。系统会根据 NdefMessage 中的第一个 NdefRecord 设置网址或 MIME 类型,从而调用具有 ACTION_NDEF_DISCOVERED 操作的 intent 来启动 activity。对于您要响应的 activity,您可以为应用关注的网址或 MIME 类型声明 intent 过滤器。如需详细了解标签调度,请参阅 NFC 开发者指南。

如果您希望 NdefMessage 带有 URI,现在可以使用便捷方法 createUri 基于字符串或 Uri 对象构造新的 NdefRecord。如果您想让应用在 Android Beam 事件期间收到这种特殊格式,应使用相同的 URI 架构为 activity 创建一个 intent 过滤器,以便接收传入的 NDEF 消息。

您还应通过 NdefMessage 传递“Android 应用记录”,以确保您的应用会处理传入的 NDEF 消息,即使其他应用对同一 intent 操作进行过滤也是如此。您可以通过调用 createApplicationRecord() 并向其传递应用的软件包名称来创建 Android 应用记录。当其他设备收到包含应用记录的 NDEF 消息,并且多个应用包含用于处理指定 intent 的 activity 时,系统始终会将该消息传递给应用中的 activity(根据匹配的应用记录)。如果目标设备当前未安装您的应用,系统会使用 Android 应用记录启动 Google Play,并将用户转到应用进行安装。

如果您的应用不使用 NFC API 执行 NDEF 推送消息传递,那么 Android 提供一种默认行为:当您的应用在一部设备上的前台运行时,当另一台 Android 设备调用 Android Beam 时,另一台设备将收到一条 NDEF 消息,其中包含一条用于标识您的应用的 Android 应用记录。如果接收方设备安装了该应用,系统会启动该应用;如果未安装该应用,Google Play 会打开并将用户引导至您的应用进行安装。

您可以在 NFC 基础知识开发者指南中详细了解 Android Beam 和其他 NFC 功能。如需查看一些使用 Android Beam 的示例代码,请参阅 Android Beam 演示

Wi-Fi P2P

Android 现在支持 Android 设备与其他设备类型(符合 Wi-Fi 联盟的 Wi-Fi DirectTM 认证计划)之间的无热点或互联网连接的 Wi-Fi 点对点 (P2P) 连接。Android 框架提供了一组 Wi-Fi 点对点 API,可让您发现并连接到其他设备(当每台设备支持 Wi-Fi 点对点时),然后通过高速连接进行通信,这些距离远远超过蓝牙连接。

新软件包 android.net.wifi.p2p 包含用于通过 Wi-Fi 执行点对点连接的所有 API。您需要使用的主类是 WifiP2pManager,您可以通过调用 getSystemService(WIFI_P2P_SERVICE) 获取该类。WifiP2pManager 包含可让您执行以下操作的 API:

其他几个接口和类也是必要的,例如:

为了使用 Wi-Fi P2P API,您的应用必须请求以下用户权限:

在某些 Wi-Fi 点对点事件发生期间,Android 系统还会广播几种不同的操作:

如需了解详情,请参阅 WifiP2pManager 文档。另请参阅 Wi-Fi 点对点演示示例应用。

蓝牙健康设备

Android 现在支持使用蓝牙健康配置文件设备,因此您可以创建使用蓝牙与支持蓝牙功能的健康设备(例如心率监测器、血糖仪、温度计、体重秤)进行通信的应用。

与常规耳机和采用 A2DP 配置文件的设备类似,您必须使用 BluetoothProfile.ServiceListenerHEALTH 配置文件类型调用 getProfileProxy(),才能与配置文件代理对象建立连接。

获取健康配置文件代理(BluetoothHealth 对象)后,要连接到配对的健康设备并与之通信,需要用到以下新的蓝牙类:

如需详细了解如何使用蓝牙健康配置文件,请参阅 BluetoothHealth 的文档。

无障碍功能

Android 4.0 通过全新的“轻触探索”模式和扩展的 API(可让您提供有关查看内容或开发高级无障碍服务的更多信息),改善了视障用户的无障碍功能。

“触摸浏览”模式

有视力障碍的用户现在可以通过触摸并在屏幕上拖动手指来探索屏幕,聆听对内容的语音描述。由于“触摸浏览”模式的工作方式类似于虚拟光标,因此屏幕阅读器可以像用户使用方向键或轨迹球导航时一样,通过读取 android:contentDescriptionsetContentDescription() 提供的信息来识别描述性文本,从而识别说明性文本,也就是在发生模拟的“悬停”事件时进行识别。因此,谨在此提醒您,您应该为应用中的视图提供描述性文本,尤其是为 ImageButtonEditTextImageView 以及其他可能不会自然包含描述性文本的 widget。

视图无障碍功能

为了增强屏幕阅读器等无障碍服务可用的信息,您可以在自定义 View 组件中为无障碍事件实现新的回调方法。

首先请务必注意,sendAccessibilityEvent() 方法的行为在 Android 4.0 中已发生更改。与以前的 Android 版本一样,当用户在设备上启用无障碍服务并且发生点击或悬停等输入事件时,系统会调用 sendAccessibilityEvent() 来通知相应的视图。以前,sendAccessibilityEvent() 的实现会初始化 AccessibilityEvent 并将其发送到 AccessibilityManager。新行为涉及一些额外的回调方法,这些方法允许视图及其父级向事件添加更多上下文信息:

  1. 调用时,sendAccessibilityEvent()sendAccessibilityEventUnchecked() 方法会遵循 onInitializeAccessibilityEvent()

    View 的自定义实现可能希望实现 onInitializeAccessibilityEvent() 以将其他无障碍功能信息附加到 AccessibilityEvent,但还应调用超类实现来提供默认信息,例如标准内容说明、项索引等。不过,您不应在此回调中添加额外的文本内容(接下来会发生)。

  2. 初始化后,如果事件是应该使用文本信息填充的几种类型之一,视图随后会收到对 dispatchPopulateAccessibilityEvent() 的调用,该调用遵循 onPopulateAccessibilityEvent() 回调。

    View 的自定义实现通常应实现 onPopulateAccessibilityEvent(),以便在 android:contentDescription 文本缺失或不足时向 AccessibilityEvent 添加其他文本内容。如需向 AccessibilityEvent 添加更多文本说明,请调用 getText().add()

  3. 此时,View 通过对父视图调用 requestSendAccessibilityEvent() 将事件向上传递视图层次结构。然后,每个父视图都有机会通过添加 AccessibilityRecord 来扩充无障碍功能信息,直到最终到达根视图,根视图会使用 sendAccessibilityEvent() 将事件发送到 AccessibilityManager

除了上面扩展 View 类时很有用的新方法之外,您还可以扩展 AccessibilityDelegate 并使用 setAccessibilityDelegate() 在视图上设置它,从而在任何 View 上拦截这些事件回调。这样,视图中的每个无障碍方法都会将调用推迟到委托中的相应方法。例如,当视图收到对 onPopulateAccessibilityEvent() 的调用时,会将其传递给 View.AccessibilityDelegate 中的同一方法。为实现默认行为,委托未处理的所有方法都会立即返回给视图。这样一来,您就可以仅替换任何给定视图所需的方法,而无需扩展 View 类。

如果您想保持与 4.0 之前的 Android 版本的兼容性,同时支持新的无障碍功能 API,则可以通过最新版本的 v4 支持库(在兼容性软件包 r4 中)使用一组实用程序类来实现该目标,这些实用程序类以向后兼容的设计提供新的无障碍功能 API。

无障碍服务

如果您正在开发无障碍服务,则有关各种无障碍事件的信息已大大扩展,以便为用户提供更高级的无障碍反馈。特别是,事件是基于视图合成生成的,这样可以提供更好的上下文信息,并允许无障碍服务遍历视图层次结构,以获取额外的视图信息并处理特殊情况。

如果您要开发无障碍服务(例如屏幕阅读器),可以按照以下步骤访问其他内容信息并遍历视图层次结构:

  1. 从应用收到 AccessibilityEvent 后,请调用 AccessibilityEvent.getRecord() 以检索特定的 AccessibilityRecord(该事件可能附加了多条记录)。
  2. AccessibilityEvent 或单个 AccessibilityRecord 中,您可以调用 getSource() 来检索 AccessibilityNodeInfo 对象。

    AccessibilityNodeInfo 表示窗口内容的单个节点,采用的格式允许您查询该节点的无障碍功能信息。从 AccessibilityEvent 返回的 AccessibilityNodeInfo 对象描述事件来源,而 AccessibilityRecord 中的来源描述事件来源的前身。

  3. 借助 AccessibilityNodeInfo,您可以查询与其相关的信息,调用 getParent()getChild() 来遍历视图层次结构,甚至可以向节点添加子视图。

为了让应用将自身作为无障碍服务发布到系统,应用必须声明与 AccessibilityServiceInfo 对应的 XML 配置文件。如需详细了解如何创建无障碍服务,请参阅 AccessibilityServiceSERVICE_META_DATA,了解有关 XML 配置的信息。

其他无障碍功能 API

如果您对设备的无障碍状态感兴趣,不妨让 AccessibilityManager 包含一些新的 API,例如:

拼写检查工具服务

借助新的拼写检查工具框架,应用能够以类似于输入法框架(适用于 IME)的方式创建拼写检查工具。如需创建新的拼写检查工具,您必须实现一项服务来扩展 SpellCheckerService 并扩展 SpellCheckerService.Session 类,以便根据接口的回调方法提供的文本提供拼写建议。在 SpellCheckerService.Session 回调方法中,您必须以 SuggestionsInfo 对象的形式返回拼写建议。

使用拼写检查工具服务的应用必须根据该服务的需要声明 BIND_TEXT_SERVICE 权限。 此服务还必须声明一个 intent 过滤器,并将 <action android:name="android.service.textservice.SpellCheckerService" /> 作为 intent 的操作,并且应包含一个 <meta-data> 元素来为拼写检查工具声明配置信息。

如需查看示例代码,请参阅 拼写检查工具服务示例应用和 拼写检查工具客户端应用示例。

文字转语音引擎

Android 的文字转语音 (TTS) API 已经过大幅扩展,可让应用更轻松地实现自定义 TTS 引擎,而希望使用 TTS 引擎的应用则具有几个用于选择引擎的新 API。

使用文字转语音引擎

在以前的 Android 版本中,您可以使用 TextToSpeech 类通过系统提供的 TTS 引擎执行文字转语音 (TTS) 操作,也可以使用 setEngineByPackageName() 设置自定义引擎。在 Android 4.0 中,setEngineByPackageName() 方法已废弃,您现在可以使用接受 TTS 引擎软件包名称的新 TextToSpeech 构造函数来指定要使用的引擎。

您还可以使用 getEngines() 查询可用的 TTS 引擎。此方法会返回 TextToSpeech.EngineInfo 对象的列表,其中包括引擎的图标、标签和软件包名称等元数据。

构建文字转语音引擎

以前,自定义引擎要求使用未记录的原生头文件构建引擎。Android 4.0 中有一整套用于构建 TTS 引擎的框架 API。

基本设置需要实现响应 INTENT_ACTION_TTS_SERVICE intent 的 TextToSpeechService。TTS 引擎的主要工作发生在扩展 TextToSpeechService 的服务中的 onSynthesizeText() 回调期间。系统会向此方法传递两个对象:

  • SynthesisRequest:包含各种数据,包括要合成的文本、语言区域、语速和音调。
  • SynthesisCallback:这是 TTS 引擎用于将生成的语音数据作为流式音频传送的接口。首先,引擎必须调用 start() 以表明引擎已准备好传输音频,然后再调用 audioAvailable(),以字节缓冲区中的形式向其传递音频数据。在您的引擎已通过所有音频的缓冲区传递所有音频后,调用 done()

现在,该框架支持用于创建 TTS 引擎的真实 API,因此不再支持原生代码实现。查找有关兼容性层的博文,您可以使用该层将旧的 TTS 引擎转换为新框架。

如需查看使用新 API 的 TTS 引擎示例,请参阅文字转语音引擎示例应用。

网络使用

Android 4.0 可让用户精确了解其应用当前使用了多少网络流量。“设置”应用提供了一些控件,可让用户管理设置的网络流量使用限制,甚至禁止各个应用使用后台流量。为了避免用户禁止您的应用从后台访问数据,您应该制定相关策略来高效使用数据连接,并根据可用连接类型调整用量。

如果您的应用执行大量网络事务,您应提供用户设置,以允许用户控制应用的数据使用习惯,例如应用同步数据的频率、是否仅在连接到 Wi-Fi 时执行上传/下载、是否在漫游时使用数据等。有了这些控件,用户在接近自己的数据使用限制时就不太可能停用应用对数据的访问权限,因为他们可以精确控制数据使用方式。如果您提供具有这些设置的偏好设置 activity,则应在其清单声明中添加用于 ACTION_MANAGE_NETWORK_USAGE 操作的 intent 过滤器。例如:

<activity android:name="DataPreferences" android:label="@string/title_preferences">
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

此 intent 过滤器会向系统表明,这是控制应用流量消耗的 activity。因此,当用户从“设置”应用检查应用使用了多少流量时,可以使用“查看应用设置”按钮启动偏好设置 activity,以便用户优化应用使用的数据量。

另请注意,getBackgroundDataSetting() 现已废弃,且始终返回 true,请改用 getActiveNetworkInfo()。在尝试任何网络事务之前,您应始终调用 getActiveNetworkInfo() 以获取表示当前网络的 NetworkInfo,并查询 isConnected() 以检查设备是否已连接到网络。然后,您可以检查其他连接属性,例如设备是处于漫游状态还是已连接到 Wi-Fi 网络。

Android Enterprise

Android 4.0 通过以下功能扩展了企业应用的功能。

VPN 服务

新的 VpnService 允许应用构建自己的 VPN(虚拟专用网),以 Service 的形式运行。VPN 服务会使用自己的地址和路由规则为虚拟网络创建接口,并使用文件描述符执行所有读取和写入操作。

如需创建 VPN 服务,请使用 VpnService.Builder,让您能够指定网络地址、DNS 服务器、网络路由等。完成后,您可以通过调用返回 ParcelFileDescriptorestablish() 来建立接口。

由于 VPN 服务可以拦截数据包,因此会带来安全隐患。因此,如果您实现 VpnService,则您的服务必须请求 BIND_VPN_SERVICE,以确保只有系统可以与其绑定(只有系统被授予此权限,应用无法请求此权限)。用户必须在系统设置中手动启用 VPN 服务,然后才能使用该服务。

设备政策

管理设备限制的应用现在可以使用 setCameraDisabled()USES_POLICY_DISABLE_CAMERA 属性(在政策配置文件中通过 <disable-camera /> 元素应用)停用相机。

证书管理

新的 KeyChain 类提供了可用于在系统密钥库中导入和访问证书的 API。证书可以简化客户端证书(验证用户的身份)和证书授权机构证书(验证服务器身份)的安装。网络浏览器或电子邮件客户端等应用可以访问已安装的证书,以向服务器验证用户身份。如需了解详情,请参阅 KeyChain 文档。

设备传感器

Android 4.0 中添加了两种新的传感器类型:

如果设备同时具有 TYPE_AMBIENT_TEMPERATURETYPE_RELATIVE_HUMIDITY 传感器,您可以使用它们来计算露点和绝对湿度。

之前的温度传感器 TYPE_TEMPERATURE 已弃用。您应改用 TYPE_AMBIENT_TEMPERATURE 传感器。

此外,Android 的三个合成传感器也得到了极大改进,因此它们现在的延迟时间更短,输出更流畅。这些传感器包括重力传感器 (TYPE_GRAVITY)、旋转矢量传感器 (TYPE_ROTATION_VECTOR) 和线性加速度传感器 (TYPE_LINEAR_ACCELERATION)。这些改进的传感器依赖陀螺仪传感器来提升其输出,因此这些传感器仅会显示在配备陀螺仪的设备上。

操作栏

更新了 ActionBar,以支持多种新行为。最重要的是,在较小的屏幕上运行时,系统会妥善管理操作栏的尺寸和配置,以便在所有尺寸的屏幕上提供最佳用户体验。例如,当屏幕较窄时(例如手机处于竖屏模式时),操作栏的导航标签页将显示在主操作栏正下方显示的“堆叠栏”中。您还可以选择使用“分屏操作栏”,当屏幕较窄时,该栏会将所有操作项放置在屏幕底部的单独栏中。

拆分操作栏

如果您的操作栏包含多个操作项,但并非所有操作项都能容纳在窄屏上的操作栏中,因此系统会将更多操作项放入溢出菜单中。不过,Android 4.0 允许您启用“拆分操作栏”,以便更多内容可以显示在屏幕底部的单独栏中。如需启用拆分操作栏,请将带有 "splitActionBarWhenNarrow"android:uiOptions 添加到清单文件中的 <application> 标记或各个 <activity> 标记中。启用后,当屏幕较窄时,系统会在屏幕底部为所有操作项额外添加一个栏(主要操作栏中不会显示任何操作项)。

如果您想使用 ActionBar.Tab API 提供的导航标签页,但不需要在顶部设置主操作栏(您希望仅标签页显示在顶部),请按上述方法启用拆分操作栏,并调用 setDisplayShowHomeEnabled(false) 以停用操作栏中的应用图标。如果主操作栏中没有任何内容,它会消失,只留下顶部的导航标签页和屏幕底部的操作项。

操作栏样式

如果您想将自定义样式应用于操作栏,可以使用新的样式属性 backgroundStackedbackgroundSplit,分别将背景可绘制对象或颜色应用于堆叠栏和拆分栏。您还可以在运行时使用 setStackedBackgroundDrawable()setSplitBackgroundDrawable() 设置这些样式。

操作提供器

利用新的 ActionProvider 类,您可以为操作项创建专用处理程序。操作提供器可以为其关联的每个操作项定义操作视图、默认操作行为和子菜单。如果您想创建具有动态行为(如变量操作视图、默认操作或子菜单)的操作项,那么为了创建可重复使用的组件,扩展 ActionProvider 是一个很好的解决方案,无需在 fragment 或 activity 中处理各种操作项转换。

例如,ShareActionProviderActionProvider 的扩展,有助于在操作栏中执行“分享”操作。您可以使用此操作提供器显示操作视图,其中包含处理 ACTION_SEND intent 的应用下拉列表,而不是使用调用 ACTION_SEND intent 的传统操作项。当用户选择用于执行操作的应用时,ShareActionProvider 会记住该选择并在操作视图中提供该选择,以便更快地访问与该应用分享的信息。

如需为操作项声明操作提供器,请在 activity 的选项菜单的 <item> 元素中添加 android:actionProviderClass 属性,并将操作提供器的类名称作为值。例如:

<item android:id="@+id/menu_share"
      android:title="Share"
      android:showAsAction="ifRoom"
      android:actionProviderClass="android.widget.ShareActionProvider" />

在您的 activity 的 onCreateOptionsMenu() 回调方法中,从菜单项检索操作提供器的实例,并设置 intent:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options, menu)
    val shareActionProvider = menu.findItem(R.id.menu_share)?.actionProvider as? ShareActionProvider
    // Set the share intent of the share action provider.
    shareActionProvider?.setShareIntent(createShareIntent())
    ...
    return super.onCreateOptionsMenu(menu)
}

Java

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    ShareActionProvider shareActionProvider =
          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
    // Set the share intent of the share action provider.
    shareActionProvider.setShareIntent(createShareIntent());
    ...
    return super.onCreateOptionsMenu(menu);
}

如需查看使用 ShareActionProvider 的示例,请参阅 ApiDemos 中的 ActionBarShareActionProviderActivity

折叠式操作视图

提供操作视图的操作项现在可以在其操作视图状态和传统操作项状态之间切换。以前,只有SearchView支持收起时用作操作视图,但现在您可以为任何操作项添加操作视图,并在展开状态(操作视图可见)和收起状态(操作项可见)之间切换。

如需声明包含操作视图的操作项可收起,请在菜单 XML 文件中 <item> 元素的 android:showAsAction 属性中添加 “collapseActionView" 标志。

如需在操作视图在展开和收起之间切换时接收回调,请通过调用 setOnActionExpandListener() 向相应的 MenuItem 注册 MenuItem.OnActionExpandListener 实例。通常,应在 onCreateOptionsMenu() 回调期间执行此操作。

如需控制可折叠操作视图,您可以对相应的 MenuItem 调用 collapseActionView()expandActionView()

创建自定义操作视图时,您还可以实现新的 CollapsibleActionView 接口,以便在视图展开和收起时接收回调。

操作栏的其他 API

  • setHomeButtonEnabled() 用于指定图标/徽标是用作导航主屏幕按钮,还是用作“向上导航”按钮(传递“true”可使其充当按钮)。
  • setIcon()setLogo() 可让您在运行时定义操作栏图标或徽标。
  • Fragment.setMenuVisibility() 用于启用或停用由 fragment 声明的选项菜单项的可见性。如果 fragment 已添加到 activity 中,但未显示,这非常有用,因此应隐藏菜单项。
  • FragmentManager.invalidateOptionsMenu() 允许您在 fragment 生命周期的各种状态下使 activity 选项菜单失效,在这些 fragment 生命周期中,使用 Activity 中的等效方法可能不可用。

界面和视图

Android 4.0 引入了各种新视图和其他界面组件。

GridLayout

GridLayout 是一个新的视图组,用于将子视图放置在矩形网格中。与 TableLayout 不同,GridLayout 依赖于平面层次结构,而不是利用中间视图(例如表格行)来提供结构。相反,子项指定它们应占用的行和列(单元格可以跨越多个行和/或列),并且默认情况下会按顺序排列网格的行和列。GridLayout 方向决定顺序子项默认是水平布局还是垂直布局。可以使用新 Space 视图的实例或通过为子项设置相关的外边距参数,指定子项之间的间距。

如需查看使用 GridLayout 的示例,请参阅 ApiDemos

TextureView

TextureView 是一个新视图,可让您显示内容流(例如视频或 OpenGL 场景)。虽然与 SurfaceView 类似,但 TextureView 的独特之处在于,它的行为类似于常规视图,而不是创建单独的窗口,因此您可以像对待任何其他 View 对象一样对待它。例如,您可以应用转换,使用 ViewPropertyAnimator 为其添加动画效果,或使用 setAlpha() 调整其不透明度。

请注意,TextureView 只能在硬件加速的窗口中运行。

如需了解详情,请参阅 TextureView 文档。

切换微件

新的 Switch widget 是一个双状态切换开关,用户可以将其拖动到一侧(或直接点按),从而在两种状态之间切换选项。

您可以使用 android:textOnandroid:textOff 属性指定在开启和关闭设置下显示在开关上的文本。您还可以使用 android:text 属性在开关旁边放置标签。

如需查看使用开关的示例,请参阅 switches.xml 布局文件以及相应的开关 activity。

Android 3.0 引入了 PopupMenu,用于创建可在您指定的定位点(通常位于所选项目的点)上弹出的简短上下文菜单。Android 4.0 通过几项实用功能扩展了 PopupMenu

偏好设置

新的 TwoStatePreference 抽象类可用作提供双状态选择选项的偏好设置的基础。新的 SwitchPreferenceTwoStatePreference 的扩展,它会在偏好设置视图中提供一个 Switch widget,让用户能够开启或关闭某项设置,而无需打开额外的偏好设置屏幕或对话框。例如,“设置”应用会使用 SwitchPreference 进行 Wi-Fi 和蓝牙设置。

系统主题

以 Android 4.0 为目标平台的所有应用的默认主题(通过将 targetSdkVersionminSdkVersion 设置为 “14" 或更高版本)现在是“设备默认”主题:Theme.DeviceDefault。这可以是深色 Holo 主题,也可以是特定设备定义的其他深色主题。

在运行相同版本的 Android 时,Theme.Holo 主题系列保证不会在不同设备之间发生变化。如果您将任何 Theme.Holo 主题明确应用于 activity,请放心,这些主题不会在同一平台版本的不同设备上更改字符。

如果您希望应用与整体设备主题融为一体(例如,当不同 OEM 为系统提供不同的默认主题时),您应明确应用 Theme.DeviceDefault 系列中的主题。

选项菜单按钮

从 Android 4.0 开始,您会注意到手机不再需要“菜单”硬件按钮。不过,如果现有应用提供选项菜单并预计会有“菜单”按钮,则无需担心这一点。为了确保现有应用继续按预期运行,系统会为专为旧版 Android 设计的应用提供屏幕菜单按钮。

为了提供最佳用户体验,全新应用和更新版应用应改用 ActionBar 来提供菜单项访问权限,并将 targetSdkVersion 设为 "14",以便利用最新的框架默认行为。

系统界面可见性控件

自 Android 问世以来,系统一直管理着一个称为“状态栏”的界面组件,该组件位于手机设备顶部,用于传递运营商信号、时间、通知等信息。Android 3.0 为平板电脑设备添加了系统栏,它位于屏幕底部,用于提供系统导航控件(主屏幕、返回等),以及状态栏通常提供的元素界面。在 Android 4.0 中,系统提供了一种新型系统界面,称为“导航栏”。您可以将导航栏视为专为手机设计的系统栏经过调整的版本 - 它为没有用于导航的硬件对应的设备提供导航控件,但省去了系统栏的通知界面和设置控件。因此,提供导航栏的设备在顶部也会显示状态栏。

到目前为止,您可以使用 FLAG_FULLSCREEN 标志隐藏手机上的状态栏。在 Android 4.0 中,控制系统栏可见性的 API 已更新,以更好地反映系统栏和导航栏的行为:

  • SYSTEM_UI_FLAG_LOW_PROFILE 标志取代了 STATUS_BAR_HIDDEN 标志。设置后,此标志会为系统栏或导航栏启用“低调”模式。导航按钮变暗,系统栏中的其他元素也会隐藏。启用此属性有助于创建沉浸感更强的游戏,而不会干扰系统导航按钮。
  • SYSTEM_UI_FLAG_VISIBLE 标志取代 STATUS_BAR_VISIBLE 标志,以请求显示系统栏或导航栏。
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION 是一个新标志,用于请求完全隐藏导航栏。请注意,这仅适用于某些手机使用的导航栏(并不会在平板电脑上隐藏系统栏)。系统收到用户输入后,导航栏会立即返回视图。因此,此模式主要适用于视频播放或需要整个屏幕但不需要用户输入的其他情况。

您可以对 activity 中的任何视图调用 setSystemUiVisibility(),为系统栏和导航栏设置各个标志。窗口管理器会将窗口中所有视图的所有标记合并(或运算在一起),并只要您的窗口具有输入焦点,它们就会应用到系统界面。当您的窗口失去输入焦点(用户离开您的应用,或出现一个对话框)时,标记会失效。同样,如果您从视图层次结构中移除这些视图,其标志将不再适用。

如需将 activity 中的其他事件与系统界面的可见性更改进行同步(例如,在系统界面隐藏时隐藏操作栏或其他界面控件),您应该注册 View.OnSystemUiVisibilityChangeListener,以便在系统栏或导航栏的可见性发生变化时收到通知。

有关不同系统界面选项的演示,请参阅 OverscanActivity 类。

输入框架

Android 4.0 添加了对光标悬停事件以及新的触控笔和鼠标按钮事件的支持。

悬停事件

View 类现在支持“悬停”事件,以便通过使用指针设备(例如鼠标或驱动屏幕光标的其他设备)实现更丰富的互动。

如需在视图上接收悬停事件,请实现 View.OnHoverListener 并使用 setOnHoverListener() 注册它。当视图上发生悬停事件时,监听器会收到对 onHover() 的调用,提供接收事件的 View 和描述发生的悬停事件类型的 MotionEvent。悬停事件可以是以下事件之一:

如果 View.OnHoverListener 会处理悬停事件,则应从 onHover() 返回 true。如果监听器返回 false,悬停事件会照常分派给父视图。

如果您的应用使用会根据当前状态更改其外观的按钮或其他 widget,您现在可以在状态列表可绘制对象中使用 android:state_hovered 属性,以便在光标悬停在视图上时提供不同的背景可绘制对象。

有关新悬停事件的演示,请参阅 ApiDemos 中的 Hover 类。

触控笔和鼠标按钮事件

Android 现在提供用于从触控笔输入设备(例如数字化仪平板电脑外围设备或支持触控笔的触摸屏)接收输入的 API。

触控笔输入的运作方式与触摸或鼠标输入类似。当触控笔与数字转换器接触时,应用会接收触摸事件,就像用手指触摸显示屏时一样。当触控笔悬停在数字转换器上方时,应用会收到悬停事件,就像在没有按下任何按钮的情况下在显示屏上移动鼠标指针时一样。

您的应用可以使用 getToolType() 查询与 MotionEvent 中的每个指针关联的“工具类型”,从而区分手指、鼠标、触控笔和橡皮擦输入。当前定义的工具类型包括:TOOL_TYPE_UNKNOWNTOOL_TYPE_FINGERTOOL_TYPE_MOUSETOOL_TYPE_STYLUSTOOL_TYPE_ERASER。通过查询工具类型,您的应用可以选择以不同于手指或鼠标输入的不同方式处理触控笔输入。

您的应用还可以使用 getButtonState() 查询 MotionEvent 的“按钮状态”,从而查询按下了哪些鼠标或触控笔按钮。当前定义的按钮状态包括:BUTTON_PRIMARYBUTTON_SECONDARYBUTTON_TERTIARYBUTTON_BACKBUTTON_FORWARD。为方便起见,后退和前进鼠标按钮会自动映射到 KEYCODE_BACKKEYCODE_FORWARD 键。您的应用可以处理这些键,以支持基于鼠标按钮的返回和前进导航。

除了精确测量触点的位置和压力之外,一些触控笔输入设备还会报告触控笔尖与数字转换器之间的距离、触控笔倾斜角度和触控笔方向角。您的应用可以使用 getAxisValue() 以及轴代码 AXIS_DISTANCEAXIS_TILTAXIS_ORIENTATION 查询此信息。

如需查看工具类型、按钮状态和新轴代码的演示,请参阅 ApiDemos 中的 TouchPaint 类。

属性

新的 Property 类提供了一种快速、高效且简单的方法来为任何对象指定属性,以允许调用方通用地设置/获取目标对象的值。它还支持传递字段/方法引用,并允许代码在不知道字段/方法的具体内容的情况下设置/获取属性的值。

例如,如果要在对象 foo 上设置 bar 字段的值,则需要先执行以下操作:

Kotlin

foo.bar = value

Java

foo.bar = value;

如果您要为底层不公开字段 bar 调用 setter,则需要先执行以下操作:

Kotlin

foo.setBar(value)

Java

foo.setBar(value);

不过,如果您想传递 foo 实例并让一些其他代码设置 bar 值,在 Android 4.0 之前的版本中,确实没有办法做到这一点。

使用 Property 类,您可以在类 Foo 上声明 Property 对象 BAR,以便按如下所示在 Foo 类的实例 foo 上设置该字段:

Kotlin

BAR.set(foo, value)

Java

BAR.set(foo, value);

View 类现在利用 Property 类允许您设置各种字段,例如在 Android 3.0 中添加的转换属性(ROTATIONROTATION_XTRANSLATION_X 等)。

ObjectAnimator 类也使用 Property 类,因此您可以使用 Property 创建 ObjectAnimator,与基于字符串的方法相比,这种方法更快速、更高效且类型安全。

硬件加速

从 Android 4.0 开始,如果您的应用已将 targetSdkVersionminSdkVersion 设置为 “14" 或更高版本,则所有窗口的硬件加速功能默认处于启用状态。硬件加速通常可使动画和滚动更流畅,并且能够提升整体性能和对用户互动的响应。

如有必要,您可以使用各个 <activity> 元素或 <application> 元素的 hardwareAccelerated 属性手动停用硬件加速。或者,您也可以通过调用 setLayerType(LAYER_TYPE_SOFTWARE) 为各个视图停用硬件加速。

如需详细了解硬件加速,包括不支持的绘制操作列表,请参阅硬件加速文档。

JNI 变更

在以前的 Android 版本中,JNI 局部引用不是间接句柄;Android 使用的是直接指针。只要垃圾回收器不移动对象,这个问题就不成问题,但它似乎能正常运行,因为它使您可以编写有 bug 的代码。在 Android 4.0 中,系统现在使用间接引用来检测这些 bug。

JNI 提示中的“局部和全局引用”介绍了 JNI 局部引用的方方面面。在 Android 4.0 中,我们增强了 CheckJNI 来检测这些错误。即将发布的博文介绍了 JNI 引用的常见错误以及如何修复这些错误,敬请关注 Android 开发者博客

JNI 实现中的这一变更只会影响以 Android 4.0 为目标平台的应用(通过将 targetSdkVersionminSdkVersion 设置为 “14" 或更高版本)。如果您将这些属性设置为任何更低的值,则 JNI 局部引用的行为与以前版本中的行为相同。

WebKit

  • WebKit 已更新至 534.30 版
  • WebView 和内置浏览器中支持印度语字体(梵文、孟加拉语和泰米尔语,包括组合使用字形所需的复杂字符)
  • WebView 和内置浏览器中支持埃塞俄比亚语、格鲁吉亚语和亚美尼亚语字体
  • WebDriver 的支持可让您更轻松地测试使用 WebView 的应用

Android 浏览器

浏览器应用添加了以下功能来支持 Web 应用:

权限

以下是新权限:

设备功能

以下是新的设备功能:

如需详细了解 Android 4.0(API 级别 14)中的所有 API 变更,请参阅 API 差异报告

旧版 API

除了上述各项之外,Android 4.0 自然也会支持以前版本中的所有 API。由于 Android 3.x 平台仅适用于大屏设备,因此如果您的开发主要是针对手机开发的,那么您可能不知道这些最新版本中添加到 Android 的所有 API。

下面来看一下您可能错过的一些最值得关注的 API,这些 API 现在也已在手机上提供:

Android 3.0
  • Fragment:一种框架组件,可让您将 activity 的不同元素拆分为独立的模块,这些模块定义自己的界面和生命周期。请参阅 fragment 开发者指南。
  • ActionBar:用于替代 activity 窗口顶部的传统标题栏。界面左上角包括应用徽标,并为菜单项提供了新界面。请参阅操作栏开发者指南。
  • Loader:一种框架组件,可协助异步加载数据,并与界面组件结合使用,以动态加载数据而不阻塞主线程。请参阅加载器开发者指南。
  • 系统剪贴板:应用可以将数据(而不仅仅是文本)复制并粘贴到系统级剪贴板,或从中粘贴数据。裁剪的数据可以是纯文本、URI 或 intent。请参阅复制和粘贴开发者指南。
  • 拖放:视图框架中内置的一组 API,可协助执行拖放操作。请参阅拖放开发者指南。
  • 借助全新的灵活动画框架,您可以为任何对象(View、Drawable、Fragment、Object 或任何其他对象)的任意属性添加动画效果,并定义动画方面,例如时长、插值、重复等。新框架使 Android 中的动画变得前所未有的简单。请参阅属性动画开发者指南。
  • RenderScript 图形和计算引擎:RenderScript 提供了原生级别的高性能 3D 图形渲染和计算 API,您可以使用 C(C99 标准)编写该 API,提供您在原生环境中所期望的性能类型,同时在不同 CPU 和 GPU 上保持可移植性。请参阅 RenderScript 开发者指南。
  • 硬件加速 2D 图形:现在,您可以通过在清单元素的 <application> 元素中或为各个 <activity> 元素设置 {android:hardwareAccelerated="true"},为您的应用启用 OpenGL 渲染程序。这样可以让动画和滚动更流畅,并且能够提升整体性能和用户互动响应。

    注意:如果您将应用的 minSdkVersiontargetSdkVersion 设为 "14" 或更高版本,则硬件加速默认处于启用状态。

  • 以及更多内容。如需了解详情,请参阅 Android 3.0 平台说明。
Android 3.1
  • USB API:功能强大的全新 API,用于将已连接的外围设备与 Android 应用集成。这些 API 基于 USB 堆栈以及平台中内置的服务,包括对 USB 主机和设备交互的支持。请参阅 USB 主机和配件开发者指南。
  • MTP/PTP API:应用可以直接与连接的摄像头和其他 PTP 设备交互,以便在连接和移除设备时收到通知、管理这些设备上的文件和存储,以及向它们传输文件和元数据。MTP API 实现了 MTP(媒体传输协议)规范的 PTP(图片传输协议)子集。请参阅 android.mtp 文档。
  • RTP API:Android 向其内置 RTP(实时传输协议)堆栈公开了 API,应用可以使用它来管理按需或交互式数据流。具体而言,提供 VoIP、推送通话、会议和音频流式传输的应用可以使用该 API 启动会话,并通过任何可用网络传输或接收数据流。请参阅 android.net.rtp 文档。
  • 支持操纵杆和其他通用动作输入。
  • 如需了解更多新 API,请参阅 Android 3.1 平台说明。
Android 3.2
  • 新屏幕支持 API,可让您更好地控制应用在不同屏幕尺寸上的显示方式。该 API 扩展了现有的屏幕支持模式,能够按尺寸精确定位特定屏幕尺寸范围,以密度无关像素单位(例如 600dp 或 720dp 宽)为单位,而不是按通用屏幕尺寸(例如大或特大)进行衡量。例如,这可以帮助您区分 5 英寸设备和 7 英寸设备,它们通常被划分为“大”屏幕。请参阅 用于管理屏幕尺寸的新工具这篇博文。
  • 新增了 <uses-feature> 常量,用于声明横向或纵向屏幕方向要求。
  • 现在,设备“屏幕尺寸”配置会在屏幕方向发生变化时发生变化。如果您的应用以 API 级别 13 或更高级别为目标平台,那么如果您还想处理 "orientation" 配置变更,则必须处理 "screenSize" 配置变更。如需了解详情,请参阅 android:configChanges
  • 如需了解其他新 API,请参阅 Android 3.2 平台说明。

API 级别

Android 4.0 API 被分配一个整数标识符 14,该标识符存储在系统本身中。此标识符称为“API 级别”,可让系统在安装应用之前正确确定应用是否与系统兼容。

若要在您的应用中使用 Android 4.0 中引入的 API,您需要针对支持 API 级别 14 或更高级别的 Android 平台编译应用。您可能还需要向 <uses-sdk> 元素添加 android:minSdkVersion="14" 属性,具体取决于您的需求。

如需了解详情,请参阅什么是 API 级别?