Android 4.1 API

API 级别:16

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

作为应用开发者,您可以从 SDK 管理器以系统映像的形式获得 Android 4.1,以便在 Android 模拟器中运行,并利用 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 互动,这会非常有用。

动态壁纸

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

如需启动动态壁纸选择器,请使用 ACTION_CHANGE_LIVE_WALLPAPER 调用 startActivity(),并传入 IntentEXTRA_LIVE_WALLPAPER_COMPONENT(以字符串形式指定动态壁纸 ComponentName 的 extra)。

应用堆栈导航

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 一样显示正确的列表。如需将此类信息传递给合成父 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(),但只需向每个 <activity> 元素添加 android:parentActivityName 即可实现正确的行为。

多媒体

媒体编解码器

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,这些 API 可让您在本地网络中广播服务、发现网络上的本地设备以及连接到设备。

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

然后,您需要实现 NsdManager.RegistrationListener 并将其与您的 NsdServiceInfo 一起传递给 registerService()

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

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

Wi-Fi 点对点服务发现

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

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

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

您还需要调用 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,高 2 级,低 2 级。

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

系统界面控件

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>

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