Skip to content

Android 9.0行为变更以及适配注意事项

shewenbiao edited this page Apr 5, 2021 · 2 revisions

List

当应用在 Android 9 平台上运行时,以下行为变更将影响所有应用,无论这些应用以哪个 API 级别为目标。

官方原文链接:https://developer.android.google.cn/about/versions/pie/android-9.0-changes-all

以下列举了一些主要行为变更, 其他行为变更可去官网查看

Android 9 引入 CALL_LOG 权限组并将 READ_CALL_LOG、WRITE_CALL_LOG 和 PROCESS_OUTGOING_CALLS 权限移入该组。 在之前的 Android 版本中,这些权限位于 PHONE 权限组。

对于需要访问通话敏感信息(如读取通话记录和识别电话号码)的应用,该 CALL_LOG 权限组为用户提供了更好的控制和可见性。

如果您的应用需要访问通话记录或者需要处理去电,则您必须向 CALL_LOG 权限组明确请求这些权限。 否则会发生 SecurityException。

在未首先获得 READ_CALL_LOG 权限的情况下,除了应用的用例需要的其他权限之外,运行于 Android 9 上的应用无法读取电话号码或手机状态。

与来电和去电关联的电话号码可在手机状态广播(比如来电和去电的手机状态广播)中看到,并可通过 PhoneStateListener 类访问。 但是,如果没有 READ_CALL_LOG 权限,则 PHONE_STATE_CHANGED 广播和 PhoneStateListener 提供的电话号码字段为空。

要从手机状态中读取电话号码,请根据您的用例更新应用以请求必要的权限:

  • 要通过 PHONE_STATE Intent 操作读取电话号码,同时需要 READ_CALL_LOG 权限和 READ_PHONE_STATE 权限。
  • 要从 onCallStateChanged() 中读取电话号码,只需要 READ_CALL_LOG 权限。 不需要 READ_PHONE_STATE 权限。

在 Android 9 中,应用进行 Wi-Fi 扫描的权限要求比之前的版本更严格。

成功调用 WifiManager.startScan() 需要满足以下所有条件:

  • 应用拥有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限。
  • 应用拥有 CHANGE_WIFI_STATE 权限。
  • 设备已启用位置信息服务(位于设置 > 位置信息下)。

类似的限制也适用于 getConnectionInfo() 函数,该函数返回描述当前 Wi-Fi 连接的 WifiInfo 对象。 如果调用应用具有以下权限,则只能使用该对象的函数来检索 SSID 和 BSSID 值:

  • ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

检索 SSID 或 BSSID 还需要在设备上启用位置服务(在 Settings > Location 下)。

从 Wi-Fi 服务函数中移除的信息

在 Android 9 中,下列事件和广播不接收用户位置或个人可识别数据方面的信息:

  • WifiManager 中的 getScanResults() 和 getConnectionInfo() 函数。
  • WifiP2pManager 中的 discoverServices() 和 addServiceRequest() 函数。
  • NETWORK_STATE_CHANGED_ACTION 广播。

Wi-Fi 的 NETWORK_STATE_CHANGED_ACTION系统广播不再包含 SSID(之前为 EXTRA_SSID)、BSSID(之前为 EXTRA_BSSID)或连接信息(之前为 EXTRA_NETWORK_INFO)。 如果应用需要此信息,请改为调用 getConnectionInfo()。

官方原文链接:https://developer.android.google.cn/about/versions/pie/android-9.0-changes-28

以下行为变更仅影响以 API 级别 28 或更高级别为目标平台的应用。将 targetSdkVersion 设为 API 级别 28 或更高级别的应用必须进行修改,以便适当地支持这些行为.

以下列举了一些主要行为变更, 其他行为变更可去官网查看

如果应用以 Android 9 或更高版本为目标平台并使用前台服务,则必须请求 FOREGROUND_SERVICE 权限。这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

如果以 Android 9 或更高版本为目标平台的应用尝试创建前台服务且未请求 FOREGROUND_SERVICE,则系统会抛出 SecurityException。

在 Android 9 中,Build.SERIAL 始终设为 "UNKNOWN",以保护用户隐私。

如果您的应用需要访问设备的硬件序列号,您应改为请求 READ_PHONE_STATE 权限,然后调用 getSerial()。

如果您的应用以 Android 9 或更高版本为目标平台,则 isCleartextTrafficPermitted() 方法默认返回 false。如果您的应用需要针对特定网域启用明文,则您必须在应用的网络安全配置中,针对这些网域明确将 cleartextTrafficPermitted 设置为 true。

在 Android 9 中,为改善应用稳定性和数据完整性,应用无法再让多个进程共享一个 WebView 数据目录。通常情况下,此类数据目录会存储 Cookie、HTTP 缓存以及其他与网络浏览有关的持久性和临时性存储。

在大多数情况下,您的应用应仅在一个进程中使用 android.webkit 软件包中的类(如 WebView 和 CookieManager)。例如,您应该将使用 WebView 的所有 Activity 对象移入同一进程。您可以通过在应用的其他进程中调用 disableWebView(),更严格地执行“仅限一个进程”规则。该调用可防止 WebView 在这些其他进程中被错误地初始化,即使是从依赖内容库进行的调用也能防止。

如果您的应用必须在多个进程中使用 WebView 实例,则您必须先使用 WebView.setDataDirectorySuffix() 方法为每个进程指定唯一的数据目录后缀,然后再在相应进程中使用 WebView 的给定实例。该方法会将每个进程的网络数据放入应用数据目录内其自己的目录中。

注意:即使您使用 setDataDirectorySuffix(),系统也不会跨应用的进程界限共享 Cookie 以及其他网络数据。如果应用中的多个进程需要访问同一网络数据,您需要自行在这些进程之间复制该数据。例如,您可以调用 getCookie() 和 setCookie(),以在不同的进程之间手动传输 Cookie 数据。

在 Android 6.0 中,我们移除了对 Apache HTTP 客户端的支持。从 Android 9 开始,该内容库已从 bootclasspath 中移除,且默认情况下应用无法使用它。

要继续使用 Apache HTTP 客户端,以 Android 9 及更高版本为目标平台的应用可以向其 AndroidManifest.xml 添加以下内容:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

  • 1.1 在9.0上出现java.lang.SecurityException: Permission Denial: startForeground from pid=32221, uid=10642 requires android.permission.FOREGROUND_SERVICE
  • 1.2 在android 8.0上会出现java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
  • 1.3 在Android 9.0上,隐私政策和服务条款页面打不开(webview显示的错误是net::ERR_CLEARTEXT_NOT_PERMITTED)
  • 1.4 有的Lottie动画出现java.lang.IllegalArgumentException: Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed,该错误在Lottie github项目的issue上有(https://github.com/airbnb/lottie-android/issues/802)
  • 1.5 在9.0上调用系统intent去卸载应用不起作用
  • 1.6 Android 9.0上出现java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/ProtocolVersion问题
Reference

Android项目-target-sdk升级到28遇到的一些问题以及解决方案

Clone this wiki locally