原文链接:http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html
伴随着新特性和功能,Android 6.0 (API level 23) 还包含了一些系统以及API行为上的变化。本文着重指出了一些你(开发者)需要了解,并在开发应用时予以考虑的关键变化。
如果你之前发布过Android应用,那么请注意,平台的这些变化会影响到你的应用。
本次发布引入了一个新的权限模型,让用户可以在运行时直接管理应用权限。这个模型为用户提供了更好的权限可见性和可控性,同时简化(streamling)了应用安装和自动升级的过程。用户可以对已安装的应用逐个赋予(grant)或者取消(revoke)权限。
如果你的应用目标平台是Android 6.0 (API level 23) 或更高,则必须确保在运行时检查权限和请求权限。通过调用新增的checkSelfPermission()
方法可以确认应用是否被赋予了某个权限。而要想获取权限,可以调用新增的requestPermissions()
方法。即使应用的目标平台不是Android 6.0,也应该在新的权限模型下对其进行测试。
更多关于如何在应用中支持新权限模型的细节,请参见使用系统权限。如果想了解如何评估新权限模型对应用的影响,可以参考权限最佳实践。
本次发布了针对空闲的设备和应用引入了新的省电优化方案。这些特性会对所有应用产生影响,所以务必在这些新的模式下对你的应用进行测试。
更多关于省电方面的变化,请参见针对休眠和应用待机的优化。
Android 6.0移除了对Apache HTTP客户端的支持。如果你的应用使用了该客户端,并且目标平台是Android 2.3 (API level 9) 或者更高,那么请用HttpURLConnection
类来替代。这个API效率更高,因为它使用了透明压缩(transparent compression)和响应缓存(response caching)来减少对网络的占用,并且降低了功耗。如果想继续使用Apache HTTP的接口,就必须先在build.gradle
文件中声明以下编译时依赖:
android {
useLibrary ‘org.apache.http.legacy‘
}
Android正在从OpenSSL迁移到BoringSSL库。如果你的应用中使用了Android NDK,那么不要链接任何不属于NDK API的加密库,比如libcrypto.so
和libssl.so
。这些库不是公共API,有可能在不引起注意的情况下,在不同的发布版和设备之间发生变化,或者崩溃。另外,这些库有可能使你暴露在安全风险面前。所以,应该修改本地代码,通过JNI调用Java的加密API,或者静态链接某个你选择的加密库,而不是链接上述库。
为了给用户提供更好的数据保护,从本次发布开始,Android不再支持应用通过Wi-Fi和蓝牙接口,以编程的方式访问设备本地硬件标识。现在,WifiInfo.getMacAddress()
和BluetoothAdapter.getAddress()
这两个方法将返回常量02:00:00:00:00:00
。
如果想通过蓝牙和Wi-Fi扫描来访问邻近其他设备的硬件标识,应用必须有ACCESS_FIN_LOCATION
或者ACCESS_CORSE_LOCATION
权限:
注意:如果运行Android 6.0 (API level 23) 的设备启动了一个后台的Wi-Fi或者蓝牙扫描,对外部设备来说,看到的会是从一个随机MAC地址发起的操作。
本次发布移除了Notification.setLatestEventInfo()
方法,取而代之的是用Notification.Builder
来创建通知。如果要重复更新某个通知,可以重用(reuse)Notification.Builder
实例,调用build()
来获得更新后的Notification
实例。
另外,命令
adb shell dumpsys notification
将不再输出通知的文本。如果想输出通知对象中的文本,需要执行:
adb shell dumpsys notification --noredact
不再支持通过AudioManager
类直接设置特定流的音量或者将其静音,setStreamSolo()
方法已被弃用(deprecated)。替代方法是调用requestAudioFocus()
方法。类似的,setStreamMute()
方法也已被弃用,替代方法是调用adjustStreamVolume()
,并传入ADJUST_MUTE
或者ADJUST_UNMUTE
。
现在,当用户在你的应用中选择文本时,你可以在一个浮动工具栏上显示诸如剪切,复制和粘贴这样的文本选择动作。这里实现的用户交互跟“在单独视图中启用上下文动作栏”一文中介绍的上下文动作栏(contextual action bar)类似。
如果想为文本选择实现一个浮动工具栏,需要在现有应用中做以下修改:
View
或者Activity
对象中,将ActionMode
的调用中从startActionMode(Callback)
改为startActionMode(Callback, ActionMode.TYPE_FLOATING)
;ActionMode.Callback
实现改为从ActionMode.Callback2
派生;onGetContentRect()
方法,提供内容Rect
对象(例如文本选择区域的矩形)在视图中的坐标;invalidateContentRect()
方法;如果你使用了22.2版的Android支持库 ,那么要注意,浮动工具栏不是向后兼容的。默认情况下,appcompat会接管对ActionMode
对象的控制,这会使浮动工具栏显示不出来。为了在AppCompatActivity
中支持ActionMode
,需要先调用getDelegate()
,然后在该方法返回的AppCompatDelegate
对象上调用setHandleNativeActionModesEnabled()
方法,并将输入参数设为false
。这个调用会将ActionMode
的控制权交还给框架(framework)。在运行Android 6.0 (API level 23) 的设备上,框架可以支持ActionBar
或者浮动工具栏模式,而在Android 5.1 (API level 22) 或者更低本的Android上,只支持ActionBar
模式。
本次发布不再支持全局书签(global bookmarks),android.provider.Browser.getAllBookmarks()
和android.provider.Browser.saveBookmark()
方法已被移除,READ_HISTORY_BOOKMARKS
和WRITE_HISTORY_BOOKMARKS
权限也同样被移除。如果你的应用目标平台是Android 6.0 (API level 23) 或者更高,那么就不要通过全局提供器来访问书签,或者使用书签的权限。相反,应用应该自行将书签数据保存在内部。
随着本次的发布,Android密钥存储提供器不再支持DSA,但仍支持ECDSA。
当安全锁屏被(比如用户或设备管理器)禁用或者重置时,将不再删除那些待机(at rest)时无需加密的密钥。而那些待机时也需要加密的密钥在这种情况下则会被删除。
本次发布在Wi-Fi和网络接口方面,引入了以下这些行为上的变化:
WifiConfiguration
对象的状态,而不能修改或者删除用户或者其他应用创建的WifiConfiguration
对象;enableNetwork()
,强制设备连接到某个特定的Wi-Fi网络,而且设置了disableAllOthers=true
,那么设备将会从其他网络(比如蜂窝数据)断开。而在本次发布中,设备将不再从其他网络断开。如果应用的targetSdkVersion
是20
或者更低,那么它会被锁定(pinned)到所选择的Wi-Fi网络。如果应用的targetSdkVersion
是21
或者更高,则要使用多网络API(比如openConnection()
,bindSocket()
和新的bindProcessToNetwork()
方法),来确保该应用的网络流量被发往所选择的网络。本次发布,将相机服务中对共享资源的访问模型,从之前的“先到先服务”改为“基于进程优先级服务”。服务行为的变化包括:
Camera
API中,会调用onError()
。而在Camera2
API中,则会调用被驱逐的客户端的onDisconnected()
方法;ART运行时现在正确地实现了newInstance()
方法的访问规则。这个变化修正了之前版本中Dalvik没有正确检查访问权限的问题。如果你的应用使用了newInstance()
方法,而且想覆盖原有的权限检查,可以调用setAccessible()
方法,并将输入参数设为true
。如果应用使用了v7 appcompat库或者v7 recyclerview库,则必须将这两个库升级到最新版本。否则,就要升级XML中引用的所有自定义类,确保它们的构造函数都是可访问的。
本次发布还升级了动态链接器(dynamic linker)的行为。现在,动态连接器可以区分库的soname
和它的路径(公开bug 6670),并实现了基于soname
的查找。之前没有正确设置DT_NEEDED
条目(通常设成了构建机器文件系统上的绝对路径)却能正常工作的应用,现在可能会加载失败。
另外,dlopen(3) RTLD_LOCAL
标志也被正确地实现了。需要注意的是,由于RTLD_LOCAL
是默认值,所以没有显式使用RTLD_LOCAL
的dlopen(3)
调用都可能受影响(除非应用显式使用了RTLD_GLOBAL
标志)。使用RTLD_LOCAL
标志加载的符号,对于后续通过dlopen(3)
加载的库来说是不可见的(跟DT_NEEDED
条目所引用的情况相反)。
在以前版本的Android上,如果应用请求系统加载一个需要代码重定位(text relocations)的共享库,系统会显示一个警告,但仍然允许库被加载。从本次发布开始,如果应用的目标SDK版本是23或者更高,系统将拒绝加载这样的库。在应用中输出dlopen(3)
失败的日志,并将dlerror(3)
返回的问题描述文本包含在其中,将有助于检测库加载失败的问题。想了解更多对代码重定位的处理方法,请参见这份指南。
现在,平台将对APK进行更严格的校验。如果manifest中声明了某个文件,但在APK中没有这个文件,那么这个APK将被视为已损坏。不管移除了什么内容,APK都必须重新签名。
现在通过USB端口连接设备,默认将是“仅充电”模式。如果想通过USB连接来访问设备和设备上的内容,需要用户显式地为这种交互授权。如果你的应用支持用户通过USB端口与设备进行交互,那么就需要考虑到这种交互需要被显式开启。
本次发布包含了以下这些Android for Work相关的变化:
setCrossProfileCallerIdDisabled()
设为true
可以在Google拨号记录中隐藏工作联系人。只有将setBluetoothContactSharingDisabled()
设为false
(默认为true
),才能通过蓝牙在其他设备上同时显示工作联系人和私人联系人;addNetwork()
),在其所属的工作配置被删除时,会被移除;WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
不为0,将不能被用户修改或者删除。但用户还是可以创建和修改自己的Wi-Fi配置。而活动设备所有者则有特权,可以编辑或者移除任意Wi-Fi配置——包括哪些不是由其创建的配置;DevicePolicyManager
特定API的行为变化: setCameraDisabled()
方法只会影响调用者自己的camera。在受管理配置(managed profile)中调用该方法,不会影响在主用户(primary user)中运行的相机应用;setKeyguardDisabledFeatures()
方法;KEYGUARD_DISABLE_TRUST_AGENT
和KEYGUARD_DISABLE_FINGERPRINT
,这会影响到当前配置的父用户的键盘锁设置;KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS
,这只影响受管理配置里的应用所产生的通知;createAndInitializeUser()
和createUser()
方法被废弃;EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
现在默认是SHA-256。为了向后兼容,目前仍支持SHA-1,但未来将不再对其支持;EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
现在只支持SHA-256;EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
,因此不能通过编程,让NFC bump provisioning解锁一个出厂时被设为保护的设备;EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
来将数据传递到设备所有者应用;DevicePolicyManager
权限接口不影响M之前的应用;ACTION_PROVISION_MANAGED_DEVICE
Intent发起的,当用户从其中的同步部分(synchronous part)退出时,系统将返回RESULT_CANCELED
结果码android.app.usage.NetworkUsageStats
类被改名为NetworkStats
;setGlobalSettings()
修改以下设置: BLUETOOTH_ON
DEVELOPMENT_SETTINGS_ENABLED
MODE_RINGER
NETWORK_PREFERENCE
WIFI_ON
setGlobalSettings()
修改一下设置: WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
原文:http://www.cnblogs.com/dongweiq/p/5089659.html