企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
API级别:17 Android 4.2(JELLY_BEAN_MR1)是Jelly Bean版本的更新,为用户和应用程序开发人员提供了新功能。本文档向开发人员介绍最显着和有用的新API。 作为应用程序开发人员,您应该尽快从SDK Manager中下载Android 4.2系统映像和SDK平台。如果您没有运行Android 4.2的设备来测试您的应用,请使用Android 4.2系统映像在Android模拟器上测试您的应用。然后针对Android 4.2平台构建您的应用程序,以开始使用最新的API。 ### **重要的行为变化** 如果您以前发布过Android应用,请注意以下可能会影响您应用行为的更改: * 内容提供者不再默认导出。也就是说,该android:exported属性的默认值是现在“false"。如果其他应用能够访问您的内容提供商很重要,那么您现在必须明确设置android:exported="true"。 这种变化仅仅发生在你设置任何影响android:targetSdkVersion或android:minSdkVersion17或更高。否则,“true" 在Android 4.2及更高版本上运行时,默认值仍然是。 * 与以前版本的Android相比,如果您的应用请求权限但不请求权限,则用户位置结果可能不太准确。 ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION 当您的应用请求粗略位置(而不是精细位置)的权限时,为了满足用户对隐私的期望,系统将不会提供比城市街区更准确的用户位置估计。 * 现在定义的一些设备设置Settings.System是只读的。如果您的应用程序试图写入Settings.System已经移动到其中的设置的更改Settings.Global,则在Android 4.2和更高版本上运行时,写入操作将以无提示方式失败。 即使你的价值android:targetSdkVersion,并android:minSdkVersion为超过17时,你的应用程序是不能修改已移动到设置Settings.Global在Android 4.2及更高版本上运行时。 * 如果您的应用程序使用WebView,Android 4.2添加了一个额外的安全层,以便您可以更安全地将JavaScript绑定到您的Android代码。如果您将其设置 targetSdkVersion 为17或更高,那么现在必须将@JavascriptInterface注释添加到您希望可用于JavaScript的方法(该方法也必须是公共的)。如果您没有提供注释,则WebView 在运行Android 4.2或更高版本时,您的网页无法访问该方法。如果将该值设置 targetSdkVersion 为16或更低,则不需要注释,但我们建议您更新目标版本并添加注释以提高安全性。 阅读更多关于将[JavaScript代码绑定到Android代码的信息](https://developer.android.com/guide/webapps/webview.html#BindingJavaScript)。 #### **梦话** Daydream是Android设备的全新交互式屏幕保护模式。当设备插入扩展坞或设备在插入充电器时闲置(而不是关闭屏幕)会自动激活。Daydream一次显示一个梦,可能是一个纯粹的视觉化的被动的显示,一触即发,或者可能是交互式的,并且响应整个输入事件。你的梦想运行在你的应用程序的过程中,并可以完全访问Android UI工具包,包括视图,布局和动画,因此它们比动态壁纸或应用程序小部件更加灵活和强大。 你可以通过实现一个子类来为Daydream创建一个梦想DreamService。这些DreamServiceAPI被设计成与那些API类似Activity。要指定自己的梦想的UI,通过一个布局资源ID或View以setContentView()在任何时候你有一个窗口后,如从onAttachedToWindow() 回调。 的DreamService类提供在底座的顶部其他重要生命周期回调方法Service的API,如onDreamingStarted(),onDreamingStopped(),和onDetachedFromWindow()。您无法DreamService从您的应用程序启动,系统会自动启动。 如果您的梦想是交互式的,您可以从梦想开始一个活动,将用户发送到您的应用程序的完整用户界面以获取更多细节或控制。您可以使用finish()结束梦想,以便用户可以看到新的活动。 为了使您的白日梦可用于系统,请在清单文件中声明DreamService一个`<service>`元素。然后您必须包含一个意向过滤器与行动"android.service.dreams.DreamService"。例如: ~~~ <service android:name=".MyDream" android:exported="true" android:icon="@drawable/dream_icon" android:label="@string/dream_label" > <intent-filter> <action android:name="android.service.dreams.DreamService" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service> ~~~ 还有其他一些有用的方法DreamService 要注意: * setInteractive(boolean)控制梦是否接收到输入事件或者在用户输入时立即退出。如果梦想是交互式的,用户可以使用“ 返回”或“ 主页”按钮退出梦想,或者您可以打电话 finish()来停止梦想。 * 如果你想要一个完全身临其境的显示器,你可以调用setFullscreen()隐藏状态栏。 * 在Daydream开始之前,显示屏会变暗,向用户发出信号,表示空闲超时正在接近。调用setScreenBright(true)允许您以通常的亮度设置显示。 有关更多信息,请参阅DreamService文档。 #### **二次显示** Android现在允许您的应用在通过有线连接或Wi-Fi连接到用户设备的其他屏幕上显示唯一内容。为辅助显示创建独特的内容,扩展Presentation 类并实现onCreate()回调。在其中 onCreate(),通过调用来为辅助显示器指定您的UI setContentView()。作为Dialog该类的扩展,Presentation该类提供了应用程序可以在辅助显示中显示唯一UI的区域。 要检测可显示的辅助显示器,请Presentation使用DisplayManager或MediaRouter API。尽管DisplayManagerAPI允许枚举多个可以同时连接的显示器,但通常应该使用它MediaRouter来快速访问系统的默认显示器以进行演示。 要获得演示文稿的默认显示,请调用MediaRouter.getSelectedRoute()并传递它 ROUTE_TYPE_LIVE_VIDEO。这将返回一个MediaRouter.RouteInfo描述系统当前选择的视频演示路线的对象。如果MediaRouter.RouteInfo不为空,打电话 getPresentationDisplay(),以获得Display代表相连接的显示器。 然后,您可以通过将Display对象传递给您的Presentation类的构造函数来显示您的演示文稿。您的演示文稿现在将显示在辅助显示屏上。 要在运行时检测到新显示器已连接,请创建一个实例,MediaRouter.SimpleCallback在该实例中实现onRoutePresentationDisplayChanged()回调方法,在连接新的演示文稿显示器时系统将调用该方法。然后注册MediaRouter.SimpleCallback通过将其传递到MediaRouter.addCallback()与沿ROUTE_TYPE_LIVE_VIDEO路径类型。当你接到电话时 onRoutePresentationDisplayChanged(),只需MediaRouter.getSelectedRoute()按上面提到的那样打电话。 要进一步优化Presentation二级屏幕中的用户界面,可以通过指定应用于应用程序或活动的android:presentationTheme属性来应用不同的主题`<style>`。 请记住,连接到用户设备的屏幕通常具有更大的屏幕尺寸,并且可能具有不同的屏幕密度。由于屏幕特征可能不同,因此应提供专门针对较大显示屏进行优化的资源。如果您需要从您的请求额外资源Presentation,调用getContext().getResources()以获取Resources显示对应的对象。这将从您的应用程序中提供最适合辅助显示器的屏幕尺寸和密度的适当资源。 有关更多信息和一些代码示例,请参阅Presentation 类文档。 #### **锁屏小部件** Android现在允许用户将应用程序小部件添加到锁定屏幕。要使您的App Widget可用于锁定屏幕,请将该android:widgetCategory属性添加到指定的Widget文件中AppWidgetProviderInfo。这个属性支持两个值:home_screen 和keyguard。默认情况下,该属性设置为home_screen用户可以将您的应用程序小部件添加到主屏幕。如果您希望您的应用程序小部件在锁定屏幕上也可用,请添加keyguard值: ~~~ <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" ... android:widgetCategory="keyguard|home_screen"> </appwidget-provider> ~~~ 您还应该在具有该android:initialKeyguardLayout属性的锁定屏幕上指定应用程序窗口小部件的初始布局。它的工作方式android:initialLayout与之相同,因为它提供的布局可以立即显示,直到应用程序窗口小部件初始化并能够更新布局为止。 有关为锁定屏幕构建应用程序小部件的更多信息,包括在锁定屏幕上正确设置应用程序小部件的大小,请参阅应用程序小部件指南。 #### **多个用户** Android现在允许可共享设备(如平板电脑)上的多个用户空间。设备上的每个用户都有自己的一套帐户,应用程序,系统设置,文件以及任何其他用户相关的数据。 作为一名应用程序开发人员,为了让您的应用程序能够与单个设备上的多个用户正常协作,您不需要做任何其他的事情。无论设备上可能存在多少用户,您的应用为特定用户保存的数据都与应用为其他用户保存的数据分开存放。系统会跟踪哪些用户数据属于您的应用正在运行的用户进程,并让您的应用仅访问该用户的数据,并且不允许访问其他用户的数据。 #### **将数据保存在多用户环境中** 无论何时您的应用程序保存用户首选项,创建数据库或将文件写入用户的内部或外部存储空间,只有以该用户身份运行时才能访问该数据。 要确定您的应用程序在多用户环境中的行为正确,请不要使用硬编码路径引用您的内部应用程序目录或外部存储位置,而是始终使用适当的API: * 要访问内部存储,使用getFilesDir(),getCacheDir()或openFileOutput()。 * 要访问外部存储,请使用getExternalFilesDir()或getExternalStoragePublicDirectory()。 无论您使用哪种API来为给定用户保存数据,在以不同用户身份运行时都无法访问数据。从您的应用程序的角度来看,每个用户都在一个完全独立的设备上运行。 #### **识别多用户环境中的用户** 如果您的应用想要识别独特的用户,例如收集分析或创建其他帐户关联,则应遵循建议的做法以识别独特的安装。通过UUID在您的应用第一次启动时创建一个新的应用,无论有多少用户在单个设备上安装您的应用,您都一定会获得用于跟踪每个用户的唯一ID。或者,您可以保存从您的服务器获取的本地令牌或使用Google Cloud Messaging提供的注册ID 。 请注意,如果您的应用程序请求其中一个硬件设备标识符(例如WiFi MAC地址或SERIAL数字),则它们将为每个用户提供相同的值,因为这些标识符与硬件绑定,而不是用户绑定。更不用说这些标识符引入的其他问题,如在识别App Installations博客文章中讨论的。 #### **新的全局设置** 系统设置已更新,以支持多个用户Settings.Global。这些设置的集合类似于Settings.Secure设置,因为它们是只读的,但可以在设备上的所有用户空间中全局应用。 一些现有的设置是从这里要么搬迁Settings.System或Settings.Secure。如果您的应用程序当前正在对之前在Settings.System (如AIRPLANE_MODE_ON)中定义的设置进行更改,那么您应该期望这样做将无法在运行Android 4.2或更高版本的设备上运行,如果这些设置已移至Settings.Global。您可以继续阅读其中的设置 Settings.Global,但是由于设置不再适合应用程序更改,因此尝试这样做会失败,系统会在Android 4.2上运行应用程序时向系统日志中写入警告,或者更高。 #### **RTL布局支持** Android现在提供了几个API,允许您构建用户界面,这些界面可以优雅地转换布局方向,以支持使用从右到左(RTL)UI和阅读方向(如阿拉伯语和希伯来语)的语言。 要开始支持应用程序中的RTL布局,请将该android:supportsRtl属性设置为<application>清单文件中的元素并进行设置“true"。启用此功能后,系统将启用各种RTL API,以RTL布局显示您的应用程序。例如,操作栏将在右侧显示图标和标题,在左侧显示操作按钮,您使用框架提供的View类创建的任何布局也将被颠倒。 如果在使用RTL布局进行显示时需要进一步优化应用程序的外观,则有两个基本的优化级别: 1. 将左侧和右侧布局属性转换为开始和结束导向布局属性。 例如,用来android:layout_marginStart 代替android:layout_marginLeft和android:layout_marginEnd代替 android:layout_marginRight。 所述RelativeLayout类还提供了相应的布局属性来替换左/右等位置,android:layout_alignParentStart以替换android:layout_alignParentLeft和android:layout_toStartOf代替 android:layout_toLeftOf。 2. 或者为RTL布局提供完整的优化,可以使用ldrtl资源限定符(ldrtllayout-direction-right-to-left)提供完全独立的布局文件。例如,您可以将您的默认布局文件保存在 res/layout/您的RTL优化布局中res/layout-ldrtl/。 在ldrtl预选赛是伟大的绘图资源,这样就可以提供在相应的读取方向的方向面向图形。 各种其他API可用于整个框架,以支持RTL布局,例如在View类中,以便您可以实现自定义视图和Configuration查询当前布局方向的正确行为。 注意:如果您使用的是SQlite,并且表名或列名仅为“数字”,请注意:String.format(String, Object...)如果设备已设置为阿拉伯语语言环境,则使用会导致数字已转换为阿拉伯数字的错误。必须使用String.format(Locale,String,Object...)以确保数字保存为ASCII。也可以使用String.format("%d", int)而不是 String.valueOf(int)用于格式化数字。 #### **嵌套片段** 您现在可以将碎片嵌入到碎片中。这对于您想要将动态和可重用UI组件放入本身为动态且可重用的UI组件的各种情况很有用。例如,如果您使用ViewPager创建左右滑动片段并占用大部分屏幕空间的片段,则现在可以将片段插入到每个片段页面中。 要嵌套片段,只需调用getChildFragmentManager()上Fragment要添加一个片段英寸 这将返回一个FragmentManager您可以像通常一样从顶级活动中使用来创建片段事务的方法。例如,下面是一些在现有Fragment类中添加片段的代码: ~~~ Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit(); ~~~ 从嵌套的片段中,可以通过调用来获取对父片段的引用 getParentFragment()。 Android支持库现在也支持嵌套片段,因此您可以在Android 1.6或更高版本上实现嵌套片段设计。 注意:当布局包含a时,不能将布局膨胀成片段`<fragment>`。只有在动态添加到片段时才支持嵌套片段。 #### **的renderScript** Renderscript计算功能已增强,具有以下功能: **脚本内在函数** 您可以使用Renderscript的内置脚本内在函数为您实现常用操作,例如: * Blends * Blur * Color matrix * 3x3 convolve * 5x5 convolve * Per-channel lookup table * Converting an Android YUV buffer to RGB 要使用内部脚本,请调用create()每个内部的静态方法来创建脚本的一个实例。然后您调用set() 每个脚本固有的可用方法来设置任何必要的输入和选项。最后,调用该forEach() 方法来执行脚本。 **脚本组** ScriptGroups允许你链接相关的Renderscript脚本并用一个调用执行它们。 使用a ScriptGroup.Builder通过调用将所有脚本添加到组中addKernel()。一旦添加了所有脚本,就通过调用在脚本之间创建连接addConnection()。完成添加连接后,请致电create() 以创建脚本组。在执行脚本组之前,指定Allocation要使用该setInput(Script.KernelID, Allocation)方法运行的输入 脚本和初始脚本, 并提供Allocation将结果写入的输出 以及运行的最终脚本setOutput()。最后,调用 execute()运行脚本组。 **Filterscript** Filterscript定义了对现有Renderscript API的约束,使得生成的代码可以在更广泛的处理器(CPU,GPU和DSP)上运行。要创建Filterscript文件,创建.fs 文件而不是.rs文件,并指定#pragma rs_fp_relaxed告诉Renderscript运行时,脚本不需要严格的IEEE 754-2008浮点精度。这个精度允许将数据清零并将数据舍入到零。此外,您的Filterscript脚本不得使用32位内置类型,并且必须使用该__attribute__((kernel))属性指定自定义的根函数, 因为Filterscript不支持root()函数的默认签名定义的指针。 > 注意:尽管平台中有Filterscript支持,但开发人员支持将在SDK Tools Release 21.0.1中提供。 有关Android 4.2中所有API更改的详细视图,请参阅 [API差异报告](https://developer.android.com/sdk/api_diff/17/changes.html)。