前幾天收到了公司的郵件,要求下一期版本中升級targetSDK29,也就是適配Android10。
想着這周自己的手機也剛剛升級到Android10系統,趁着趁着興奮就趕緊來研究一下AndroidQ吧!
1.框架遷移步驟
從AndroidStudio中Tools > SDK Manager > SDK Platforms中選擇Android Q SDK (Api Level 29) 下載並且安裝即可。
2.更新Android工程配置
首先在gradle.properties中開啓支持Android 10的支持,示例如下:
android.useAndroidX=true
android.enableJetifier=true
android {
compileSdkVersion 29
buildToolsVersion 29.0.2
defaultConfig {
targetSdkVersion 29
}
...
}
3.遷移Support包至Android X
使用AS工具:refactor -> Migrate to Android X
手動修改包名,參考如下映射關係
可以參考官網對應的轉換關係:
https://developer.android.com/jetpack/androidx/migrate/artifact-mappings
4.處理升級android Q帶來的行爲變更
1.Android Q中的媒體資源讀寫
隱私是Android 10的核心關注點,更嚴格的權限,並限制了數據應用程序的使用。針對媒體資源讀寫,有以下地方需要注意:
掃描系統相冊、視頻等,圖片、視頻選擇器都是通過ContentResolver來提供;
//公有目錄只能通過Content Uri+id的方式訪問,以前的File路徑全部無效,如果是Video,記得換成MediaStore.Videos
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
path = MediaStore.Images.Media
.EXTERNAL_CONTENT_URI
.buildUpon()
.appendPath(String.valueOf(id)).build().toString();
}
判斷公有目錄文件是否存在,自Android Q開始公有目錄File API都失效,不能直接通過new File(path).exists();判斷公文件是否存在;
Copy或者Download文件到公有目錄也需要注意;
保存圖片相關,通過MediaStore保存,兼容AndroidQ,保存成功自動添加到相冊數據庫,無需再發送廣播告訴系統插入相冊;
2.EditText默認不獲取焦點,不自動彈出鍵盤
當SDK版本大於API 28時,且設備版本爲Android P以上版本,解決方法在onCreate中加入如下代碼,可獲得焦點,如需彈出鍵盤可延遲下:
mEditText.post(() -> {
mEditText.requestFocus();
mEditText.setFocusable(true);
mEditText.setFocusableInTouchMode(true);
});
3.第三方分享圖片等操作,都只能通過MediaStore等API
直接使用文件路徑的,如QQ圖片分享,都需要注意,這是不可行的,都只能通過MediaStore等API,拿到Uri來操作。
4.設備硬件信息讀取限制
在Android10中, 系統不允許普通App請求android.permission.READ_PHONE_STATE權限, 故新版App需要取消該動態權限的申請。
當前獲取設備唯一ID的方式爲使用SSAID, 若獲取爲空的話則使用UUID.randomUUID().toString()獲得一個隨機ID並存儲起來, 該ID保證唯一, 但App卸載重裝之後就會改變。
SSAID的獲取方式爲:
String id = android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
5.Region.Op相關異常
這個問題主要是SDK版本大於API 28上調用canvas出現的崩潰“Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed“,當目標版本從Android P開始,Canvas.clipPath(@NonNull Path path, @NonNull Region.Op op) ; 已經被廢棄,而且是包含異常風險的廢棄API,只有 Region.Op.INTERSECT 和 Region.Op.DIFFERENCE 得到兼容,幾乎所有的博客解決方案都是如下簡單粗暴:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
canvas.clipPath(path);
} else {
canvas.clipPath(path, Region.Op.XOR);// REPLACE、UNION 等
}
6.限制程序訪問剪貼板
Android Q 包含了名爲“READ_CLIPBOARD_IN_BACKGROUND”的新權限。 顧名思義,新的權限將阻止隨機的後臺應用程序訪問剪貼板內容。