注:本文是原创翻译Android 6.0 Changes一文,附上原文地址:
https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-runtime-permissions
**Introduction**
Along with new features and capabilities, Android 6.0 (API level 23) includes a variety of system changes and API behavior changes. This document highlights some of the key changes that you should understand and account for in your apps. If you have previously published an app for Android, be aware that these changes in the platform affect your app.
伴随着新的特性和功能的产生,Android 6.0 发生了一系列的系统和API实现的变化。这篇文章,主要是介绍那些,在你开发app时,有必要明白和理解的关键性变化。如果你之前有开发过Android的经验,那你得关心一下,这些修改将会对你的app所产生的影响。
**Runtime Permissions**
This release introduces a new permissions model, where users can now directly manage app permissions at runtime. This model gives users improved visibility and control over permissions, while streamlining the installation and auto-update processes for app developers. Users can grant or revoke permissions individually for installed apps.
On your apps that target Android 6.0 (API level 23) or higher, make sure to check for and request permissions at runtime. To determine if your app has been granted a permission, call the new checkSelfPermission() method. To request a permission, call the new requestPermissions() method. Even if your app is not targeting Android 6.0 (API level 23), you should test your app under the new permissions model.
For details on supporting the new permissions model in your app, see Working with System Permissions. For tips on how to assess the impact on your app, see Permissions Best Practices.
Android 6.0 引进了新的权限模式。现在,通过这个模式,可以使得用户在app运行的过程中,直接的管理app的权限,它也提供给用户更为直观的管理权限功能,以及提供一体化的安装和自动更新程序给开发者。对于用户来说,他还可以在安装app的时候,直接地赋予或拒绝权限。
如果你的app的target值在23或者更高,那请确保你是在app的运行过程中,才检查和请求权限的。在此基础上,如果你想判断app是否拥有某个权限,可以调用*[checkSelfPermission()](https://developer.android.com/reference/android/content/Context.html#checkSelfPermission%28java.lang.String%29)*方法。如果你想为app申请某个权限,则可以通过调用 *[requestPermissions()](https://developer.android.com/reference/android/app/Activity.html#requestPermissions%28java.lang.String%5B%5D,%20int%29)* 方法来实现。即使你的App targeting 并不是23,你也应该测试一下你的app在新的权限模式下的运行效果。
关于如何在你的app上,更好的支持新的权限管理模式的详细介绍,请看 [Working with System Permission](https://developer.android.com/training/permissions/index.html)一文。对于如何使你的app更好的兼容新模式,建议你去看看[Permissions Best Practices](https://developer.android.com/training/permissions/best-practices.html#testing)。
**Doze and App Standby**
This release introduces new power-saving optimizations for idle devices and apps. These features affect all apps so make sure to test your apps in these new modes.
Doze: If a user unplugs a device and leaves it stationary, with its screen off, for a period of time, the device goes into Doze mode, where it attempts to keep the system in a sleep state. In this mode, devices periodically resume normal operations for brief periods of time so that app syncing can occur and the system can perform any pending operations.
App Standby: App Standby allows the system to determine that an app is idle when the user is not actively using it. The system makes this determination when the user does not touch the app for a certain period of time. If the device is unplugged, the system disables network access and suspends syncs and jobs for the apps it deems idle.
To learn more about these power-saving changes, see Optimizing for Doze and App Standby.
同样地,Android 6.0 也引进了新的省电模式(一共两种,一种针对设备,一种针对设备上的app),主要是用来针对那些处于“空闲状态”的设备(手机、平板、车载)和app。这个省电模式,将会影响所有的app。所以,请确保在这个省电模式下,有测试过你的app。
Doze: 如果用户的设备处于非充电状态,并且它的屏幕已经关闭了一段时间。那么,设备将会自动进入Doze模式,它会试图让系统处于一种休眠状态。在这种模式下,设备会不定期地,在短时间内重启一些普通的操作,来使app可以同步数据,以及让Android系统执行一些应该做的事情。
App Standby: 这个模式,允许系统,在用户没有再继续操作app的情况下,决定哪一个app是处于空闲状态。系统会通过监听用户在一段时间内,是否没有再操作app,来判定某一个app是否是处于空闲状态。当设备处于非充电状态,系统将会断开网络连接,并中断所有app的数据同步和工作(相当于认为设备是空闲的)。
为习更多的有关省电模式的修改,可以看[Optimizing for Doze and App Standby](https://developer.android.com/training/monitoring-device-state/doze-standby.html).
**Apache HTTP Client Removal**
Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead. This API is more efficient because it reduces network use through transparent compression and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you must first declare the following compile-time dependency in your build.gradle file:
```
android {
useLibrary 'org.apache.http.legacy'
}
```
Android 6.0 取消了对 Apache HTTP client的支持。如果你的app,正在使用这个类的API进行网络请求,并且你的app的targets在9及以上。那么,你应该使用[HttpURLConnection](https://developer.android.com/reference/java/net/HttpURLConnection.html) 类来代替。因为,这个类的API可以更加有效率的进行网络请求。而这主要体现在,它可以减少网络传输包的大小和响应缓存,并且可以使网络请求所耗费的电量,降到最小。如果,你还是想要在6.0上,继续使用Apache HTTP的api。那你必须在你的build.gradle文件里,添加如下代码:
```
android {
useLibrary 'org.apache.http.legacy'
}
```
**BoringSSL**
Android is moving away from OpenSSL to the BoringSSL library. If you’re using the Android NDK in your app, don't link against cryptographic libraries that are not a part of the NDK API, such as libcrypto.so and libssl.so. These libraries are not public APIs, and may change or break without notice across releases and devices. In addition, you may expose yourself to security vulnerabilities. Instead, modify your native code to call the Java cryptography APIs via JNI or to statically link against a cryptography library of your choice.
Android 系统正在逐步使用BoringSSL库来代替OpenSSL库的使用。如果你的app,涉及到NDK的开发,那请不要再使用cryptographic的库了。因为,这些库并不属于NDK的API的一部分,比如libcrypto.so 和libssl.so。这些库,也不属于公共的通用API。所以,有可能会在版本迭代的过程中,被修改和删除掉,而这并不会有任何通知告诉你,它们已经被修改或删除了。除此之外,这也会导致你自己将自己的安全缺陷暴露出来(没搞过NDK开发,不知道暴的啥安全缺陷)。所以,为了避免上述情况的发生,取而代之的做法是,你应该修改本地的代码,通过JNI来调用Java的cryptography库的api。或者,通过静态链接,来调用你所需要的cryptography库。
**Access to Hardware Identifier**
To provide users with greater data protection, starting in this release, Android removes programmatic access to the device’s local hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods now return a constant value of 02:00:00:00:00:00.
To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions:
WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()
Note: When a device running Android 6.0 (API level 23) initiates a background Wi-Fi or Bluetooth scan, the operation is visible to external devices as originating from a randomized MAC address.
为了给用户提供更好的数据保护,从Android 6.0开始,app在使用WIFI和蓝牙API的时候,Android将不会自动授权访问设备的本地硬件标识(MAC地址)。如果你想调用WifiInfo.getMacAddress() 和 BluetoothAdapter.getAddress()方法来获取MAC地址,那现在,得到的将是一个常量值: 02:00:00:00:00:00.
如果想通过,蓝牙和WIFI的扫描,来获取附近的外部设备的硬件标识。你必须声明下面的两个权限之一: ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION permissions:
WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()
注: 当一个运行在6.0系统的机子,在后台进行WIFI或蓝牙扫描时,你的这个操作,将会在其它手机上,以一个随机的MAC地址的形式,展现出来。
**Notifications**
This release removes the Notification.setLatestEventInfo() method. Use the Notification.Builder class instead to construct notifications. To update a notification repeatedly, reuse the Notification.Builder instance. Call the build() method to get updated Notification instances.
The adb shell dumpsys notification command no longer prints out your notification text. Use the adb shell dumpsys notification --noredact command instead to print out the text in a notification object.
AudioManager Changes
注:
1、关于权限管理,现在大部分的4.0+和5.0+的机子,都能够实现安装时权限授予和运行过程中授予的功能了(也有可能是产商自已定制,非安卓自带)。
2、关于省电管理。App Standby 段里,关于设备处于非充电状态,就会自动断网和中断所有app的数据同步和工作。这有点夸张,不知道是不是我翻译的有问题。如果处于锁屏状态,那还正常,也有可能是原文写少了。
先翻译这部分,剩下的明天,再翻译。