Android 4.1 API

API 级别:16

Android 4.1 (JELLY_BEAN) 是平台的进阶版,可提供更出色的性能和更出色的用户体验。它为用户和应用开发者添加了新功能。本文档介绍了面向应用开发者的最值得关注、最实用的新 API。

作为应用开发者,您可以从 SDK 管理器以系统映像的形式(在 Android 模拟器中运行)获取 Android 4.1,从而通过 SDK 平台构建应用。您应尽快下载系统映像和平台,以便在 Android 4.1 上构建和测试您的应用。

为了更好地针对搭载 Android 4.1 的设备优化您的应用,您应将 targetSdkVersion 设置为 "16",将其安装在 Android 4.1 系统映像上并进行测试,然后发布包含此变更的更新。

您可以使用 Android 4.1 中的 API,同时支持较低版本,方法是在代码中添加条件,在执行您的 minSdkVersion 不支持的 API 之前检查系统 API 级别。如需详细了解如何保持向后兼容性,请参阅创建向后兼容界面

如需详细了解 API 级别的工作原理,请参阅什么是 API 级别?

应用组件

隔离服务

通过在 <service> 标记中指定 android:isolatedProcess="true"Service 将在自身没有权限的独立用户 ID 进程下运行。

内存管理

新的 ComponentCallbacks2 常量(如 TRIM_MEMORY_RUNNING_LOWTRIM_MEMORY_RUNNING_CRITICAL)可在系统调用 onLowMemory() 之前为前台进程提供有关内存状态的更多信息。

新的 getMyMemoryState(ActivityManager.RunningAppProcessInfo) 方法允许您检索常规内存状态。

content provider

新方法 acquireUnstableContentProviderClient() 可让您访问可能“不稳定”的 ContentProviderClient,这样一来,即使 content provider 出现崩溃,您的应用也不会崩溃。如果您在单独的应用中与 content provider 互动,此按钮会很有用。

动态壁纸

新增了 intent 协议,可直接启动动态壁纸预览 activity,以便帮助用户轻松选择您的动态壁纸,而无需强制他们离开您的应用并在主屏幕壁纸选择器中导航。

如需启动动态壁纸选择器,请使用 ACTION_CHANGE_LIVE_WALLPAPER 通过 Intent 调用 startActivity(),并在 EXTRA_LIVE_WALLPAPER_COMPONENT 中将动态壁纸 ComponentName 指定为字符串。

应用堆栈导航

Android 4.1 可让您更轻松地为向上导航实现正确的设计模式。您只需将 android:parentActivityName 添加到清单文件中的每个 <activity> 元素即可。当用户按下操作栏中的“向上”按钮时(同时完成当前 activity),系统会使用此信息打开相应的 activity。因此,如果您为每个 activity 声明了 android:parentActivityName,则不需要使用 onOptionsItemSelected() 方法处理操作栏应用图标上的点击事件,系统现在会处理该事件,然后恢复或创建相应的 activity。

当用户通过“深度解析”intent(例如,从通知或来自不同应用的 intent)进入应用的某个 activity 时,此功能尤其强大(如在应用之间导航设计指南中所述)。当用户通过这种方式进入您的 activity 时,您的应用本身可能不会有可在用户向上导航时恢复的 activity 返回堆栈。不过,如果您为 activity 提供 android:parentActivityName 属性,系统会识别您的应用是否已包含父 activity 的返回堆栈,如果没有,则会构造包含所有父 activity 的合成返回堆栈。

注意:当用户在应用中进入深度 activity 并为应用创建新任务时,实际上是将父 activity 的堆栈插入到该任务中。因此,按返回按钮也会在父 activity 堆栈中返回。

当系统为您的应用创建合成返回堆栈时,它会构建一个基本的 Intent 来为每个父 activity 创建一个新实例。因此,父 activity 不存在用户自然导航浏览每个 activity 所期望的方式。如果任何父 activity 正常显示依赖于用户上下文的界面,则该上下文信息将缺失,您应该在用户导航返回堆栈时提供该信息。例如,如果用户正在音乐应用中查看专辑,向上导航可能会将用户带到列出所选音乐类型中的所有专辑的 activity。在这种情况下,如果必须创建堆栈,则必须告知父 activity 当前专辑所属的类型,以便父项可以显示正确的列表,就像用户确实来自该 activity 一样。如需将此类信息传递给合成父 activity,您必须替换 onPrepareNavigateUpTaskStack() 方法。这将为您提供系统为了合成父 activity 而创建的 TaskStackBuilder 对象。TaskStackBuilder 包含系统用于创建每个父 activity 的 Intent 对象。在 onPrepareNavigateUpTaskStack() 的实现中,您可以修改相应的 Intent 以添加额外数据,以供父 activity 用于确定相应上下文并显示相应的界面。

