🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
原文API级别:16 Android 4.1([JELLY_BEAN](https://developer.android.com/reference/android/os/Build.VERSION_CODES.html#JELLY_BEAN))是一个平台的进步,提供了改进的性能和增强的用户体验。它为用户和应用程序开发人员增加了新功能。本文档为应用程序开发人员介绍了最值得注意和有用的新API。 > 声明您的应用程序API级别 > 为了更好地为运行Android 4.1的设备优化您的应用程序,您应该设置[targetSdkVersion](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target)为 "16",将其安装在Android 4.1系统映像上,对其进行测试,然后使用此更改发布更新。 > 您可以在Android 4.1中使用API,同时还可以通过在代码中添加条件来检查系统API级别,然后执行不支持的API [minSdkVersion](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min)。要了解有关维护向后兼容性的更多信息,请阅读[创建向后兼容的UI](https://developer.android.com/training/backward-compatible-ui/index.html)。 > 关于API级别如何工作的更多信息可以在[什么是API级别](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)? 作为一名应用程序开发人员,您可以从[SDK Manager](https://developer.android.com/tools/help/sdk-manager.html)中获得Android 4.1 作为系统映像,您可以在Android模拟器和SDK平台上运行,以便构建您的应用程序。您应该尽快下载系统映像和平台,以在Android 4.1上构建和测试您的应用程序。 ### **应用组件** #### **隔离的服务** 通过[android:isolatedProcess="true"](https://developer.android.com/guide/topics/manifest/service-element.html#isolated)在 [`<service>`](https://developer.android.com/guide/topics/manifest/service-element.html)标签中指定,您[Service](https://developer.android.com/reference/android/app/Service.html)将在自己的独立用户标识进程下运行,而不需要自己的权限。 #### **内存管理** 在系统调用之前,新的[ComponentCallbacks2](https://developer.android.com/reference/android/content/ComponentCallbacks2.html)常量例如[TRIM_MEMORY_RUNNING_LOW](https://developer.android.com/reference/android/content/ComponentCallbacks2.html#TRIM_MEMORY_RUNNING_LOW)和[TRIM_MEMORY_RUNNING_CRITICAL](https://developer.android.com/reference/android/content/ComponentCallbacks2.html#TRIM_MEMORY_RUNNING_CRITICAL)提供前台处理更多关于内存状态的信息[onLowMemory()](https://developer.android.com/reference/android/app/Activity.html#onLowMemory())。 新的[getMyMemoryState(ActivityManager.RunningAppProcessInfo)](https://developer.android.com/reference/android/app/ActivityManager.html#getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo))方法允许你检索一般的内存状态。 #### **内容提供者** 一种新的方法,[acquireUnstableContentProviderClient()](https://developer.android.com/reference/android/content/ContentResolver.html#acquireUnstableContentProviderClient(android.net.Uri))允许你访问一个[ContentProviderClient](https://developer.android.com/reference/android/content/ContentProviderClient.html)可能“不稳定”的东西,这样如果内容提供者这样做,你的应用就不会崩溃。当您在单独的应用程序中与内容提供者交互时,这非常有用。 #### **动态壁纸** 新的意向协议,直接启动动态壁纸预览活动,所以你可以帮助用户轻松地选择你的动态壁纸,而不强迫他们离开你的应用程序,并通过家庭壁纸选择器导航。 要启动动态壁纸选取器,请[startActivity()](https://developer.android.com/reference/android/content/Context.html#startActivity(android.content.Intent))使用一个[Intent](https://developer.android.com/reference/android/content/Intent.html)使用 [ACTION_CHANGE_LIVE_WALLPAPER](https://developer.android.com/reference/android/app/WallpaperManager.html#ACTION_CHANGE_LIVE_WALLPAPER)和一个额外的指定您的动态壁纸[ComponentName](https://developer.android.com/reference/android/content/ComponentName.html)作为一个字符串[EXTRA_LIVE_WALLPAPER_COMPONENT](https://developer.android.com/reference/android/app/WallpaperManager.html#EXTRA_LIVE_WALLPAPER_COMPONENT)。 #### **应用程序堆栈导航** Android 4.1使得为Up导航实现适当的设计模式变得更加容易。所有你需要做的就是添加[android:parentActivityName](https://developer.android.com/guide/topics/manifest/activity-element.html#parent)到[`<activity>`](https://developer.android.com/guide/topics/manifest/activity-element.html)清单文件中的每个元素。系统使用此信息在用户按下操作栏中的“上”按钮(同时也结束当前活动)时打开相应的活动。因此,如果您android:parentActivityName为每个活动声明,则不需要该[onOptionsItemSelected()](https://developer.android.com/reference/android/app/Activity.html#onOptionsItemSelected(android.view.MenuItem))方法来处理操作栏的应用程序图标上的点击事件 - 系统现在处理该事件并恢复或创建适当的活动。 对于用户通过“深潜”意图(例如来自不同应用程序的通知或意图(如在应用程序间[导航](https://developer.android.com/design/patterns/navigation.html#between-apps)的设计指南中所述))输入您的应用程序活动之一的场景,这尤其强大。当用户以这种方式输入活动时,您的应用程序可能不会自然而然地拥有一堆可以在用户导航时恢复的活动。但是,当您[android:parentActivityName](https://developer.android.com/guide/topics/manifest/activity-element.html#parent)为活动提供属性时,系统会识别您的应用程序是否已经包含父活动的后退堆栈,如果没有,则会构造一个包含所有父活动的合成后退堆栈。 > **注意**:当用户在您的应用程序中输入一个深度活动,并为您的应用程序创建一个新任务时,系统实际上会将该父活动堆栈插入到该任务中。因此,按“后退”按钮也可以浏览父活动的堆栈。 当系统为您的应用程序创建一个合成后台堆栈时,它会构建一个基本的 [Intent](https://developer.android.com/reference/android/content/Intent.html)创建每个父级活动的新实例。所以没有保存的父活动的状态,你希望用户自然浏览每个活动的方式。如果任何父活动通常显示取决于用户上下文的UI,那么该上下文信息将会丢失,并且当用户浏览堆栈时应该将其传递。例如,如果用户正在查看音乐应用程序中的专辑,则向上导航可能会将其带到列出所选音乐流派中的所有专辑的活动。在这种情况下,如果必须创建堆栈,则必须通知父活动当前相册属于哪种类型,以便父级可以显示正确的列表,就好像用户实际上来自该活动一样。为了将这些信息传递给合成的家长活动,[onPrepareNavigateUpTaskStack()](https://developer.android.com/reference/android/app/Activity.html#onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder))方法。这为您提供了[TaskStackBuilder](https://developer.android.com/reference/android/app/TaskStackBuilder.html)系统创建的对象,以便合成父级活动。该[TaskStackBuilder](https://developer.android.com/reference/android/app/TaskStackBuilder.html)包含[Intent](https://developer.android.com/reference/android/content/Intent.html)系统用来创建每个父活动的对象。在你的实现中[onPrepareNavigateUpTaskStack()](https://developer.android.com/reference/android/app/Activity.html#onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)),你可以修改适当[Intent](https://developer.android.com/reference/android/content/Intent.html)的添加额外的数据,父活动可以用来确定适当的上下文,并显示适当的用户界面。 当系统创建该对象时[TaskStackBuilder](https://developer.android.com/reference/android/app/TaskStackBuilder.html),它会[Intent](https://developer.android.com/reference/android/content/Intent.html)按照从活动树顶部开始的逻辑顺序添加用于创建父活动的对象。所以,最后一个Intent添加到内部数组是当前活动的直接父项。如果要修改[Intent](https://developer.android.com/reference/android/content/Intent.html)活动的父项,请首先确定数组的长度,[getIntentCount()](https://developer.android.com/reference/android/content/Intent.html)然后将该值传递给[editIntentAt()](https://developer.android.com/reference/android/app/TaskStackBuilder.html#editIntentAt(int))。 如果您的应用程序结构更为复杂,则还有其他几个可用的API可用来处理Up导航的行为,并完全自定义合成背堆栈。一些给你额外控制的API包括: * [onNavigateUp()](https://developer.android.com/reference/android/app/Activity.html#onNavigateUp()) 当用户按下“上”按钮时,覆盖此操作以执行自定义操作。 * [navigateUpTo(Intent)](https://developer.android.com/reference/android/app/Activity.html#navigateUpTo(android.content.Intent)) 调用它来完成当前的活动并转到提供的活动Intent。如果活动存在于后退堆栈中,但不是最接近的父活动,则当前活动与意图指定的活动之间的所有其他活动也将完成。 * [getParentActivityIntent()](https://developer.android.com/reference/android/app/Activity.html#getParentActivityIntent()) 调用这个来获得Intent那个会启动当前活动的逻辑父项。 * [shouldUpRecreateTask(Intent)](https://developer.android.com/reference/android/app/Activity.html#shouldUpRecreateTask(android.content.Intent)) 调用此参数来查询是否必须创建合成背堆栈以便向上导航。如果必须创建合成堆栈,则返回true;如果合适的堆栈已经存在,则返回false。 * [finishAffinity()](https://developer.android.com/reference/android/app/Activity.html#finishAffinity()) 调用此方法来完成当前活动以及与当前活动链接的具有相同任务关系的所有父活动。如果您覆盖默认行为(如,) [onNavigateUp()](https://developer.android.com/reference/android/app/Activity.html#onNavigateUp()),则应在上导航中创建合成背堆栈时调用此方法。 * [onCreateNavigateUpTaskStack](https://developer.android.com/reference/android/app/Activity.html#onCreateNavigateUpTaskStack(android.app.TaskStackBuilder)) 如果需要完全控制如何创建综合任务堆栈,则覆盖此选项。如果你只是想添加一些额外的数据到你的后台堆栈的意图,你应该改写[onPrepareNavigateUpTaskStack()](https://developer.android.com/reference/android/app/Activity.html#onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)) 但是,大多数应用程序不需要使用这些API或实现[onPrepareNavigateUpTaskStack()](https://developer.android.com/reference/android/app/Activity.html#onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)),但可以简单地通过添加[android:parentActivityName](https://developer.android.com/guide/topics/manifest/activity-element.html#parent)到每个[`<activity>`](https://developer.android.com/guide/topics/manifest/activity-element.html)元素来实现正确的行为。 ### **多媒体** #### **媒体编解码器** 该[MediaCodec](https://developer.android.com/reference/android/media/MediaCodec.html)课程提供对低级媒体编解码器的访问,以对媒体进行编码和解码。您可以MediaCodec通过调用[createEncoderByType()](https://developer.android.com/reference/android/media/MediaCodec.html#createEncoderByType(java.lang.String))编码媒体或调用[createDecoderByType()](https://developer.android.com/reference/android/media/MediaCodec.html#createDecoderByType(java.lang.String))解码媒体来实例化一个媒体。这些方法中的每一个对于要编码或解码的媒体类型都采用MIME类型,例如"video/3gpp"或"audio/vorbis"。 通过[MediaCodec](https://developer.android.com/reference/android/media/MediaCodec.html)创建的实例,可以调用configure()指定媒体格式或内容是否加密等属性。 无论是对媒体进行编码还是解码,创建完成后其余的过程都是一样的[MediaCodec](https://developer.android.com/reference/android/media/MediaCodec.html)。首先调用[getInputBuffers](https://developer.android.com/reference/android/media/MediaCodec.html#getInputBuffers())()获取输入ByteBuffer 对象数组并[getOutputBuffers()](https://developer.android.com/reference/android/media/MediaCodec.html#getOutputBuffers())获取输出[ByteBuffer](https://developer.android.com/reference/java/nio/ByteBuffer.html)对象数组。 准备编码或解码时,请调用[dequeueInputBuffer()](https://developer.android.com/reference/android/media/MediaCodec.html#dequeueInputBuffer(long))以获取[ByteBuffer](https://developer.android.com/reference/java/nio/ByteBuffer.html)(应该使用输入缓冲区数组)的索引位置,以便在源媒体中进行输入。在填充[ByteBuffer](https://developer.android.com/reference/java/nio/ByteBuffer.html)源媒体之后,通过调用释放缓冲区的所有权[queueInputBuffer()](https://developer.android.com/reference/android/media/MediaCodec.html#queueInputBuffer(int, int, int, long, int))。 同样,对于输出缓冲区,请调用dequeueOutputBuffer()以获取[ByteBuffer](https://developer.android.com/reference/java/nio/ByteBuffer.html) 您将收到结果的位置的索引位置。读完输出后ByteBuffer,通过调用释放所有权releaseOutputBuffer()。 你可以通过调用处理在编解码器加密的媒体数据queueSecureInputBuffer()与结合[MediaCrypto](https://developer.android.com/reference/android/media/MediaCrypto.html)的API,而不是正常,queueInputBuffer()。 有关如何使用编解码器的更多信息,请参阅MediaCodec文档。 #### **在提示上录制音频** 新的方法[startRecording()](https://developer.android.com/reference/android/media/AudioRecord.html#startRecording())可以让你开始音频记录基于一个定义的提示[MediaSyncEvent](https://developer.android.com/reference/android/media/MediaSyncEvent.html)。所述MediaSyncEvent指定的音频会议(由诸如一项所定义[MediaPlayer](https://developer.android.com/reference/android/media/MediaPlayer.html)),其中,当完成时,触发音频记录开始记录。例如,您可以使用此功能来播放指示录制会话开始的音频音调,录音自动开始,因此您不必手动同步音调和开始录音。 #### **定时文本轨道** 在MediaPlayer无论是在带内和带外文本轨道现在处理。带内文本轨道在MP4或3GPP媒体源中成为文本轨道。可以通过addTimedTextSource()方法将带外文本轨道添加为外部文本源。在添加了所有外部文本轨道源之后,[getTrackInfo()](https://developer.android.com/reference/android/media/MediaPlayer.html#getTrackInfo())应该调用以获取数据源中所有可用轨道的刷新列表。 要设置要使用的音轨MediaPlayer,必须[selectTrack()](https://developer.android.com/reference/android/media/MediaPlayer.html#selectTrack(int))使用要使用的音轨的索引位置进行调用。 要在文本轨道准备播放时收到通知,请执行该 [MediaPlayer.OnTimedTextListener](https://developer.android.com/reference/android/media/MediaPlayer.OnTimedTextListener.html)界面并将其传递给setOnTimedTextListener()。 #### **音频效果** 在[AudioEffect](https://developer.android.com/reference/android/media/audiofx/AudioEffect.html)类现在支持捕获音频时附加的音频预处理类型: * 声学回声[AcousticEchoCanceler](https://developer.android.com/reference/android/media/audiofx/AcousticEchoCanceler.html) 消除器(AEC)从所捕获的音频信号中消除从对方接收到的信号的贡献。 * 自动增益控制(AGC)[AutomaticGainControl](https://developer.android.com/reference/android/media/audiofx/AutomaticGainControl.html) 自动标准化捕获信号的输出。 * 噪声抑制器(NS)可[NoiseSuppressor](https://developer.android.com/reference/android/media/audiofx/NoiseSuppressor.html) 消除捕获信号中的背景噪声。 您可以将这些预处理器效果应用于[AudioRecord](https://developer.android.com/reference/android/media/AudioRecord.html)使用其中一个[AudioEffect](https://developer.android.com/reference/android/media/audiofx/AudioEffect.html) 子类捕获的音频。 > 注意:不能保证所有设备都支持这些效果,所以您应该首先通过调用[isAvailable()](https://developer.android.com/reference/android/media/audiofx/AcousticEchoCanceler.html#isAvailable())相应的音频效果类来检查可用性。 #### **无缝播放** 您现在可以在两个单独的[MediaPlayer](https://developer.android.com/reference/android/media/MediaPlayer.html)对象之间执行无间隙回放 。在第一次MediaPlayer结束之前的任何时候,通话setNextMediaPlayer()和Android都会在第一个玩家停止的时候尝试启动第二个玩家。 媒体路由器。新的API MediaRouter,MediaRouteActionProvider和MediaRouteButton提供了标准的机制和UI来选择播放媒体的位置。 ### **相机** #### **自动对焦运动** 新的界面[Camera.AutoFocusMoveCallback](https://developer.android.com/reference/android/hardware/Camera.AutoFocusMoveCallback.html)允许您听取自动对焦运动的变化。你可以注册你的界面setAutoFocusMoveCallback()。然后,当相机处于连续自动对焦模式([FOCUS_MODE_CONTINUOUS_VIDEO](https://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_VIDEO)或 [FOCUS_MODE_CONTINUOUS_PICTURE](https://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_PICTURE))时,您将收到一个呼叫onAutoFocusMoving(),告诉您自动对焦是开始移动还是停止移动。 相机的声音 该[MediaActionSound](https://developer.android.com/reference/android/media/MediaActionSound.html)课程提供了一套简单的API来生成相机或其他媒体操作所产生的标准声音。您应该使用这些API在构建自定义静态摄像机或摄像机时播放适当的声音。 要播放声音,只需实例化一个MediaActionSound对象,调用 [load()](https://developer.android.com/reference/android/media/MediaActionSound.html#load(int))预加载所需的声音,然后在适当的时候调用[play()](https://developer.android.com/reference/android/media/MediaActionSound.html#play(int))。 ### **连接** #### **Android Beam** Android Beam™现在支持通过蓝牙进行大量有效载荷传输。当您使用新setBeamPushUris() 方法或新回调界面定义要传输的数据时[NfcAdapter.CreateBeamUrisCallback](https://developer.android.com/reference/android/nfc/NfcAdapter.CreateBeamUrisCallback.html),Android会将数据传输转移到蓝牙或其他备用传输,以实现更快的传输速度。这对于诸如图像和音频文件之类的大型有效载荷特别有用,并且不需要设备之间的可见配对。您的应用不需要额外的工作来利用蓝牙传输。 该setBeamPushUris()方法需要一个[Uri](https://developer.android.com/reference/android/net/Uri.html)对象数组 ,指定要从应用程序传输的数据。或者,您可以实现NfcAdapter.CreateBeamUrisCallback 可以通过调用为您的活动指定的界面setBeamPushUrisCallback()。 当使用回调接口时,[createBeamUris()](https://developer.android.com/reference/android/nfc/NfcAdapter.CreateBeamUrisCallback.html#createBeamUris(android.nfc.NfcEvent))当用户使用Android Beam执行共享时,系统会调用接口的方法,以便您可以定义在共享时共享的URI。如果要共享的URI取决于活动中的用户上下文,则setBeamPushUris()这非常有用,而当要共享的URI不变时,调用会很有用,您可以提前安全地定义它们。 #### **网络服务发现** Android 4.1增加了对组播基于DNS的服务发现的支持,允许您通过Wi-Fi查找并连接到对等设备提供的服务,例如移动设备,打印机,相机,媒体播放器以及其他本地注册的服务网络。 新的软件包[android.net.nsd](https://developer.android.com/reference/android/net/nsd/package-summary.html)包含新的API,允许您在本地网络上广播您的服务,发现网络上的本地设备,并连接到设备。 要注册你的服务,你必须先创建一个[NsdServiceInfo](https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html) 对象,并使用方法,如定义服务的各种属性 [setServiceName()](https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html#setServiceName(java.lang.String)), [setServiceType()](https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html#setServiceType(java.lang.String))和 [setPort()](https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html#setPort(int))。 那么你需要实现[NsdManager.RegistrationListener](https://developer.android.com/reference/android/net/nsd/NsdManager.RegistrationListener.html) 并传递给registerService() 你的[NsdServiceInfo](https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html)。 发现网络上的服务,实现[NsdManager.DiscoveryListener](https://developer.android.com/reference/android/net/nsd/NsdManager.DiscoveryListener.html)并传递给它discoverServices()。 当您[NsdManager.DiscoveryListener](https://developer.android.com/reference/android/net/nsd/NsdManager.DiscoveryListener.html)收到有关找到的服务的回调时,您需要通过调用来解析该服务 resolveService(),并将其传递给[NsdManager.ResolveListener](https://developer.android.com/reference/android/net/nsd/NsdManager.ResolveListener.html)接收[NsdServiceInfo](https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html)包含有关发现的服务的信息的对象的实现,从而允许您启动连接。 #### **Wi-Fi P2P服务发现** 在Android 4.1中增强了Wi-Fi P2P API,以支持预关联服务发现WifiP2pManager。这允许您在连接到服务之前使用Wi-Fi P2P发现并过滤附近的设备,而网络服务发现则允许您在现有连接的网络(例如本地Wi-Fi网络)上发现服务。 要通过Wi-Fi将应用程序作为服务广播,以便其他设备可以发现您的应用程序并连接到该应用程序,请addLocalService()使用WifiP2pServiceInfo描述应用程序服务的 对象进行调用。 要通过Wi-Fi发现附近的设备,您需要先决定是否使用Bonjour或Upnp进行通信。要使用Bonjour,首先设置一些回调监听器 setDnsSdResponseListeners(),同时使用a WifiP2pManager.DnsSdServiceResponseListener和WifiP2pManager.DnsSdTxtRecordListener。要使用Upnp,请使用 setUpnpServiceResponseListener()一个WifiP2pManager.UpnpServiceResponseListener。 在您开始在本地设备上发现服务之前,您还需要致电addServiceRequest()。当WifiP2pManager.ActionListener你通过这个方法接收到一个成功的回调,你就可以开始通过调用在本地设备上发现服务discoverServices()。 当发现本地服务时,您会收到WifiP2pManager.DnsSdServiceResponseListeneror 的回WifiP2pManager.UpnpServiceResponseListener叫,具体取决于您是否注册使用Bonjour或Upnp。在任何情况下收到的回调都包含WifiP2pDevice代表对等设备的 对象。 #### **网络使用** 新方法isActiveNetworkMetered()允许您检查设备当前是否连接到一个测量网络。通过在执行密集的网络事务之前检查此状态,您可以帮助管理数据使用情况,这可能会使您的用户花费金钱,并就现在或以后是否执行交易(例如设备连接到Wi-Fi时)做出明智的决定。 ### **无障碍** #### **辅助功能服务API** 在Android 4.1中,辅助功能服务API的覆盖面已经显着增加。现在允许你建立监测服务和更多的输入事件,如使用复杂的手势做出反应onGesture(),通过增加的和其他输入事件AccessibilityEvent,AccessibilityNodeInfo以及AccessibilityRecord类。 辅助功能服务也可以代表用户执行操作,包括使用performAction和单击,滚动和逐步浏览文本setMovementGranularities。该performGlobalAction()方法还允许服务执行诸如“返回”,“主页”以及打开“最近使用的应用程序和通知”等操作。 #### **可定制的应用程序导航** 在构建Android应用程序时,您现在可以通过使用findFocus()和找到可聚焦的元素和输入小部件来自定义导航方案,并使用focusSearch()焦点setAccessibilityFocused()。 #### **更易于使用的小部件** 新android.view.accessibility.AccessibilityNodeProvider类允许您将复杂的自定义视图显示到可访问性服务,以便以更易于访问的方式呈现信息。在android.view.accessibility.AccessibilityNodeProvider允许用户与小部件的高级内容,诸如日历网格,以呈现一个逻辑语义结构的可访问的服务,是从微件的布局结构完全分离的。这种语义结构允许无障碍服务为视力受损的用户提供更有用的交互模式。 ### **复制和粘贴** #### **复制并粘贴意图** 现在可以将ClipData对象与Intent使用该setClipData()方法的对象关联起来。当使用意图将多个content:URI 传输到另一个应用程序(例如共享多个文档时)时,这是特别有用的。以content:这种方式提供的URI也将尊重意图的标志以提供读取或写入访问,允许您在意图中授予对多个URI的访问权限。当开始ACTION_SEND或ACTION_SEND_MULTIPLE意图时,意图中提供的URI现在自动传播到ClipData接收者可以授予访问权限。 #### **支持HTML和字符串样式** 在ClipData类现在支持样式文本(无论是作为HTML或Android 风格的字符串)。您可以HTML样式的文本添加到ClipData同newHtmlText()。 #### **的renderScript** Renderscript计算功能已增强,具有以下功能: * 在一个脚本内支持多个内核。 * 支持从新的脚本API中通过计算过滤采样器进行分配读取 rsSample。 * 支持不同级别的FP精度#pragma。 * 支持从计算脚本查询来自RS对象的附加信息。 * 许多性能改进。 新的pragmas也可以用来定义计算Renderscripts所需的浮点精度。这使您可以在CPU路径上启用NEON类似的操作,例如快速矢量数学运算,否则将无法使用完整的IEEE 754-2008标准。 > 注意:实验Renderscript图形引擎现在已被弃用。 ### **动画** #### **活动启动动画** 您现在可以启动Activity使用缩放动画或您自己的自定义动画。要指定所需的动画,请使用ActivityOptionsAPI构建一个Bundle可以传递给启动活动的任何方法的API ,例如startActivity()。 这个ActivityOptions类包含了一个不同的方法,你可以在活动打开时显示每种类型的动画: * makeScaleUpAnimation() 创建一个动画,从屏幕上的指定起始位置和指定的起始大小放大活动窗口。例如,Android 4.1中的主屏幕在打开应用程序时会使用此屏幕。 * makeThumbnailScaleUpAnimation() 创建一个从指定位置和提供的缩略图开始放大活动窗口的动画。例如,Android 4.1中的“最近的应用程序”窗口在返回到应用程序时使用此窗口。 * makeCustomAnimation() 创建一个由您自己的资源定义的动画:一个为活动开放定义动画,另一个为停止的活动定义动画。 #### **时间动画师** 新TimeAnimator提供了一个简单的回调机制TimeAnimator.TimeListener,通知你每一帧的动画。此动画制作器没有持续时间,插值或对象值设置。收听者的回叫接收每帧的信息,包括总经过时间和自上一个动画帧以来的经过时间。 ### **用户界面** #### **通知** 在Android 4.1中,您可以创建具有较大内容区域,大图像预览,多个操作按钮和可配置优先级的通知。 #### **通知样式** 新方法setStyle()允许您为通知指定三种新样式之一,每个样式都提供更大的内容区域。要为大型内容区域指定样式,请传递setStyle()以下对象之一: * Notification.BigPictureStyle 用于包含大图像附件的通知。 * Notification.BigTextStyle 对于包含大量文本的通知,例如单个电子邮件。 * Notification.InboxStyle 对于包含字符串列表的通知,例如来自多个电子邮件的摘录。 #### **通知行为** 现在,通知消息底部最多可以显示两个操作按钮,无论您的通知是使用常规还是较大的样式。 要添加一个操作按钮,请致电addAction()。这个方法有三个参数:一个图标的可绘制资源,一个按钮的文本,以及一个PendingIntent将action定义为perfrom的函数。 #### **优先级** 您现在可以通过设置优先级来向系统提示您的通知对通知在列表中的排序有多重要setPriority()。你可以在类中传递由PRIORITY_*常量定义的五个不同优先级中的一个Notification。默认是PRIORITY_DEFAULT,有两个级别,两个级别较低。 高优先级通知是用户通常希望快速响应的事件,例如新的即时消息,文本消息或即将发生的事件提醒。低优先级通知就是过期的日历活动或应用促销活动。 #### **系统用户界面的控件** Android 4.0(冰淇淋三明治)添加了新的标志来控制系统UI元素的可见性,例如调暗系统栏的外观或使其在手机上完全消失。Android 4.1增加了一些标志,通过调用setSystemUiVisibility() 和传递下列标志,可以进一步控制系统UI元素的外观以及与之相关的活动布局: * SYSTEM_UI_FLAG_FULLSCREEN 隐藏非关键系统UI(如状态栏)。如果你的活动在叠加模式中使用了动作条(通过启用android:windowActionBarOverlay),那么这个标志也隐藏了动作条,并且在隐藏和显示两者的情况下用协调的动画来执行。 * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 将活动布局设置为使用与启用时相同的屏幕区域,SYSTEM_UI_FLAG_FULLSCREEN即使系统UI元素仍可见。虽然部分布局将被系统UI覆盖,但是如果您的应用程序经常隐藏并显示系统UI,则此部分很有用 SYSTEM_UI_FLAG_FULLSCREEN,因为每次系统UI隐藏或显示时都会避免将布局调整为新的布局边界。 * SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION SYSTEM_UI_FLAG_HIDE_NAVIGATION即使系统UI元素仍然可见,请将活动布局设置为使用启用(在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()即使隐藏了所有系统UI,系统UI元素的可见性仍然保持不变。 有关其他相关系统UI标志的更多讨论,请阅读Android 4.0中添加的相关内容。 #### **远程视图** GridLayout而ViewStub 现在远程的意见,所以你可以在布局中使用他们为你的应用程序部件和通知自定义布局。 #### **字体家族** Android 4.1增加了Roboto字体样式的多个变体,共有10个变体,而且它们都可以被应用程序使用。您的应用程序现在可以访问全套轻量级和浓缩型变体。 Roboto字体变体的完整集合是: * 定期 * 斜体 * 胆大 * 加粗斜体 * 光 * 光斜体 * 浓缩正规 * 浓缩斜体 * 粗体粗体 * 浓缩的粗体 - 斜体 您可以将这些新fontFamily 属性中的任何一个与属性结合使用textStyle。 支持的值fontFamily是: * "sans-serif" 对于经常Roboto * "sans-serif-light" 为Roboto光 * "sans-serif-condensed" 为Roboto压缩 然后,您可以应用粗体和/或倾斜的textStyle值 "bold"和"italic"。你可以这样应用:android:textStyle="bold|italic"。 你也可以使用Typeface.create()。例如Typeface.create("sans-serif-light", Typeface.NORMAL)。 ### **输入框架** #### **多个输入设备** 新InputManager类允许您查询当前连接的输入设备集,并在添加,更改或删除新设备时通知注册。如果您正在构建支持多个玩家的游戏,并且想要检测连接的控制器的数量以及控制器的数量发生了什么变化,这一点尤其有用。 您可以查询通过呼叫连接的所有输入设备 getInputDeviceIds()。这将返回一个整数数组,每个整数都是不同输入设备的ID。然后可以调用 getInputDevice()获取InputDevice指定的输入设备ID。 如果您希望在新的输入设备连接,更改或断开连接时得到通知,请执行该InputManager.InputDeviceListener界面并注册registerInputDeviceListener()。 #### **振动输入控制器** 如果连接的输入设备有自己的振动功能,现在可以控制使用现有的这些设备的振动Vibrator简单地通过调用的API getVibrator()上InputDevice。 #### **权限** 以下是新的权限: * 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](https://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_TELEVISION)。要声明您的应用程序需要电视界面,请在清单文件中使用以下[<uses-feature>](https://developer.android.com/guide/topics/manifest/uses-feature-element.html)元素声明此功能: ~~~ <manifest ... > <uses-feature android:name="android.hardware.type.television" android:required="true" /> ... </manifest> ~~~ 该特征将“电视”定义为典型的起居室电视体验:显示在大屏幕上,用户坐在很远的地方,输入的主要形式是类似d-pad的东西,而且通常不是通过触摸或鼠标/指示器装置。