前言
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_LOG
、WRITE_CALL_LOG
和 PROCESS_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"
...
>
結語
以上,完結!