当系统创建 TaskStackBuilder 时,它会添加 Intent 对象,这些对象用于按照从 activity 树顶部开始的逻辑顺序创建父 activity。因此,添加到内部数组的最后一个 Intent 是当前 activity 的直接父项。如果您要修改 activity 父级的 Intent,请先使用 getIntentCount() 确定数组的长度,然后将该值传递给 editIntentAt()

如果您的应用结构更为复杂,还有其他一些 API 可用于处理向上导航的行为,并完全自定义合成返回堆栈。一些为您提供额外控制的 API 包括:

onNavigateUp()
替换此设置,以便在用户按向上按钮时执行自定义操作。
navigateUpTo(Intent)
调用此函数以结束当前 activity,并转到提供的 Intent 指示的 activity。如果 activity 存在于返回堆栈中,但不是最近的父项,则当前 activity 与通过 intent 指定的 activity 之间的所有其他 activity 也会结束。
getParentActivityIntent()
调用此方法以获取将启动当前 activity 的逻辑父项的 Intent
shouldUpRecreateTask(Intent)
调用此函数以查询是否必须创建合成返回堆栈才能向上导航。如果必须创建合成堆栈,则返回 true;如果已存在适当的堆栈,则返回 false。
finishAffinity()
调用此方法可以结束当前 activity 以及链接到当前 activity 且具有相同任务亲和性的所有父 activity。如果您替换 onNavigateUp() 等默认行为,则应在执行向上导航时创建合成返回堆栈时调用此方法。
onCreateNavigateUpTaskStack
如果您需要完全控制合成任务堆栈的创建方式,请替换此方法。如果您只想向返回堆栈的 intent 添加一些额外的数据,则应替换 onPrepareNavigateUpTaskStack()

不过,大多数应用不需要使用这些 API 或实现 onPrepareNavigateUpTaskStack(),但只需将 android:parentActivityName 添加到每个 <activity> 元素,即可实现正确的行为。

多媒体

媒体编解码器

MediaCodec 类提供对低级媒体编解码器的访问权限,用于对媒体进行编码和解码。您可以通过调用 createEncoderByType() 对媒体进行编码或调用 createDecoderByType() 对媒体进行解码来实例化 MediaCodec。每种方法都接受您要编码或解码的媒体类型的 MIME 类型,例如 "video/3gpp""audio/vorbis"

创建 MediaCodec 的实例后,您可以调用 configure() 来指定媒体格式或内容是否加密等属性。

无论您是对媒体进行编码还是解码,在您创建 MediaCodec 后,其余过程都是相同的。首先调用 getInputBuffers() 以获取输入 ByteBuffer 对象的数组,并调用 getOutputBuffers() 以获取输出 ByteBuffer 对象的数组。

当您准备好编码或解码时,请调用 dequeueInputBuffer() 以获取 ByteBuffer 的索引位置(来自输入缓冲区数组),您应使用它来馈送源媒体。使用源媒体填充 ByteBuffer 后,通过调用 queueInputBuffer() 释放缓冲区的所有权。

同样,对于输出缓冲区,请调用 dequeueOutputBuffer() 以获取用于接收结果的 ByteBuffer 的索引位置。从 ByteBuffer 读取输出后,通过调用 releaseOutputBuffer() 释放所有权。

您可以结合使用 queueSecureInputBuffer()MediaCrypto API(而不是常规的 queueInputBuffer()),在编解码器中处理加密的媒体数据。

如需详细了解如何使用编解码器,请参阅 MediaCodec 文档。

提示时录制音频

新方法 startRecording() 可让您根据 MediaSyncEvent 定义的提示开始录音。MediaSyncEvent 会指定一个音频会话(例如由 MediaPlayer 定义的音频会话),完成后会触发录音器开始录制。例如,您可以使用此功能播放表示录音会话已开始的音频提示音,并且系统会自动开始录制,因此您无需手动同步提示音和开始录制。

定时文本轨道

