备注:之前Android入门学习的书籍使用的是杨丰盛的《Android应用开发揭秘》,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增加了很多的新组件,一直没有系统的学习过。现在开始这个“完善Android学习”系列,将2.2以后的新知识做一个概览。概览来自:http://developer.android.com/about/versions/android-4.0.html
Android4.0(ICE_CREAM_SANDWICH)为用户和开发者集中增加了一批新的特性。除了下面即将讨论到的各种新的特征和API之外,Android4.0之所以重要,还因为它将3.x(为平板设计)上的很多特性引入到小屏幕上(手机)。作为开发者来讲,你现在有一个单一一致的框架(Android4.0以及以上,API Level 14)来在手机、平板以及其余设备上开发发布你的应用,并且有很好的用户体验。
API Overview
Social APIs in Contacts Provider
ContactsContract provider定义的contact API已经被扩展支持新的面向社交的特征,比如设备拥有者的一份个人描述,以及用户可以邀请一个联系人进入安装在设备上的各种社交网络。
User Profile
Android现在拥有一个个人描述来表示设备拥有者了,它被定义在ContactsContract.Profile表中。维系着用户身份的社交应用现在可以通过在ContactsContract.Profile创建一个新的ContractsContract.RawContracts条目来完善用户的描述数据。具体来说,代表设备用户的raw contact不属于由ContactsContract.RawContact Uri定义的传统的raw contacts表格,相反,你必须在由CONTENT_RAW_CONTACTS_URI定义的表格中添加一个描述raw contact。表中的Raw contacts之后就被聚集到唯一的用户可见的标记着“Me”的描述文件中。
为描述文件添加新的raw contact需要WRITE_PROFILE许可。同样的,为了从描述文件中读取数据,必须申请READ_PROFILE许可。然而,绝大部分的应用不需要读取描述文件,即使应用完善了描述文件,读取描述文件是一个非常敏感的许可权,用户会对此感到迷惑和怀疑。
Invite Intent
INVITE_CONTACT intent允许一个应用触发一个动作,表示用户希望添加一个联系人进入社交网络,接收端的应用通过它邀请一个特定的联系人进入社交网络。
大部分的应用将会在这个操作的接收端。例如,内置的people应用程序里,用户详细信息列表上列出了该用户使用的社交应用,用户可以通过社交应用上的"添加联接"按钮调用 invite intent 连接两个人的社会网络。
为了让你的社交应用程序出现在“添加链接”按钮的列表里,你的应用必须提供一个同步适配器来同步你的社交网络中的联系人信息。你必须通过对你的应用程序的同步配置文件增加inviteContactActivity属性告知系统你的应用回应 INVITE_CONTACT intent ,并且制定一个完整的activity名字,这样发送invite intent后系统才知道应该启动哪一个,相关activity 才会检索响应的数据,邀请相关的人加入社会网络或者与手机使用者建立连接。
Large photos
android现在支持高分辨率的联系人照片,当你将一个照片放到联系人记录中的时候,系统会把它处理成96x96的缩略图(像之前那样),和一个存储在基于文件的相片存储中的256x256 的显示图片(该系统选择的确切尺寸,在未来可能会有所不同)。你能够在联系人的PHOTO列添加一个大照片,系统会再加工成相应的缩略图显示照片记录。
Contact Usage Feedback
新的 ContactsContract.DataUsageFeedback APIs 允许你追踪用户使用特定的方法联系其他人的频度,例如用户多久使用每个电话号码或邮件。此信息有助于改善与每个人相关联的每个接触方法的排名,并提供更好的建议去联系每个人联系。
Calendar (日历) Provider
新的日历API允许我们读,增加,编辑和删除存储在Calendar Provider的日程表、事件与会者,提醒和警示, 各种应用程序和部件可以使用这些API来读取和修改日历事件。然而,一些最引人注目的用例的是能够通过Calendar Provider同步其他日历服务的用户的日历的同步适配器,它能够为所有的用户事件提供一个统一的存放位置。例如,GOOGLE日历事件,通过google日历同步适配器进行同步,允许这些事件在android内置的日历软件中查看。
Calendar Provider中日历的数据模式和事件相关的信息是由CalendarContract来定义的。所有用户的日历数据都是由CalendarContract的各种子类定义的,存储在一系列的表中:
1)CalendarContract.Calendars表:表中存储着日程表的详细信息,每一行包含了一个日程表的详细信息,比如:名字,颜色,同步信息以及其余的内容;
2)CalendarContract.Events表:表中存储着事件额详细信息,表中每一行存储着单一事件的信息,比如事件的标题,地点,开始时间,结束时间以及其它信息,事件可以只发生一次或者多次重复发生,参与者,提醒者以及扩展属性都被存储在独立的表中,使用事件的_ID连接两张表格;
3)Calendar.Instances表:表中存储着事件的发生的开始和结束时间,表中的每一行代表着一个时间的发生。对于只发生一次的时间来说,时间和事件之间一一对应,对于不止发生一次的事件来说,多条行会自动产生来对应于时间的发生;
4)Calendar.Attendees表:表中存储着事件的参与者或者受邀者的信息,每一行代表着一个时间的参与者,它指明了参与者的类型,以及参与者对时间的响应;
5)Calendar.Remainders表:表中存储着警告和提醒的数据,每一行包含着对一个时间的警告,一个时间可以有多个提醒者,一个时间最多的提醒者数目由MAX_REMINDERS决定,是由拥有日程表的同步适配器决定的,提醒者是在事件发生前确定的几分钟时触发的,也详细记录了提醒的方式:alert或者是SMS,或者是邮件等等;
5)Calendar.ExtendedProperties表:表中记录了被同步适配器使用的隐秘数据,provider不会去动表中的数据,除非是相关的数据被删除以后去删除它们;
为了用Calendar Provider访问用户的日历数据。应用必须获取READ_CALENDAR和WRITE_CALENDAR权限。
Event intent
如果你想要做的是往用户的日历添加事件,你可以使用ACTION_INSERT intent携带Events.CONTENT_URI定义的数据来打开一个Calendar应用中创建新事件的activity。使用该intent,不需要任何权限并且您可以使用下列额外的参数指定详细信息:事件名,事件开始时间,结束时间,地点,描述,参与者的邮件地址,时间重发规则,事件是私有的还是公共的,该事件发生的时间段是否允许别的时间发生。
Voicemail Provider
新的Voicemail Provider允许用户往设备中添加voicemails以便于在一个单一的视图中展示所有的voicemals。举个例子,用户可能有很多的voicemails来源,比如来自手机的servie provider,来自VoIP的或者其余的语音服务的,这些应用可以通过Voicemail Provider API将自己的voicemails添加到设备中去。然后内建的Phone应用就可以在一个统一的视图中展示所有的voicemails。Phone应用是唯一一个可以读取所有的voicemails的应用,其余的应用只可以读取自己添加的voicemails,别的应用添加的是不可以读取的。
因为目前的API不允许第三方应用读取所有的voicemails,所有应该去使用voicemails API的应用应该是那些有voicemails要传播给用户的应用。
VoicemailContract类定义了Voice Provider的content provider。子类:VoicemailContract.Voicemails和VoicemailContract.Status则提供了应用可以插入存储voicemails数据的表格。
Multimedia
Media Effects
一个新的Media效果框架允许用户定义图片以及视频施加各种各样的视觉效果。举个例子,图片效果允许你轻松的修正红眼,将图片转成灰度图片,调整亮度,饱和度,旋转图片,施加鱼眼效果等等。系统使用GPU去处理这些效果来获得最大的性能。
为了获取最大性能,效果被直接施加在OpenGL上,所以为了使用这些API效果,你的应用必须提供一个可用的OpenGL环境。施加效果的对象可能是一个bitmap,视频或者甚至是摄像头,然而,对象必须遵守以下几个约束:
1)它们必须是GL_TEXTURE_2D结构图片;
2)必须至少有一个mipmap层级;
一个效果对象定义了一个你可以施加到图片帧上的media效果,创建一个效果对象的基本流程如下:
1)在OpenGL ES 2.0环境中调用EffectContext.createWithCurrentContext();
2)使用返回的EffectContext调用EffectContext.getFactory(),返回一个EffectFactory实例;
3)调用createEffect()方法,传入android.media.effect.EffectFactory中定义的效果名称;
你可以通过调用setParameter()方法来设置效果的参数,然后传入参数的名字和参数的值,不同的效果将接受不同的参数,这和效果的名字列在一起。
为了在一个Media上施加效果,在Effect上调用apply()方法,然后穿进去要施加的对象,它的高和宽,以及输出的对象。输入对象必须是GL_TEXTURE_2D结构的图片(通常由调用函数glTexImage2D()获得)。你可以提供多mipmap层级。输出则和输入同样的尺寸。
在EffectFactory中列出的效果都是保证支持的,然而,由外部库提供的效果却不一定被所有的设备支持,所以你必须使用方法isEffectedSupported()方法查看来自外部库的想要的效果是否被支持。
Remote control client
心的RemoteControlClient 允许媒体播放器从远程控制客户端(例如设备锁屏界面)控制媒体文件的播放。媒体播放器也可以向外暴露播放媒体文件的信息,比如唱片等等。
为了使用远程控制客户端吧,媒体播放器必须用RemoteControlClient实例化,向它传输一个PendingIntent,广播一个ACTION_MEDIA_BUTTON。这个intent必须在app中显示声明一个ACTION_MEDIA_BUTTON事件接收器。
为了声明你的播放器能够处理哪一个媒体控制输入,你必须调用RemoteControlClient的setTransportControlFlags()方法,传输进入一系列的FLAG_KEY_MEDIA_*标记,比如FLAG_KEY_MEDIA_PREVIOUS和FLAG_KEY_MEDIA_NEXT。
你必须通过将RemoteControlClient传递给 MediaManager.registerRemoteControlClient()来进行注册,一旦注册,当你实例化RemoteControlClient的时候你声明的广播接收器在远程控制的一个按钮被按下去的时候将会收到一个ACTION_MEDIA_BUTTON事件。收到的Intent包含着按下去的key的KeyEvent,你可以通过 getParcelableExtra(Intent.EXTRA_KEY_EVENT)获取该对象。
为了在远程控制上展示正在播放的媒体文件的信息,可以调用editMedaData()方法,将metadata添加到返回的RemoteControlClient.MedataEditor中去,你可以为播放媒体文件的artwork提供一张bitmap,为播放时间提供数字信息,为磁带标题提供文字信息。可以通过查看MediaMetadataRetriver中的METADATA_KEY_*获取更多的可用键。
Media Player
1)从4.0开始,MediaPlayer播放网络上的媒体文件需要INTERNET许可。
2)setSurface()方法允许用户设置一个Surface作为video的接收端;
3)setDataSource()允许你在请求中添加额外的HTTP headers,这对http实时流很有帮助;
4)HTTP流现在不再忽视请求中的cookies了。
Media types
Android4.0开始支持:
1)HTTP/HTTPS 实时流媒体协议第三版;
2)ADTS raw AAC音频编码;
3)WEBP图片;
4)Matriska视频;
Camera
Camera类现在包含以下的API来探测人脸,控制焦点和计量区。
Face detection
Camera应用现在可以使用Android的人脸识别API来增强自身的能力了——不但可以探测到一个人的脸,而且可以看到详细的特征,比如眼睛和嘴巴。
为了在应用中侦测要人脸,开发者必须调用setFaceDetectionListener()方法来注册一个Camera.FaceDetectionListener。然后你就可以开启你的camera surface,然后调用startFaceDetection()方法开始探测人脸。
当系统在照相机镜头中探测到一张或者多张人脸的时候,它就会调用Camera.FaceDetectionListener中的OnFaceDetection()回调方法,穿进去一组Camera.Face对象。
一个Camera.Face实例包含着侦测到的人脸的各种信息,包括:
1)一个Rect,描述人脸的区域,这和camera当前的视觉区域相关;
2)一个1-100之间的参数来告诉开发者,系统有多大的信心确认侦测到的对象是一个人脸;
3)一个唯一的ID让你可以区分侦测到的各个人脸;
4)几个Point对象指明人眼和嘴巴在哪里;
注意:人脸识别在某些设备上可能不被支持,你西药通过调用getMaxNumDetectedFaces()方法来检查,确保返回的值大于0。同样,一些设备或许也不支持人眼和嘴巴的识别,这种情况下,Camera.Face中的这些对象将会是Null。
Focus and metering area
Camera应用现在可以控制摄像头用于计算焦点和测量白平衡以及自动曝光的区域了。两种特性都是用Camera.Area类来确定计算焦点和测量的当前的摄像头视觉区域。一个Camera.Area类的实例使用一个Rect来定义区域的边界以及相对于其余区域的权重(一个整数)。
在设置一个聚焦区域或者测量区域之前,你需要首先调用getMaxFocusAreas()或者getMaxMeteringAreas()方法。如果返回的是0,表明设备不支持相应的特性。
为了详细确定聚焦和测量区域,只要调用setFocusArea()和setMeteringAreas()。每一个都是用一list的Camera.Area对象来表明可以考虑用作聚焦或者测量的区域。举例来说,你或许实现了一个功能——让用户触摸预览区来控制聚焦区域,你可以通过将区域转化成Camera.Area对象来要求camera聚焦在该区域,那个区域的焦点或者曝光率就会随着视图的变化实时更新。
Continus auto focus for photos
现在在拍照片的时候可以允许持续自动对焦(CAF)了。要让应用使用CAF,只需要通过方法setFocusMode()设置参数FOCUS_MODE_CONTINUOUS_PICTURE。当想要捕捉图片的时候,调用方法autoFoucs(),然后Camera.AutoFoucsCallback()方法就会立刻被回调,来表明焦点是否被获得。在调用后为了恢复CAF,必须调用cancelAutoFocus()方法。
备注:CAF在拍摄视频的时候也能被支持,是要使用API 9中添加的FOCUS_MODE_CONTINUOUS_VIDEO即可。
Other camera feature
1)当录制视频的时候,可以调用takePicture()方法来保存一张图片而不用大断送回聘录制过程。在这之前,你需要调用isVideoSnapshotSupported()来判断硬件是否支持。
2)现在可以通过方法setAutoExposureLock()和方法setAutoWhiteBlanceLock()来锁定自动曝光和白平衡调节。
3)现在可以在预览正在运行的时候调用setDisplayOrientation()方法。在之前,只有在开始预览之前调用这个方法,但是现在可以在任何时候调用该方法了。
Camra broadcast intents
Camera.ACTION_NEW_PICTURE:广播告知:用户拍摄了一个新照片。内建的Camera应用在照片被拍摄以后进行这个广播,第三方应用也应该在拍摄照片之后,进行这个广播;
Camera.ACTION_NEW_VIDEO:如上。
Network Usage
Android4.0让用户可以精确的看到他们的应用到底使用了多少流量。设置应用提供了设置流量使用上限的控制功能,甚至可以禁止一个APP在后台使用流量。为了避免用户从后台显示你的应用获取数据,开发者应该开发链接使用策略,让数据连接更加有效并且可以根据不同类型的连接调整数据连接的使用。
如果你的应用需要耗费很多的网络资源,应用应该提供给用户设置功能来控制应用的数据习惯,比如多久同步一次,在WIFI状态下是否进行上传下载操作,漫游状态下是否使用数据。有了这些设置,用户更可能在流量达到上限的时候不去禁止你的应用获取数据,因为他们可以精确控制你的应用使用的数据量。如果你为这些设置提供一个preference activity,你需要在它的manifest声明中为动作ACTION_MANAGE_NETWORK_USAGE添加一个intent filter。举例如下:
<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 filter告诉系统,这个activity是用来控制应用的数据使用的。因此,当用户想通过设置应用来检测你的应用到底是用了多少流量的时候的,一个“View application settings”按钮就可以被用来点击查看你的preference activity以便于用户可以改善应用的数据使用情况。
Enterprise
VPN services
新的VpnService允许应用建立自己的VPN,并且当做Service运行.
Device Sensors
Android4.0中添加了两种新的sensor:
1)TYPE_AMBIENT_TEMPERATURE:提供周围温度的感应器;
2)TYPE_RELATIVE)HUMIDITY:提供周围湿度的感应器;
如果一个设备具有以上两种感应器,就可以使用它们侧到的数据来计算露点和绝对湿度。
之前的温度感应器:TYPE_TEMPERATURE已经被废弃了,开发者应该使用心的。
另外,Android的三种感应器已经被极大的优化了,现在有更短的等待时间,更加稳定的输出。这些感应器包括:重力感应器,转向感应器和直线加速感应器。优化过的感应器依赖于陀螺仪来优化输出,所以这些感应器只在有陀螺仪的设备上才有。
Action Bar
ActionBar被升级用来支持几个新行为。最重要的是,系统可以在小屏幕上优雅的管理action bar的尺寸和配置,以便于在所有屏幕的设备上可以提供良好的用户体验。
Split action bar
如果你的action bar包含好多的action item,在一个窄屏设备上是不会全部放在action bar上的,所以系统将会将大部分的item放到overflow menu中去,然而Android4.0允许你使用split action bar以便于将部分Item放到屏幕底部去,让用户看到更多的item。要使用split action bar,在<application>或者<activity>中添加一个属性:android:uiOptions,值为splitActionBarWhenNarrow。这样当屏幕过窄的时候,系统就会在屏幕地步添加一个额外的bar。
如果你想要使用ActionBar.Tab提供的导航tab,但是不需要显示action bar(你想要只在顶部显示tab),可以向上面一样启用split action bar,然后调用方法setDisplayShowHomeEnabled(false)方法来禁止应用程序屯表出现在action bar上面,当action bar上面什么都没有的时候,它就消失了——只有导航tabs存留下来以及底部的action items。
Action bar styles
如果你想使用自己定制的action bar style,可以使用新的style属性backgroundStacked和backgroundSplit来为stacked bar和split bar设置一个背景图片或者颜色。也可以在运行时用方法setStackedBackgroundDrawable()和setSplitBackgroundDrawable()设置。
Action provider
新的ActionProvider类允许开发者为action item创建一个定制的处理器。一个action povider可以定义一个action view,一个默认的action行为,以及关联action item的一系列子菜单。当你想要创建一个有动态行为的action item的时候,继承ActionProvider是一个不错的解决方案,这可以创建可充用组件。
举个例子,ShareActionProvider就是ActionProvider的子类。不同于传统的action item。在点击的时候发送ACTION_SEND intent,你现在可以使用action provider来展示一个可以处理ACTION_SEND intent的应用的下拉列表。当用户选择一个应用来处理该动作,ShareActionProvider会记住该选择,然后在action view中提供更快的访问。
要替acion item声明一个action provider,只需要在<item>中包含属性android:actionProviderClass,用action provider类的名字作为值,如下:
<item android:id="@+id/menu_share"
android:title="Share"
android:showAsAction="ifRoom"
android:actionProviderClass="android.widget.ShareActionProvider" />
在activity的onCreateOptionMenu()方法中,实例化这个action provider,然后设置Intent:
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);
}
Collapsible action views
提供action view 的action items仙子阿可以在他们的action view和传统的action item状态之间进行切换。之前只有SearchView当做action view用的时候支持,现在,你可以为任何一个action item提供一个action view并且在展开状态和收起状态之间进行切换。
要声明一个action item拥有一个可折叠的action view,只需要在<item>中添加android:shopwAsAction属性,值为"collapseActionView"。
要监听收起展开状态,则在响应的MenuItem上添加一个MenuItem.OnActionExpandListener监听器,通常这是在onCreateOprtionsMenu()方法中做的。
想要控制可伸缩的action view,可以调用相应的MenuItem的collapseActionView()和expandActionView()方法。
当创建自己的action view的时候,开发者可以实现新的CollapsibleActionView()接口,这样当action view展开或者收起的时候就会收到回调。
Other APIs for action bar
1) setHomeButtonEnabled():允许你设置应用的图标是否可以像一个按钮一样进行导航;
2)setIcon()和setLogo()允许开发者在运行时定义action bar的icon或者logo;
3)Fragment.setMenuVisisbility():允许你显示/隐藏fragment定义的可选菜单,当fragment被添加到activity的时候,但是还是不可见,这个时候menu就应该不可见;
4)FragmentManager.invalidateOptionsMenu():允许你在fragment声明周期中的任何状态让activity的可选菜单失效(有时候来自activity的同效方法不可访问)
User Interface and Views
GridLayout
GridLayout是一个新的ViewGroup,它把子元素放置在矩形的方格里面。不同于TableLayout,GridLayout
TextureView
TextureView是一个心的view,它允许你展示一个内容流,比如video或者OpenGL场景。尽管它和SurfaceView差不多,但是TextureView只是一个普通的View,它不会创建一个独立的窗口,所以开发者可以像别的普通View对象一样对待它,举个例子,你可以施加变化,使用ViewPropertyAnimator添加动画,或者使用setAlpha调节它的透明度。
要注意的是,TextureView只在硬件加速的窗口中工作。
Switch widget
新的Switch widget是一个2-态触发器,允许用户在两种状态中通过拖拉和点击进行切换。开发者可以使用android:textOn和android:textOff来说明在开关状态下要显示的文字。android:text则允许开发者在switch边上放置一个label。
Popup menus
Android3.0引入了PopupMenu来创建简短的上下文菜单,可以在选定的地点弹出来。Android4.0则扩展了PopMenu的特征:
1)你现在可以很轻松的从menu资源文件中读取xml,然后设置popup menu的内容;
2)现在可以创建PopupMenu.OnDismissListener,当PopupMenu小时的时候可以接收一个回调;
Preferences
一个新的TwoStatePreference抽象类作为提供二值选择项的preferences的基础出现。新的SwitchPreference则是TwoStatePreference的继承类。提供了一个Switch widget让用户开启/关闭一个设置,而不用打开另外一个preference屏幕或者对话框。举个例子,设置应用是永恒SwitchPreference来进行Wifi和BlueTooth的设置。
System themes
Android4.0(targetSdkVersion或者minSdkVersion是14或者更高的)所有应用的默认主题现在是"device default"主题:Theme.DeviceDefault。这或许是一个暗色的Holo主题,但是暗色程度由特定的设备设置。
Theme.Holo家族保证在所有同样版本的Android运行的时候不会有改变。如果你显示的将这个主题运用到Activity上去,你可以确信,在同一个Android版本的机器上运行的时候,主题是不会改变的。
如果你希望你的应用与总体的设备主题和谐一致,你就需要显示的使用来自Theme.DeviceDefault家族的主题。
Options menu button
从Android4.0开始,你将会注意到手持设备不再需要一个Menu hardware button。然而,如果你有一个应用提供了一个options menu并且期待有一个Menu button,你不必为此担心。为了保证已有的应用可以继续工作,系统提供了一个屏幕上的Menu按钮。
为了获得最好的用户体验,新的和升级的应用应该使用Actionbar来替代提供访问不同的Menu items的功能,然后将targetSdkVersion设置为14来充分最新框架提供的默认行为。
Controls for system UI visibility
在Android的早期,系统管理一个叫做status bar的UI组件,它在设备屏幕的顶端,展示诸如提醒,时间,消息等等信息。Android3.0为平板设备添加了system bar,它在设备屏幕的底部,来提供系统导航(Home,后退等)。以及一些传统status bar的接口元素。在Android4.0上面,系统提供了一种新的组件叫做navigation bar。你或许会把navidation ba当做一个为手持设备设计的system bar的再造物——它为没有硬件相对物进行导航的设备提供导航控制,但是它没有system bar的提醒UI和设置控制。因为这样,拥有navigation bar的设备也在顶端有一个status bat。
到了今天,我们可以使用FLAG_FULLSCREEN来隐藏设备的status bar。在Android4.0上面,控制system bar的可见性的API已经被升级更新,可以更好的反应system bar和navigation bar的行为:
1)SYSTEM_UI_FLAG_LOW_PROFILE:替代了STATUS_BAR_HIDDEN标签,当被设置后,这个标签可以为system bar或者navigation bar开启“low profile”模式。导航按钮变暗淡,system bar上的其余的元素也被隐藏起来。开启这个模式在创建不受system navigation按钮影响的拟真游戏的时候非常有用;
2)SYSTEM_UI_FLAG_VISIBLE:替代STATUS_VAR_BISIBLE标签,要求system bar和navigation bar可见;
3)SYSTEM_UI_FLAG_HIDE_NAVIGATION是一个新的标签,要求navigation bar彻底隐藏起来。注意,它只是隐藏某些设备使用的navigation bar(并不隐藏平板上的system bar)。navigation bar在系统获得用户输入的时候就会变得可见。因为这样,这个模式在播放视频或者在需要求全屏而不需要用户输入的情况下变得非常有用。
开发者可以调用setSystemUiVisibility()来设置这些flag。窗口管理器会整合所有窗口里面View的flag,将它们设置到system UI上去,只要你的窗口还有焦点。当你的窗口是去输入焦点以后(用户导航离开你的应用,或者对话框出现),flag就会失效。同样的,如果你将这些view从view继承中移除了,这些flag就不会再起作用。
为了同步activity中其余的组件可见事件(举个例子,当隐藏system UI的时候隐藏action bar或者其余的组件控制),开发者应该注册一个 View.OnSystemUiVisibilityChangeListener,当system bar或者navigation bar的可见性改变的时候,可以进行通知。
Properties
新的Property类提供了一个快速高效的方式来在任何的对象上明确一个属性,允许调用者在目标对象上自动set/get属性值。它也允许传递字段/方法引用,并且允许通过代码来获取/设置属性的值,即使我们不知道属性/方法的详细情况。举个例子,以前如果要设置foo对象的bar属性,我们会这样:
foo.bar = value;
foo.setBar(value);
然而,如果你想要传递foo实例并且使用别的代码来设置bar的值,在Android4.0之前真的没有别的办法。然而在Android4.0之后你可以使用Property类在Foo类上声明一个Property对象BAR,然后你就可以设置Foo类的实例food的实例:
BAR.set(foo, value);
View类现在利用Property类来允许你设置各种各样的属性,比如在3.0中假如的变化属性(ROTATION, ROTATION_X等)。ObjectAnimator类也使用Property类。你就可以创建ObjectAnimator,这样可以更快更高效,并且类型安全。
Hardware Acceleration
从4.0开始,为窗口提供硬件加速就是默认开启的,如果你的应用将targetSdkVersion或者minSdkVersion中的任何一个设置为14或者更高。硬件加速会让动画更加平滑,滚动更加平滑,以及总体上来说更好的性能,更快速的操作响应。
如果有必要,你可以手动关闭硬件加速,在<activity>或者<application>元素中使用属性hardwareAccelerated。运行时,也可以关闭硬件加速,方法是setLayerType(LAYER_TYPE_SPFTWARE)。
WebKit
1)WebKit更新到版本534.30
2)在WebView'中支持Ethiopic, Georgian, and Armenian、Indic字体和内建的浏览器;
3)支持WebDriver,使得使用WebView测试应用更加容易。
Android Browser
浏览器应用添加了一下的特征来支持web程序:
1)升级的V8 Javascript解释器,有更快的性能;
2)增加了来自Android3.0的一些其他的显著的增强;
Permission
新的许可权:
1)ADD_VOICEMAIL:允许一个voicemail服务往设备中添加voicemail 消息。
2)BIND_TEXT_SERVICE:实现SpellCheckerService的服务必须要求这项权限;
3)BIND_VPN_SERVICE:实现VpnService的服务必须要求这项权限;
4)READ_PROFILE:前面已经提及;
5)WRITE_PROFILE:前面已经提及;
Device Feature
下面是新的设备特性:
FEATURE_WIFI_DIRECT:声明应用需要使用Wi-Fi来进行P2P交流。