Android應用在9.0版本手機或者target設置28需要關注的問題

前言

app在設置target=28之後,在華爲的一款9.0的手機上測試,出現大面積的圖片顯示不出來的問題(少部分正常顯示),在調試過程中發現,不能正常顯示的圖片的url都是http的,能正常顯示的圖片都是https,由此找到問題原因,藉此總結一下Android9.0版本對app的一些限制,還有在設置target爲28之後,需要對9.0版本做的適配工作,這裏不說9.0的功能,只瞭解對開發者需要注意的點。

Android9.0設備的限制

下邊是Android設備的版本爲9.0對應用的一些限制,不管你的target是多少,都會有這些限制!
我這裏只瞭解一般開發比較常用的,全部內容請參考:android-9.0-changes-all

隱私權變更

後臺對傳感器的訪問受限

Android 9 限制後臺應用訪問用戶輸入和傳感器數據的能力。如果應用進入後臺,則:

  • 不能訪問麥克風和攝像頭
  • 使用連續報告模式的傳感器(例如加速度計和陀螺儀)不會接收事件。
  • 使用變化或一次性報告模式的傳感器不會接收事件。

就是說比如直播應用,或者導航應用,需要用到手機設備的麥克風,攝像頭或者其他傳感器,一旦應用進入後臺,則收不到傳感器的數據。

對此的解決方案,就是使用前臺服務。在你的service中調用startForeground(NOTIFICATION_ID, notification);,方法有兩個參數:唯一標識通知的整型數和狀態欄的 Notification,這樣服務就會運行在前臺,我們在通知欄就能看到應用。

限制訪問通話記錄和電話號碼

對於需要訪問通話敏感信息(如讀取通話記錄和識別電話號碼)的應用,需要請求權限組CALL_LOG,否則會發生SecurityException

一般對於類型通訊管家這種應用,就直接使用運行時權限請求CALL_LOG權限組就完事了,CALL_LOG權限組包括READ_CALL_LOGWRITE_CALL_LOGPROCESS_OUTGOING_CALLS

對使用非 SDK 接口的限制

這是一條讓人心情很沉重的限制,看完我都快哭了!😭

看一下官方是怎麼說的:

爲幫助確保應用穩定性和兼容性,此平臺對某些非 SDK 函數和字段的使用進行了限制;無論您是直接訪問這些函數和字段,還是通過反射或 JNI 訪問,這些限制均適用。 在 Android 9 中,您的應用可以繼續訪問這些受限的接口;該平臺通過 toast 和日誌條目提醒您注意這些接口。

這意味着之前的好多黑科技在Android9.0之後可能就不能用了!
在 Android 9(API 級別 28)中,非受限灰名單中的非 SDK 接口稱爲淺灰名單,而受限灰名單中的非 SDK 接口稱爲深灰名單。也就是說,如果我們訪問了深灰名單中的api,那就gg了!
關於更多內容,可以參考:針對非 SDK 接口的限制

現在強制執行 FLAG_ACTIVITY_NEW_TASK 要求

在 Android 9 中,您不能從非 Activity 環境中啓動 Activity,除非您傳遞 Intent 標誌 FLAG_ACTIVITY_NEW_TASK。 如果您嘗試在不傳遞此標誌的情況下啓動 Activity,則該 Activity 不會啓動,系統會在日誌中輸出一則消息。

之前遇到在一個service中啓動一個activity,在Android9.0上失效,原因就是沒有添加FLAG_ACTIVITY_NEW_TASK

Apache HTTP 客戶端棄用影響採用非標準 ClassLoader 的應用

在 Android 6.0 中,取消了對 Apache HTTP 客戶端的支持。

在6.0中,sdk移除了HttpClient相關的api。而推薦使用HttpURLConnection

此變更對大多數不以 Android 9 或更高版本爲目標的應用沒有任何影響。 不過,此變更會影響使用非標準 ClassLoader 結構的某些應用,即使這些應用不以 Android 9 或更高版本爲目標平臺。

這些內容什麼意思呢?
就是說在6.0移除了 Apache HTTP 客戶端,當然我們知道要想用還可以用,在build.gradle中添加:

android {
    useLibrary 'org.apache.http.legacy'
}

但是從9.0開始,org.apache.http.legacy 庫將從 bootclasspath 中刪除。
所以,在9.0版本之前想用,引用方式相同,只是不能顯式地指定系統的ClassLoader去加載apache-http的類,通過應用的ClassLoader去加載。在9.0之後想用,要在Manifest.xml中添加:

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

當然,說實話,現在很少有人會有Apache HTTP了!😁

target設置爲28及以上的限制

同樣的,下邊只瞭解常用的,需要了解全部可以參考:
行爲變更:以 API 級別 28+ 爲目標的應用

前臺服務

針對 Android 9 或更高版本並使用前臺服務的應用必須請求 FOREGROUND_SERVICE 權限。 這是普通權限,因此,系統會自動爲請求權限的應用授予此權限。

如果針對 Android 9 或更高版本的應用嘗試創建一個前臺服務且未請求 FOREGROUND_SERVICE,則系統會引發SecurityException

構建序列號棄用

在 Android 9 中,Build.SERIAL 始終設置爲"UNKNOWN"以保護用戶的隱私。
如果應用需要訪問設備的硬件序列號,您應請求 READ_PHONE_STATE權限,然後調用getSerial()

Apache HTTP 客戶端棄用

在 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"/>

注:擁有最低 SDK 版本 23 或更低版本的應用需要 android:required=“false” 屬性,因爲在 API 級別低於 24 的設備上,org.apache.http.legacy 庫不可用。 (在這些設備上,Apache HTTP 類在 bootclasspath 中提供。)

這塊內容,在上邊已經提到過!

界面變更

視圖焦點

0 面積的視圖(即寬度或高度爲 0)再也不能被聚焦。

此外,Activity 不再隱式分配觸摸模式下的初始焦點。 而是由您顯式請求初始焦點(如若需要的話)。

CSS RGBA 十六進制值處理

以 Android 9 或更高版本爲目標的應用必須支持草案版 CSS 顏色模塊級別 4 的行爲,用於處理 4 和 8 個十六進制數字 CSS 顏色。

例如,對於以 API 級別 27 或更低版本爲目標平臺的應用,顏色 #80ff8080 目前在 WebView 中被渲染爲不透明淺紅色 (#ff8080)。 先導部分(Android 會將其解讀爲 Alpha 部分)目前被忽略。 如果某個應用以 API 級別 28 或更高版本爲目標,則 #80ff8080 將被解讀爲 50% 透明淺綠 (#80ff80)。

也就是說,28以前顏色解析爲ARGB,28之後變成了RGBA!

HTTP請求被禁止

Android9.0之後,默認禁止不安全的HTTP請求。
這個就是文章開頭所提到的問題!
解決方案:
在res->xml文件夾下新建network_security_config.xml:

<network-security-config>
  <base-config cleartextTrafficPermitted="true" />
</network-security-config>

然後在manifest.xml中的application標籤中引入:

<application
...
android:networkSecurityConfig="@xml/network_security_config"
...
>

結語

以上,完結!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章