MediaPlayer 现在可处理带内和带外文本轨道。带内文本轨道是 MP4 或 3GPP 媒体源中的文本轨道。可以通过 addTimedTextSource() 方法将带外文本轨道添加为外部文本源。添加完所有外部文本轨道源后,应调用 getTrackInfo() 以获取数据源中所有可用轨道的刷新列表。

如需设置与 MediaPlayer 搭配使用的轨道,您必须使用想要使用的轨道的索引位置来调用 selectTrack()

如需在文本轨道可以播放时收到通知,请实现 MediaPlayer.OnTimedTextListener 接口并将其传递给 setOnTimedTextListener()

音效

AudioEffect 类现在支持在捕获音频时使用其他音频预处理类型:

  • 具有 AcousticEchoCanceler 的回声消除器 (AEC) 可消除来自远程方的信号对捕获的音频信号的影响。
  • 使用 AutomaticGainControl 的自动增益控制 (AGC) 会自动将捕获的信号的输出归一化。
  • 具有 NoiseSuppressor 的噪音抑制器 (NS) 可从捕获的信号中移除背景噪声。

您可以使用 AudioEffect 子类之一,对使用 AudioRecord 捕获的音频应用这些预处理器效果。

注意:我们并不保证所有设备都支持这些效果,因此请务必先对相应的音效类调用 isAvailable() 来检查可用性。

无间断播放

您现在可以在两个单独的 MediaPlayer 对象之间执行无间断播放。在您的第一个 MediaPlayer 完成之前的任何时间,调用 setNextMediaPlayer(),Android 会在第一个播放器停止时尝试启动第二个播放器。

媒体路由器。新的 API MediaRouter、MediaRouteActionProvider 和 MediaRouteButton 提供用于选择媒体播放位置的标准机制和界面。

相机

自动对焦移动

通过新接口 Camera.AutoFocusMoveCallback,您可以监听对自动焦点移动的更改。您可以通过 setAutoFocusMoveCallback() 注册接口。然后,当相机处于连续自动对焦模式(FOCUS_MODE_CONTINUOUS_VIDEOFOCUS_MODE_CONTINUOUS_PICTURE)时,您将收到对 onAutoFocusMoving() 的调用,告知您自动对焦已经开始移动还是已停止移动。

相机提示音

MediaActionSound 类提供了一组简单的 API,用于生成由相机或其他媒体操作发出的标准声音。构建自定义静态或摄像机时,您应使用这些 API 播放适当的声音。

如需播放声音,只需实例化 MediaActionSound 对象,调用 load() 预加载所需的声音,然后在适当的时间调用 play() 即可。

畅连乐享

Android Beam

Android BeamTM 现在支持通过蓝牙传输大型载荷。当您使用新的 setBeamPushUris() 方法或新的回调接口 NfcAdapter.CreateBeamUrisCallback 定义要传输的数据时,Android 会将数据传输至蓝牙或其他替代传输方式,以实现更快的传输速度。这对于图像和音频文件等大型载荷特别有用,并且无需在设备之间进行可见配对。您的应用无需执行任何额外操作即可利用蓝牙传输功能。

setBeamPushUris() 方法接受 Uri 对象数组,这些对象指定您要从应用传输的数据。或者,您也可以实现 NfcAdapter.CreateBeamUrisCallback 接口,通过调用 setBeamPushUrisCallback() 为 activity 指定该接口。

使用回调接口时,系统会在用户通过 Android Beam 执行分享时调用该接口的 createBeamUris() 方法,以便您可以定义在分享时共享的 URI。如果要共享的 URI 可能因 activity 中的用户情境而异,则该方法非常有用;而当要共享的 URI 不变时,调用 setBeamPushUris() 很有用,您可以提前安全地定义它们。

网络服务发现

Android 4.1 增加了对基于多播 DNS 的服务发现的支持,可让您查找和连接到对等设备通过 Wi-Fi 提供的服务,例如移动设备、打印机、相机、媒体播放器等在本地网络上注册的服务。

新的软件包 android.net.nsd 包含新的 API,可让您在本地网络上广播服务、发现网络上的本地设备以及连接到设备。

如需注册服务,您必须先创建一个 NsdServiceInfo 对象,并通过 setServiceName()setServiceType()setPort() 等方法定义服务的各种属性。

然后,您需要实现 NsdManager.RegistrationListener,并使用 NsdServiceInfo 将其传递给 registerService()

如需发现网络上的服务,请实现 NsdManager.DiscoveryListener 并将其传递给 discoverServices()

