Android8.0适配方案
準備工作
?
將我們項目中的targetSdkVersion改為 26(8.0) 或者 27(8.1)
1運行時權限
?
首先引用官方的原文。
https://developer.android.google.cn/about/versions/oreo/android-8.0-changes#rmp
?
在 Android 8.0 之前,如果應用在運行時請求權限并且被授予該權限,系統會錯誤地將屬于同一權限組并且在清單中注冊的其他權限也一起授予應用。?
對于針對 Android 8.0 的應用,此行為已被糾正。系統只會授予應用明確請求的權限。然而,一旦用戶為應用授予某個權限,則所有后續對該權限組中權限的請求都將被自動批準。?
例如,假設某個應用在其清單中列出?READ_EXTERNAL_STORAGE?和?WRITE_EXTERNAL_STORAGE。應用請求?READ_EXTERNAL_STORAGE,并且用戶授予了該權限。如果該應用針對的是 API 級別 24 或更低級別,系統還會同時授予?WRITE_EXTERNAL_STORAGE,因為該權限也屬于同一?STORAGE?權限組并且也在清單中注冊過。如果該應用針對的是 Android 8.0,則系統此時僅會授予?READ_EXTERNAL_STORAGE;不過,如果該應用后來又請求?WRITE_EXTERNAL_STORAGE,則系統會立即授予該權限,而不會提示用戶。
?
所謂權限組如下:?
?
?
所以總結下來,如果你之前是用什么權限就去申請什么權限,那么恭喜你,這個變化不會影響到你。
?
如果你只申請了權限組中的某些權限,卻用了同組的其他權限,那么你就需要去適配一下了。
?
那么怎么適配呢,如果你去檢查之前每個申請權限的地方,未免太過麻煩。那么你可以根據你項目中的Manifest文件中需要的權限與權限組去對比,整理出你需要申請的各個權限組。比如你需要android.permission.CALL_PHONE(打電話)與android.permission.READ_PHONE_STATE(讀取手機狀態) 這兩個權限。那么你就整理出了類似下面的類。
?
public?class?PermissionGroup?{//Phone權限public?static?String[]?PHONE?=?new?String[]?{Manifest.permission.READ_PHONE_STATE,?Manifest.permission.CALL_PHONE};... }?
到時在申請權限時就可以直接獲取它,一次將它們都申請了。這樣就防止了遺漏某個權限,導致的異常。
?
2通知適配
ps:也可以參考https://mp.weixin.qq.com/s/Ez-G_9hzUCOjU8rRnsW8SA
其實8.0在通知這里變化還挺多的,比如通知渠道、通知標志、通知超時、背景顏色的等,詳細的說明可以去看官方的Android 8.0 功能和 API。
?
雖然變化很多,但是國內的機子貌似支持的不多。。。我在小米的文檔中了解到,Android 已將通知渠道的邏輯納入 Android Compatibility Definition Document (CDD) 中,意味著所有 Android 廠商都必須支持。所以我們可以放心的去適配。
?
?
通知渠道:Android 8.0 引入了通知渠道,其允許您為要顯示的每種通知類型創建用戶可自定義的渠道。用戶界面將通知渠道稱之為通知類別。
?
我個人很喜歡這個新特性。也就是說,我們可以將我們給用戶的通知進行分類,我用高德地圖app來舉例,從左到右分別是小米(MIUI10)、華為(EMUI 8.1.0)、一加(氫OS 5.1):
?
?
?
可以看到高德地圖分的很細致,分為四個組共13個類別(華為貌似對組不生效)。這樣有個好處,我們可以控制我們想收到的通知,比如我不喜歡運營活動通知,那我就可以把它關閉。
?
這樣避免大量的不必要通知,否則使得用戶覺得煩,一棒子打死。直接關閉你的允許通知。當然了,大量app都還沒有適配,適配的也都分的不是很細致,比如下圖的QQ。(沒有對比就沒有傷害)
?
?
?
當然更重要的問題是,如果不去適配,可能通知都不會彈出來。那么適配的方法如下:
?
private?void?createNotificationChannel()?{if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.O)?{NotificationManager?notificationManager?=?(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);//分組(可選)//groupId要唯一String?groupId?=?"group_001";NotificationChannelGroup?group?=?new?NotificationChannelGroup(groupId,?"廣告");//創建groupnotificationManager.createNotificationChannelGroup(group);//channelId要唯一String?channelId?=?"channel_001";NotificationChannel?adChannel?=?new?NotificationChannel(channelId,"推廣信息",?NotificationManager.IMPORTANCE_DEFAULT);//補充channel的含義(可選)adChannel.setDescription("推廣信息");//將渠道添加進組(先創建組才能添加)adChannel.setGroup(groupId);//創建channelnotificationManager.createNotificationChannel(adChannel);//創建通知時,標記你的渠道idNotification?notification?=?new?Notification.Builder(MainActivity.this,?channelId).setSmallIcon(R.mipmap.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(),?R.mipmap.ic_launcher)).setContentTitle("一條新通知").setContentText("這是一條測試消息").setAutoCancel(true).build();notificationManager.notify(1,?notification);} }?
效果如下:?
?
華為手機當只有一個渠道時,不會顯示,會當做默認通知處理,除非一個以上。
?
注意:當Channel已經存在時,后面的createNotificationChannel方法僅能更新其name/description,以及對importance進行降級,其余配置均無法更新。所以如果有必要的修改只能創建新的渠道,刪除舊渠道。
?
刪除渠道代碼如下:
?
private?void?deleteNotificationChannel(String?channelId){if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.O)?{NotificationManager?mNotificationManager?=?(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);mNotificationManager.deleteNotificationChannel(channelId);}}?
?
3懸浮窗適配
?
使用?SYSTEM_ALERT_WINDOW?權限的應用無法再使用以下窗口類型來在其他應用和系統窗口上方顯示提醒窗口:
?
-
TYPE_PHONE
-
TYPE_PRIORITY_PHONE
-
TYPE_SYSTEM_ALERT
-
TYPE_SYSTEM_OVERLAY
-
TYPE_SYSTEM_ERROR
?
相反,應用必須使用名為?TYPE_APPLICATION_OVERLAY?的新窗口類型。
也就是說需要在之前的基礎上判斷一下:
?
if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.O)?{mWindowParams.type?=?WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY }else?{mWindowParams.type?=?WindowManager.LayoutParams.TYPE_SYSTEM_ALERT }?
當然記得需要有權限
?
<uses-permission?android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission?android:name="android.permission.SYSTEM_OVERLAY_WINDOW"?/>?
再進行判斷.
?
4安裝APK
?
Android 8.0去除了“允許未知來源”選項,所以如果我們的App有安裝App的功能(檢查更新之類的),那么會無法正常安裝。
?
首先在AndroidManifest文件中添加安裝未知來源應用的權限:
?
<uses-permission?android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>?
這樣系統會自動詢問用戶完成授權。當然你也可以先使用?canRequestPackageInstalls()查詢是否有此權限,如果沒有的話使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES這個action將用戶引導至安裝未知應用權限界面去授權。
?
private?static?final?int?REQUEST_CODE_UNKNOWN_APP?=?100;private?void?installAPK(){if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.O)?{boolean?hasInstallPermission?=?getPackageManager().canRequestPackageInstalls();if?(hasInstallPermission)?{//安裝應用}?else?{//跳轉至“安裝未知應用”權限界面,引導用戶開啟權限Uri?selfPackageUri?=?Uri.parse("package:"?+?this.getPackageName());Intent?intent?=?new?Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,?selfPackageUri);startActivityForResult(intent,?REQUEST_CODE_UNKNOWN_APP);}}else?{//安裝應用}}//接收“安裝未知應用”權限的開啟結果 @Override protected?void?onActivityResult(int?requestCode,?int?resultCode,?Intent?data)?{super.onActivityResult(requestCode,?resultCode,?data);if?(requestCode?==?REQUEST_CODE_UNKNOWN_APP)?{installAPK();} }?
對于權限組、懸浮窗還有安裝未知來源應用的權限適配,我們也可以使用AndPermission。這樣更加便捷。
https://github.com/yanzhenjie/AndPermission
?
5集合的處理
?
現在,AbstractCollection.removeAll(null)?和?AbstractCollection.retainAll(null)始終引發?NullPointerException;之前,當集合為空時不會引發?NullPointerException。所以我們需要做判空處理。
?
6后臺執行限制
?
https://developer.android.google.cn/about/versions/oreo/background
?
應用在兩個方面受到限制:
?
后臺服務限制:處于空閑狀態時,應用可以使用的后臺服務存在限制。 這些限制不適用于前臺服務,因為前臺服務更容易引起用戶注意。
?
廣播限制:除了有限的例外情況,應用無法使用清單注冊隱式廣播。 它們仍然可以在運行時注冊這些廣播,并且可以使用清單注冊專門針對它們的顯式廣播。
?
在大多數情況下,應用都可以使用?JobScheduler?克服這些限制。 這種方式讓應用安排為在未活躍運行時執行工作,不過仍能夠使系統可以在不影響用戶體驗的情況下安排這些作業。
?
關于的用法可以參考官方例子:android-JobScheduler
https://github.com/googlesamples/android-JobScheduler
?
當然還有后臺位置的限制需要去注意。
https://developer.android.google.cn/about/versions/oreo/background-location-limits
?
7圖標適配
郭神的博客:https://mp.weixin.qq.com/s/WxgHJ1stBjokPi6lTUd1Mg
?
8安卓6.0-9.0的適配
https://mp.weixin.qq.com/s/K9eIN0veW96sjXoczHms5w
安卓11的文件部分適配
https://mp.weixin.qq.com/s/bEHTMAn9LB8SAUyf8WyF6A
安卓11完整適配
https://mp.weixin.qq.com/s/vwbnZPAFKg1rMYUkHxpirQ
參考
?
MIUI 10 通知類別 / Channel 適配
https://dev.mi.com/console/doc/detail?pId=1303
Create and Manage Notification Channels
https://developer.android.google.cn/training/notify-user/channels
Presentation of Notifications
https://source.android.google.cn/compatibility/8.0/android-8.0-cdd#3_8_user_interface_compatibility
Android 實現應用更新適配 Android O
https://blog.csdn.net/mq2856992713/article/details/79688587
?
原文鏈接:https://mp.weixin.qq.com/s/MhWurQy9oOf9OuDsdBLU-w
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Android8.0适配方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android7.0适配方案
- 下一篇: 图解八大排序算法