Android 12 适配攻略
疫情又又又又又來了,疫情封控居家辦公已經兩周了,希望疫情快點過去?。
接下來進入今天的主題👉 Android 12。
首語
2022年2月11日,谷歌發布了首個 Android 13 開發者預覽版。2022年7月,發布了Beta 4版本,接下來就是Final Relase版本了。是時候適配一波Android12了,為后面項目適配鋪平道路。
介紹
2021年2月,谷歌發布了首個 Android 12開發者預覽版,2021年10月5日谷歌發布Android 12正式版。
使用 Material You 打造的全新系統界面,富有表現力、活力和個性。使用重新設計的微件、AppSearch、游戲模式和新的編解碼器擴展您的應用。支持隱私信息中心和大致位置等新的保護功能。使用富媒體內容插入功能、更簡便的模糊處理功能、經過改進的原生調試功能等提高工作效率。
行為變更
應用啟動畫面
從Android 12開始,所有的App在每次啟動時(特指冷啟動與溫啟動),系統都會為我們加上一個默認的啟動畫面。
啟動畫面主要由4個元素組成
- 應用圖標:可以是靜態或動畫形式。默認情況下,使用Launcher圖標。
- 圖標背景:可選,在圖標與窗口背景之間需要更高的對比度時很有用。
- 前景遮罩:可選,前景的 ? 將被遮蓋。
- 窗口背景:不透明的單色,默認是所設置主題的windowBackground。
外觀更改
- 背景填充
- 中心圖標替換
如果通過AnimationDrawable和AnimatedVectorDrawable實現動畫效果,還需要設置windowSplashScreenAnimationDuration,以在顯示啟動頁面的同時播放動畫。
<item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>- 啟動畫面圖標動畫的時長
- 啟動畫面圖標后面的背景
- 啟動畫面底部的圖片
- 啟動畫面在初始化數據加載完關閉場景
- 自定義關閉啟動畫面的動畫
- 計算動畫的剩余時長
用戶使用App時會在視覺上感覺多個啟動畫面,可以通過Jetpack的SplashScreen庫進行定制。
implementation 'androidx.core:core-splashscreen:1.0.0-alpha01'啟動頁調用splashScreen.setKeepVisibleCondition{true}使得默認的啟動畫面持續覆蓋原有的啟動頁,直到廣告頁開始顯現時,才調用splashScreen.setKeepVisibleCondition{false}讓頁面重新顯示,以此實現平穩過渡。
組件導出
以Android 12為目標平臺的App,如果其包含的四大組件中使用到了Intent過濾器(intent-filter),則必須顯式聲明 android:exported 屬性,否則App將無法在Android 12及更高系統版本的設備上安裝
Manifest中Activity標簽未設置android:exported屬性error如下:
As of Android 12, android:exported must be set; use true to make the activity available to other apps, and false otherwise. For launcher activities, this should be set to true.
意思大概是:從 Android 12 開始,必須設置 android:exported;使用 true 使Activity可用于其他應用程序,否則使用 false。對于啟動Activity,這應該設置為 true。
Merged Manifest也會出現Merging Errors:
Error: android:exported needs to be explicitly specified for . Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details. Android12Test.app main manifest (this file)
這里有個棘手的問題是:依賴的第三方庫使用到了intent-filter。
解決方案:打包時會合并多個Module的AndroidManifest.xml文件,可以通過Gradle腳本,在打包過程中檢索合并后的AndroidManifest.xml使用到intent-filter但沒有聲明android:exported屬性的四大組件,動態添加android:exported屬性。
腳本方案參考如下:http://events.jianshu.io/p/1913b48f2dad
安全和隱私設置
大致位置
Android提供了兩種不同精確度的位置權限,分別是:
-
ACCESS_COARSE_LOCATION(大致位置)
提供設備位置的估算值,將范圍限定在大約 1.6 公里(1 英里)內
-
ACCESS_FINE_LOCATION(確切位置)
通常將范圍限定在大約 50 米(160 英尺)內,有時精確到幾米(10 英尺)范圍以內
在以Android 12 系統的APP上,請求ACCESS_FINE_LOCATION權限時,系統權限對話框會提供兩個選項,即允許App獲取確切位置,還是僅允許獲取大致位置。
用戶拒絕提供確切位置后,可再次請求獲取確切位置。
在這次請求前可給用戶添加權限說明來幫助獲取確切位置,當然App也要做好大概位置的業務處理。
麥克風和攝像頭切換開關
以Android 12為目標平臺的App,用戶狀態欄新增麥克風使用權限和攝像頭使用權限,可以一鍵啟用/停用。
如果在畫面錄制過程中,關閉攝像頭使用權限時,錄制的會是空白畫面;如果在聲音錄制過程中,關閉麥克風使用權限時,錄制的會是無聲音頻。
官網提供了設備是否支持麥克風和攝像頭切換開關的代碼。
val sensorPrivacyManager = applicationContext.getSystemService(SensorPrivacyManager::class.java)as SensorPrivacyManager val supportsMicrophoneToggle = sensorPrivacyManager.supportsSensorToggle(Sensors.MICROPHONE) val supportsCameraToggle = sensorPrivacyManager.supportsSensorToggle(Sensors.CAMERA)SensorPrivacyManager類提供麥克風和攝像頭切換開關的信息,但由于是SystemApi( 調用系統API就必須要系統簽名),無法調用。
@SystemApi @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY) public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) {return isSensorPrivacyEnabled(sensor, UserHandle.USER_CURRENT); }如果用戶主動關閉了攝像頭或麥克風的使用權限,那么當下次App再需要啟動攝像頭或麥克風時,系統就會提醒用戶,相關硬件的使用權限已關閉,并申請重新開啟。
當應用使用麥克風或相機時,圖標會出現在狀態欄中。
Activity生命周期
以 Android 12 為目標平臺的App,在根啟動Activity(intent過濾器聲明ACTION_MAIN和CATEGORY-LAUNCHER的Activity)頁面按下返回按鈕,系統會將 Activity 及其任務移到后臺,而不是finish Activity。
自定義通知
以 Android 12 為目標平臺的App,包含自定義內容視圖的通知將不再使用完整通知區域;相反,系統會應用標準模板。為用戶提供可看到且熟悉的通知展開功能,使所有通知保持外觀一致且易于瀏覽。
所有通知都是可展開的。通常,這意味著,如果您使用的是 setCustomContentView,則還需要使用 setBigCustomContentView,以確保收起狀態和展開狀態保持一致。
權限重置
以 Android 12 為目標平臺的App,用戶幾個月未與App互動,系統會自動重置授予的所有權限并將您的應用置于休眠狀態。
待處理 intent 可變性
以 Android 12 為目標平臺的App,構建PendingIntent時需要指定Flag為FLAG_IMMUTABLE(建議)或FLAG_MUTABLE二者之一,否則App將崩潰并出現以下error。
- FLAG_IMMUTABLE,指示創建的 PendingIntent 應該是不可變的標志。
- FLAG_MUTABLE,指示創建的 PendingIntent 應該是可變的標志。
對于使用的第三方庫未正確指定Flag的問題,等待庫更新或者使用同樣功能的正確指定flag的庫進行替代。
前臺服務啟動限制
以 Android 12 為目標平臺的App,無法在后臺運行時啟動前臺服務,否則會引發異常。
if (fgRequired) {logFgsBackgroundStart(r);if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {String msg = "startForegroundService() not allowed due to "+ "mAllowStartForeground false: service "+ r.shortInstanceName;Slog.w(TAG, msg);showFgsBgRestrictedNotificationLocked(r);logFGSStateChangeLocked(r,FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED,0);if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) {throw new ForegroundServiceStartNotAllowedException(msg);}return null;}}考慮改用WorkManager在App后臺運行時,啟動完成加急工作。
通過adb命令,監控App是否有后臺啟動前臺服務的行為,一旦發現,通知欄推送一條通知,定位到代碼處。
精確的鬧鐘權限
以Android 12為目標平臺的App,通過AlarmManager來設置定時任務,并且設置的是精確的鬧鐘(使用了setAlarmClock()、setExact()、setExactAndAllowWhileIdle()這幾種方法),需要聲明SCHEDULE_EXACT_ALARM權限聲明且授權,否則會有如下error。
Caused by: java.lang.SecurityException: Caller com.yhj.Android12Test needs to hold android.permission.SCHEDULE_EXACT_ALARM to set exact alarm.因此在AndroidManifest.xml清單文件中聲明 SCHEDULE_EXACT_ALARM 權限,代碼判斷是否具有設置鬧鐘的權限。
private val singlePermissions=registerForActivityResult(ActivityResultContracts.RequestPermission()){isGranted ->when {isGranted -> Log.e("yhj", "申請成功")!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.SCHEDULE_EXACT_ALARM) -> Log.e("yhj", "拒絕且不在詢問")else -> Log.e("yhj", "拒絕")}}通知 trampoline 限制
在配置通知的點按行為時,可能會通過PendingIntent來啟動一個Service或BrocastReceiver。以Android 12為目標平臺的App,如果嘗試在Service或BrocastReceiver中內調用 startActivity(),系統會阻止該Activity啟動,并在 Logcat 中顯示以下消息:
Indirect notification activity start (trampoline) from PACKAGE_NAME,
this should be avoided for performance reasons.
可通過adb命令識別在點按通知后,識別哪個Service或BrocastReceiver調用了startActivity(),并輸出相關信息到Logcat,
adb shell dumpsys activity service \ com.android.systemui/.dump.SystemUIAuxiliaryDumpServiceToast提示重新設計
文本旁邊顯示應用圖標,上限為兩行文本。
新功能和API
Material You
Android 12 引入了一種名為Material you的新設計語言,可以理解它是Material Design的替代品。
依賴
implementation 'com.google.android.material:material:1.8.0-alpha01'提供一個官方文檔及源碼供使用學習。
- Material You 官網:https://material.io/blog/announcing-material-you
- 源碼地址:https://github.com/material-components/material-components-android
- Geting started:https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md
圓角API
Android 12 引入了 RoundedCorner 和 WindowInsets.getRoundedCorner(int position),它們可以提供圓角的半徑和中心點。
通知的豐富圖片支持
以Android 12為目標平臺的App,可以通過在 MessagingStyle()和 BigPictureStyle()通知中提供動畫圖片來豐富應用的通知體驗。此外,您的應用現在還可以讓用戶在從通知欄回復消息時發送圖片消息。
藍牙權限
Android 12 引入了 BLUETOOTH_SCAN(尋找藍牙設備)、BLUETOOTH_ADVERTISE(當前設備可被其他藍牙設備發現)和 BLUETOOTH_CONNECT(與已配對的藍牙設備通信)權限。
自動更新應用
使用 PackageInstallerAPI 的應用引入了 setRequireUserAction()方法。此方法可讓安裝程序應用執行應用更新而無需用戶確認操作。
設備芯片組信息
Android 12 向 android.os.Build 添加了兩個常量, Build.SOC_MANUFACTURER(設備主要片上系統的制造商)和 Build.SOC_MODEL (設備上主要片上系統的型號名稱)
總結
更多變更細節參考官網:https://developer.android.google.cn/about/versions/12。
總結
以上是生活随笔為你收集整理的Android 12 适配攻略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 万彩办公大师多页PDF文档去掉空白部分合
- 下一篇: RDS-TMC(Traffic Mess