当您的 NsdManager.DiscoveryListener 收到关于所找到服务的回调时,您需要通过调用 resolveService() 并向其传递 NsdManager.ResolveListener 的实现来解析该服务,该对象会收到包含所发现服务相关信息的 NsdServiceInfo 对象,从而使您能够发起连接。

WLAN 点对点服务发现

Wi-Fi 点对点 API 在 Android 4.1 中得到增强,以支持 WifiP2pManager 中的预关联服务发现。这样,您就可以在连接到某个现有设备之前,使用 Wi-Fi 点对点服务来发现和过滤附近的设备,而网络服务发现可让您在现有已连接网络(例如本地 Wi-Fi 网络)上发现服务。

如需通过 Wi-Fi 将应用作为服务进行广播,以便其他设备能够发现并连接到该应用,请使用描述应用服务的 WifiP2pServiceInfo 对象调用 addLocalService()

如需通过 Wi-Fi 启动发现附近的设备,您需要先决定是使用 Bonjour 还是使用 Upnp 进行通信。如需使用 Bonjour,请先使用 setDnsSdResponseListeners() 设置一些回调监听器,它接受 WifiP2pManager.DnsSdServiceResponseListenerWifiP2pManager.DnsSdTxtRecordListener。如需使用 Upnp,请调用接受 WifiP2pManager.UpnpServiceResponseListenersetUpnpServiceResponseListener()

您需要先调用 addServiceRequest(),然后才能开始在本地设备上发现服务。当您传递给此方法的 WifiP2pManager.ActionListener 收到成功回调后,您就可以通过调用 discoverServices() 开始在本地设备上发现服务。

发现本地服务时,您将收到对 WifiP2pManager.DnsSdServiceResponseListenerWifiP2pManager.UpnpServiceResponseListener 的回调,具体取决于您注册使用 Bonjour 还是 Upnp。在任一情况下收到的回调都包含表示对等设备的 WifiP2pDevice 对象。

网络用量

利用新方法 isActiveNetworkMetered(),您可以检查设备当前是否连接到按流量计费的网络。通过在执行密集型网络事务之前检查此状态,您可以帮助管理可能会产生用户费用的流量消耗,并就是立即还是稍后执行事务(例如,当设备连接到 Wi-Fi 时)做出明智的决策。

无障碍功能

无障碍服务 API

在 Android 4.1 中,无障碍服务 API 的覆盖范围已显著增加。现在,通过向 AccessibilityEventAccessibilityNodeInfoAccessibilityRecord 类添加内容,您还可以构建用于监控和响应更多输入事件的服务,例如使用 onGesture() 的复杂手势以及其他输入事件。

无障碍服务还可以代表用户执行操作,包括使用 performActionsetMovementGranularities 执行点击、滚动和单步调试文本。performGlobalAction() 方法还允许服务执行“返回”“主屏幕”以及打开“最近用过的应用和通知”等操作。

可自定义的应用导航

构建 Android 应用时,您现在可以自定义导航架构,方法是使用 findFocus()focusSearch() 查找可聚焦的元素和输入 widget,并使用 setAccessibilityFocused() 设置焦点。

更方便的微件

借助新的 android.view.accessibility.AccessibilityNodeProvider 类,您可以向无障碍服务呈现复杂的自定义视图,以便它们能够以更无障碍的方式呈现信息。android.view.accessibility.AccessibilityNodeProvider 允许具有高级内容(例如日历网格)的用户 widget 为无障碍服务呈现逻辑语义结构,该逻辑结构完全独立于 widget 的布局结构。这种语义结构使无障碍服务能够为视障用户提供更实用的互动模型。

复制和粘贴

使用 intent 复制和粘贴

您现在可以使用 setClipData() 方法将 ClipData 对象与 Intent 相关联。在使用 intent 将多个 content: URI 传输给其他应用时(例如共享多个文档时),这种方法特别有用。以这种方式提供的 content: URI 也将遵循 intent 的标志,以提供读取或写入权限,从而允许您授予对 intent 中的多个 URI 的访问权限。启动 ACTION_SENDACTION_SEND_MULTIPLE intent 时,intent 中提供的 URI 现在会自动传播到 ClipData,以便接收者可以向它们授予访问权限。

支持 HTML 和字符串样式

ClipData 类现在支持带样式的文本(作为 HTML 或 Android 样式化字符串)。您可以使用 newHtmlText()ClipData 添加 HTML 样式的文本。

Renderscript

