原文链接:https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html
Android 6.0(API 级别 23)除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更。本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更。
如果您之前发布过 Android 应用,请注意您的应用可能受到这些平台变更的影响。
此版本引入了一种新的权限模式,如今,用户可直接在运行时管理应用权限。这种模式让用户能够更好地了解和控制权限,同时为应用开发者精简了安装和自动更新过程。用户可为所安装的各个应用分别授予或撤销权限。
对于以 Android 6.0(API 级别 23)或更高版本为目标平台的应用,请务必在运行时检查和请求权限。要确定您的应用是否已被授予权限,请调用新增的 checkSelfPermission()
方法。要请求权限,请调用新增的 requestPermissions()
方法。即使您的应用并不以 Android 6.0(API 级别 23)为目标平台,您也应该在新权限模式下测试您的应用。
如需了解有关在您的应用中支持新权限模式的详情,请参阅使用系统权限。如需了解有关如何评估新模式对应用的影响的提示,请参阅权限最佳做法。
此版本引入了针对空闲设备和应用的最新节能优化技术。这些功能会影响所有应用,因此请务必在这些新模式下测试您的应用。
要详细了解这些节能变更,请参阅对低电耗模式和应用待机模式进行针对性优化。
Android 6.0 版移除了对 Apache HTTP 客户端的支持。如果您的应用使用该客户端,并以 Android 2.3(API 级别 9)或更高版本为目标平台,请改用 HttpURLConnection
类。此 API 效率更高,因为它可以通过透明压缩和响应缓存减少网络使用,并可最大限度降低耗电量。要继续使用 Apache HTTP API,您必须先在 build.gradle
文件中声明以下编译时依赖项:
android { useLibrary 'org.apache.http.legacy' }
Android 正在从使用 OpenSSL 库转向使用 BoringSSL 库。如果您要在应用中使用 Android NDK,请勿链接到并非 NDK API 组成部分的加密库,如 libcrypto.so
和 libssl.so
。这些库并非公共 API,可能会在不同版本和设备上毫无征兆地发生变化或出现故障。此外,您还可能让自己暴露在安全漏洞的风险之下。请改为修改原生代码,以通过 JNI 调用 Java 加密 API,或静态链接到您选择的加密库。
为给用户提供更严格的数据保护,从此版本开始,对于使用 WLAN API 和 Bluetooth API 的应用,Android 移除了对设备本地硬件标识符的编程访问权。WifiInfo.getMacAddress()
方法和 BluetoothAdapter.getAddress()
方法现在会返回常量值 02:00:00:00:00:00
。
现在,要通过蓝牙和 WLAN 扫描访问附近外部设备的硬件标识符,您的应用必须拥有 ACCESS_FINE_LOCATION
或 ACCESS_COARSE_LOCATION
权限。
WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()
注:当运行 Android 6.0(API 级别 23)的设备发起后台 WLAN 或蓝牙扫描时,在外部设备看来,该操作的发起来源是一个随机化 MAC 地址。
此版本移除了 Notification.setLatestEventInfo()
方法。请改用 Notification.Builder
类来构建通知。要重复更新通知,请重复使用 Notification.Builder
实例。调用 build()
方法可获取更新后的 Notification
实例。
adb shell dumpsys notification
命令不再打印输出您的通知文本。请改用 adb shell dumpsys notification --noredact
命令打印输出 notification 对象中的文本。
不再支持通过 AudioManager
类直接设置音量或将特定音频流静音。setStreamSolo()
方法已弃用,您应该改为调用 requestAudioFocus()
方法。类似地,setStreamMute()
方法也已弃用,请改为调用 adjustStreamVolume()
方法并传入方向值 ADJUST_MUTE
或 ADJUST_UNMUTE
。
现在,当用户在您的应用中选择文本时,您可以在一个浮动工具栏中显示“剪切”、“复制”和“粘贴”等文本选择操作。其在用户交互实现上与为单个视图启用上下文操作模式中所述的上下文操作栏类似。
要实现可用于文本选择的浮动工具栏,请在您的现有应用中做出以下更改:
View
对象或 Activity
对象中,将 ActionMode
调用从 startActionMode(Callback)
更改为 startActionMode(Callback, ActionMode.TYPE_FLOATING)
。ActionMode.Callback
的现有实现扩展 ActionMode.Callback2
。onGetContentRect()
方法,用于提供 Rect
内容对象(如文本选择矩形)在视图中的坐标。invalidateContentRect()
方法。 请注意,如果您使用 Android 支持库 22.2 修订版,浮动工具栏不向后兼容,默认情况下 appcompat 会获得对 ActionMode
对象的控制权。这会禁止显示浮动工具栏。要在 ActionMode
中启用 AppCompatActivity
支持,请调用 getDelegate()
,然后对返回的 setHandleNativeActionModesEnabled()
对象调用 AppCompatDelegate
,并将输入参数设置为 false
。此调用会将 ActionMode
对象的控制权交还给框架。在运行 Android 6.0(API 级别 23)的设备上,框架可以支持 ActionBar
模式或浮动工具栏模式;而在运行 Android 5.1(API 级别 22)或之前版本的设备上,框架仅支持 ActionBar
模式。
此版本移除了对全局书签的支持。android.provider.Browser.getAllBookmarks()
和 android.provider.Browser.saveBookmark()
方法现已移除。同样,READ_HISTORY_BOOKMARKS
权限和 WRITE_HISTORY_BOOKMARKS
权限也已移除。如果您的应用以 Android 6.0(API 级别 23)或更高版本为目标平台,请勿从全局提供程序访问书签或使用书签权限。您的应用应改为在内部存储书签数据。
从此版本开始,Android 密钥库提供程序不再支持 DSA。但仍支持 ECDSA。
停用或重置安全锁定屏幕时(例如,由用户或设备管理员执行此类操作时),系统将不再删除需要闲时加密的密钥,但在上述事件期间会删除需要闲时加密的密钥。
此版本对 WLAN API 和 Networking API 引入了以下行为变更。
WifiConfiguration
对象的状态。系统不允许您修改或删除由用户或其他应用创建的 WifiConfiguration
对象。disableAllOthers=true
设置的 enableNetwork()
强制设备连接特定 WLAN 网络,设备将会断开与移动数据网络等其他网络的连接。在此版本中,设备不再断开与上述其他网络的连接。如果您的应用的 targetSdkVersion
为 “20”
或更低,则会固定连接所选 WLAN 网络。如果您的应用的 targetSdkVersion
为 “21”
或更高,请使用多网络 API(如 openConnection()
、bindSocket()
和新增的 bindProcessToNetwork()
方法)来确保通过所选网络传送网络流量。在此版本中,相机服务中共享资源的访问模式已从之前的“先到先得”访问模式更改为高优先级进程优先的访问模式。对服务行为的变更包括:
Camera
API 中,这会导致系统为被驱逐的客户端调用 onError()
。在 Camera2
API 中,这会导致系统为被驱逐的客户端调用 onDisconnected()
; ART 运行时环境现在可正确实现 newInstance()
方法的访问规则。此变更修正了之前版本中 Dalvik 无法正确检查访问规则的问题。如果您的应用使用 newInstance()
方法,并且您想重写访问检查,请调用 setAccessible()
方法(将输入参数设置为 true
)。如果您的应用使用 v7 appcompat 库或 v7 recyclerview 库,则您必须更新应用以使用这些库的最新版本。否则,请务必更新从 XML 引用的任何自定义类,以便能够访问它们的类构造函数。
此版本更新了动态链接程序的行为。动态链接程序现在可以识别库的 soname
与其路径之间的差异(公开错误 6670),并且现在已实现了按 soname
搜索。之前包含错误的 DT_NEEDED
条目(通常是开发计算机文件系统上的绝对路径)却仍工作正常的应用,如今可能会出现加载失败。
现已正确实现 dlopen(3) RTLD_LOCAL
标记。请注意,RTLD_LOCAL
是默认值,因此不显式使用 RTLD_LOCAL
的 dlopen(3)
调用将受到影响(除非您的应用显式使用 RTLD_GLOBAL
)。使用 RTLD_LOCAL
时,在随后通过调用 dlopen(3)
加载的库中并不能使用这些符号(这与由 DT_NEEDED
条目引用的情况截然不同)。
在之前版本的 Android 上,如果您的应用请求系统加载包含文本重定位信息的共享库,系统会显示警告,但仍允许加载共享库。从此版本开始,如果您的应用的目标 SDK 版本为 23 或更高,则系统会拒绝加载该库。为帮助您检测库是否加载失败,您的应用应该记录 dlopen(3)
失败日志,并在日志中加入 dlerror(3)
调用返回的问题描述文本。要详细了解如何处理文本重定位,请参阅此指南。
该平台现在执行的 APK 验证更为严格。如果在清单中声明的文件在 APK 中并不存在,该 APK 将被视为已损坏。移除任何内容后必须重新签署 APK。
默认情况下,现在通过 USB 端口进行的设备连接设置为仅充电模式。要通过 USB 连接访问设备及其内容,用户必须明确地为此类交互授予权限。如果您的应用支持用户通过 USB 端口与设备进行交互,请将必须显式启用交互考虑在内。
此版本包含下列针对 Android for Work 的行为变更:
setCrossProfileCallerIdDisabled()
设置为 true
可在 Google 拨号器通话记录中隐藏托管配置文件联系人。仅当您将 setBluetoothContactSharingDisabled()
设置为 false
时,才可以通过蓝牙将工作联系人随个人联系人一起显示给设备。默认情况下,它设置为 true
。addNetwork()
方法添加的配置)。WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
不为零,则用户无法再修改或删除任何由活动设备所有者创建的 WLAN 配置。用户仍可创建和修改其自己的 WLAN 配置。活动设备所有者拥有编辑或删除任何 WLAN 配置(包括并非由其创建的配置)的权限。DevicePolicyManager
API 行为的变更:
setCameraDisabled()
方法只会影响调用该方法的用户的相机;从托管配置文件调用它不会影响主用户运行的相机应用。setKeyguardDisabledFeatures()
方法现在除了可供设备所有者使用外,还可供配置文件所有者使用。 KEYGUARD_DISABLE_TRUST_AGENTS
和 KEYGUARD_DISABLE_FINGERPRINT
,它们影响配置文件上级用户的键盘锁设置。KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS
,它只影响应用在托管配置文件中生成的通知。DevicePolicyManager.createAndInitializeUser()
方法和 DevicePolicyManager.createUser()
方法已弃用。setScreenCaptureDisabled()
方法现在也会屏蔽辅助结构。 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
现在默认为 SHA-256。出于向后兼容性考虑,仍然支持 SHA-1,但未来将会取消该支持。EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
现在只接受 SHA-256。EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
已删除,因此 NFC 占位配置无法通过编程解锁受恢复出厂设置保护的设备EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
extra 在对托管设备进行 NFC 配置期间向设备所有者应用传递数据。DevicePolicyManager
权限 API 不会影响 M 之前版本的应用。ACTION_PROVISION_MANAGED_PROFILE
或 ACTION_PROVISION_MANAGED_DEVICE
intent 发起的设置流程的同步部分时,系统现在会返回 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