Renderscript 计算功能通过以下功能得到增强:

  • 支持在一个脚本中包含多个内核。
  • 在新脚本 API rsSample 中,支持使用经过过滤的采样器从分配中读取数据。
  • #pragma 中支持不同级别的 FP 精度。
  • 支持通过计算脚本从 RS 对象查询其他信息。
  • 多项性能改进。

您还可以使用新的 pragma 来定义计算 RenderScript 所需的浮点数精度。这样,您就可以启用类似于 NEON 的运算(例如 CPU 路径上的快速矢量数学运算),这是使用完整 IEEE 754-2008 标准无法实现的。

注意:实验性 Renderscript 图形引擎现已弃用,

动画

activity 启动动画

您现在可以使用缩放动画或您自己的自定义动画启动 Activity。如需指定所需的动画,请使用 ActivityOptions API 构建 Bundle,然后您可以将其传递给启动 activity 的任何方法,例如 startActivity()

对于您可能希望在 activity 打开时显示的每种动画类型,ActivityOptions 类包含一个不同的方法:

makeScaleUpAnimation()
创建一个动画,将 activity 窗口从屏幕上的指定开始位置和指定的起始大小放大。例如,Android 4.1 中的主屏幕在打开应用时会使用此属性。
makeThumbnailScaleUpAnimation()
创建一个动画,从指定位置和提供的缩略图开始将 activity 窗口放大。例如,Android 4.1 中的“最近用过的应用”窗口在返回应用时便使用此窗口。
makeCustomAnimation()
创建由您自己的资源定义的动画:一个用于定义 Activity 打开的动画,另一个用于定义 Activity 的动画。

时间动画师

新的 TimeAnimator 通过 TimeAnimator.TimeListener 提供了一种简单的回调机制,该机制会在动画出现每一帧时通知您。此 Animator 无需设置时长、插值或对象值。监听器的回调会接收每一帧的信息,包括总时间和自上一个动画帧以来经过的时间。

界面

通知

在 Android 4.1 中,您可以创建具有更大内容区域、大图片预览、多个操作按钮和可配置的优先级的通知。

通知样式

新方法 setStyle() 允许您为通知指定三种新样式中的一种,以说明每种样式都会提供更大的内容区域。如需为大型内容区域指定样式,请传递以下对象之一 setStyle()

Notification.BigPictureStyle
对于包含大图片附件的通知。
Notification.BigTextStyle
适用于包含大量文字的通知,例如一封电子邮件。
Notification.InboxStyle
适用于包含字符串列表的通知,例如多封电子邮件的摘要。
通知操作

现在支持在通知消息底部显示最多两个操作按钮,无论通知使用的是普通样式还是更大的样式。

如需添加操作按钮,请调用 addAction()。此方法采用三个参数:图标的可绘制资源、按钮的文本,以及用于定义要执行的操作的 PendingIntent

优先级

您现在可以将优先级设置为 setPriority(),以提示系统通知对通知在列表中的顺序有多重要。您可以从 Notification 类中的 PRIORITY_* 常量定义的五种不同优先级中选择一种,从而向此传递此优先级。默认值为 PRIORITY_DEFAULT,有高两个级别,低两个级别。

高优先级通知是用户通常希望快速响应的内容,例如新的即时通讯、短信或即将到来的活动提醒。低优先级通知是指已过期的日历活动或应用促销等通知。

系统界面控件

Android 4.0 (Ice Cream Sandwich) 添加了新标志来控制系统界面元素的可见性,例如调暗系统栏的外观或使其在手机上完全消失。Android 4.1 添加了另外几个标志,可让您通过调用 setSystemUiVisibility() 并传递以下标志,进一步控制系统界面元素的外观以及与其相关的 activity 布局:

SYSTEM_UI_FLAG_FULLSCREEN
隐藏非关键系统界面(例如状态栏)。 如果 activity 在叠加模式下使用操作栏(通过启用 android:windowActionBarOverlay),则该标志还会隐藏操作栏,并在隐藏和显示操作栏时通过协调动画执行此操作。
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
将 activity 布局设置为使用已启用 SYSTEM_UI_FLAG_FULLSCREEN 后可用的同一屏幕区域,即使系统界面元素仍然可见也是如此。虽然系统界面将叠加部分布局,但如果您的应用经常使用 SYSTEM_UI_FLAG_FULLSCREEN 隐藏和显示系统界面,这会很有用,因为它可以避免每次系统界面隐藏或显示时,布局都会调整到新的布局边界。
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
将 activity 布局设置为使用已启用 SYSTEM_UI_FLAG_HIDE_NAVIGATION(在 Android 4.0 中添加)后可用的屏幕区域,即使系统界面元素仍然可见。尽管导航栏的某些部分将叠加在导航栏上,但如果应用经常使用 SYSTEM_UI_FLAG_HIDE_NAVIGATION 隐藏和显示导航栏,这会很有用,因为这可以避免导航栏在每次隐藏或显示时都根据新的布局边界调整布局。
SYSTEM_UI_FLAG_LAYOUT_STABLE
如果您使用的是 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 和/或 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,则可能需要添加此标志,以确保对视图调用 fitSystemWindows() 时,定义的边界相对于可用屏幕空间而言保持一致。 也就是说,设置此标志后,即使您隐藏所有系统界面,fitSystemWindows() 也会假定系统界面元素的可见性保持不变。

如需了解有关其他相关系统界面标志的详细讨论,请参阅 Android 4.0 中添加的标志。

远程视图

GridLayoutViewStub 现在是远程视图,因此您可以在应用微件和通知自定义布局的布局中使用它们。

字体系列

Android 4.1 又添加了几个 Roboto 字体样式变体,总共 10 个变体,并且这些变体可供应用使用。现在,您的应用可以访问所有浅色变体和浓缩变体。

可用的整套 Roboto 字体变体为:

  • 常规
  • 斜体
  • 粗体
  • 粗斜体
  • 浅色
  • 浅斜体
  • 精简常规
  • 浓缩斜体
  • 浓缩粗体
  • 浓缩粗体斜体

您可以将新的 fontFamily 属性与 textStyle 属性结合使用,以应用上述任何一种属性。

支持的 fontFamily 值包括:

  • "sans-serif"(适用于常规 Roboto)
  • "sans-serif-light"(适用于 Roboto Light)
  • "sans-serif-condensed"(适用于 Roboto Condensed)

然后,您可以使用 textStyle"bold""italic" 应用粗体和/或斜体。您可以按如下方式应用这两者:android:textStyle="bold|italic"

您也可以使用 Typeface.create()。例如 Typeface.create("sans-serif-light", Typeface.NORMAL)

输入框架

多种输入设备

新的 InputManager 类可让您查询当前连接的输入设备集,并注册在添加、更改或移除新设备时收到通知。如果您正在构建支持多玩家的游戏,并且希望检测连接的控制器数量以及控制器数量发生变化,这会特别有用。

您可以通过调用 getInputDeviceIds() 查询连接的所有输入设备。这将返回一个整数数组,其中每个整数都是不同输入设备的 ID。然后,您可以调用 getInputDevice() 以获取指定输入设备 ID 的 InputDevice

如果您想在新的输入设备连接、更改或断开连接时收到通知,请实现 InputManager.InputDeviceListener 接口并向 registerInputDeviceListener() 注册该接口。

输入控制器振动

如果连接的输入设备有自己的振动功能,您现在可以使用现有的 Vibrator API 来控制这些设备的振动,只需在 InputDevice 上调用 getVibrator() 即可。

权限

以下是新权限:

READ_EXTERNAL_STORAGE
提供对外部存储空间的受保护读取权限。在 Android 4.1 中,所有应用在默认情况下仍具有读取权限。这将在未来版本中进行更改,以要求应用使用此权限明确请求读取权限。如果您的应用已请求写入权限,它也会自动获得读取权限。我们推出了一个新的开发者选项,用于开启读取访问权限限制,以便开发者根据 Android 未来的行为方式测试其应用。
android.Manifest.permission.READ_USER_DICTIONARY
允许应用读取用户字典。应只有 IME 或字典编辑器(如“设置”应用)需要此访问权限。
READ_CALL_LOG
允许应用读取系统的通话记录(其中包含有关来电和去电的信息)。
WRITE_CALL_LOG
允许应用修改存储在您手机上的系统通话记录
android.Manifest.permission.WRITE_USER_DICTIONARY
允许应用对用户的字词字典执行写入操作。

设备功能

Android 4.1 针对专用于在电视屏幕上显示界面的设备添加了一项新的功能声明:FEATURE_TELEVISION。如需声明您的应用需要电视接口,请在清单文件中使用 <uses-feature> 元素声明此功能:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

此功能将“电视”定义为一种典型的客厅电视体验:显示在大屏幕上,用户坐在远处,主流输入形式是类似方向键的设备,通常不会通过触摸或鼠标/指控设备进行输入。