1. 程式人生 > >Android無許可權彈懸浮窗適配8.0

Android無許可權彈懸浮窗適配8.0

背景

  相信大家在開發的過程中肯定會遇到建立懸浮框需要許可權的問題,如果不申請許可權會出現以下錯誤:

 token null is not valid; is your activity running?

  或者類似的錯誤,這類的文章在百度上面經常可以檢視到,但是基本上都是停留在Android6.0以下的,文章比較老舊。隨著6.0之後的巨大變化,主要是搞版本之後Google開啟了嚴苛模式,使使用者的隱私更加的難獲取,對某些敏感手機資訊,我們不僅需要在AndroidMainfest.xml配置檔案中申請許可權,還要在程式碼中進行動態許可權的申請,我們今天討論的懸浮框許可權就是其實的一個,今天我分享的這篇文章最高適配到最新的Android8.0,測試的手機包含了國內外的各大廠商的大部分主流手機。Demo最低適配到api 10,最高適配api27。

思路

  我們都清楚Android碎片的化的嚴重,但其實也有個大致版本的分割線,為了迎合此文,我們大致把手機大致分為3個區間,其實19,22,16的版本都具有很明顯的變換。

  • api<19 ,android 4.4以前的
  • api>22,api<26, Android4.4與8.0之間的
  • api>=26 最新版本的Android手機

功能

1.喚醒一個懸浮框
2.點選底部虛擬按鈕,懸浮框消失不見。
3.監聽懸浮框的按鈕

技術實現

前提:

  1. 儘量不在配置檔案中申請許可權。
  2. 儘量不在當前APP申請動態許可權。
  3. 如果繞不過去前兩者,則引導使用者開啟許可權。

核心程式碼:

  其中最關鍵的是圈中程式碼,對type進行的適配。有興趣的可以下載Demo在研究研究,該篇文章以研究為主。
這裡寫圖片描述

測試機型

廠商 型號 Android版本號 系統 配置靜態許可權 動態懸浮框開關 targetSdkVersion 互動成功
SAMSUNG 三星Nexus 4.3(18) 4.3 Y
SAMSUNG 三星Note3 5.0(21) 5.0 Y
SAMSUNG 三星 G9300 7.0(24) 7.0 Y
MIUI 小米4 6.0.1(23) MIUI 8.5 Y
MIUI 小米3 4.4.4(19) MIUI 9.2 Y
MIUI 小米 note 7.0(24) MIUI 8.7 Y
MIUI 小米 6 7.1.1(25) MIUI 9.2 Y
魅族 MEIZU MX5 5.0.0(21) Flyme 6.2 Y
HTC HTC A9W 7.0(24) 7.0 Y
Google Nexus 5 5.1.1(22) 5.1.1 22 Y
華為 Nexus 6P 8.0.0(26) 8.0.0 Y
Google Pixel XL 8.0.0(26) 8.0.0 <=22 3秒之後消失
Google Pixel XL 8.0.0(26) 8.0.0 api>22 Y
努比亞 Nubia 4.0 5.1.1(22) nubia v4.0 Y
華為 華為 P9 7.0.0 7.0.0(25) api>22 Y
華為 華為 Nova 2s 8.0.0(26) EMUI 8.0 <=22 3秒之後消失
華為 華為 Nova 2s 8.0.0(26) EMUI 8.0 api>22 Y
聯想 Lenovo K920 4.4.2(19) 4.4.2 Y
OPPO colorOs v1.2.0 4.3(19) 4.3 Y
OPPO OPPO R11 7.1(25) 7.1 Y
vivo vivo Y55A 6.0.1(23) 6.0.1 Y
vivo vivo X9 7.1.1(23) 7.1.1 Y

靜態許可權申請:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

結論:

API Level 廠商 targetSdkVersion 靜態許可權 動態許可權 WindowManager
api<19(4.3) All - 需要 - TYPE_PHONE
19<=api<26 All(小米,vivo除外) - 不需要 不需要 TYPE_TOAST
小米 - 需要 需要 TYPE_PHONE
vivo - 不需要 需要 TYPE_PHONE
api>=26(8.0) All version>=23 需要 需要 TYPE_APPLICATION_OVERLAY
api>=26(8.0) All version<23 不需要 不需要 TYPE_TOAST

注:
* 優先使用WindowManager.LayoutParams.TYPE_TOAST,但4.4版本之前無法接收事件也即無法互動, 7.1 版本後源app失去焦點時有個定時器自動隱藏掉這個 Toast Window

  • 適配api>=26的,且 targeSdkVersion>=23 不僅需要靜態配置,還需要動態配置懸浮框許可權, type=WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY。如果不在清單中申請靜態配置,無法開啟動態啟動的懸浮框許可權; targeSdkVersion<23,如果依據不增加任何許可權,懸浮框出現3秒之後自動消失,type=WindowManager.LayoutParams.TYPE_TOAST這個不一定,少部分機型是不會消失的,比如華為代工的nexus 6p
  • MIUI V5的以上的手機根據版本號與機型進行調整。少數是不需要配置許可權的,但是一定需要動態開啟懸浮框許可權,建議都進行靜態配置,並且呼叫配置懸浮框許可權。
  • 如果打開了靜態控制權限,19<=api<26 的情況下,則動態申請一定要開啟,type=WindowManager.LayoutParams.TYPE_PHONE
  • vivo手機需要動態開啟懸浮框許可權。

答疑:
1.為什麼4.4之下使用 TYPE_TOAST沒有效果,而大於等於4.4就有效果了?
    低版本中使用這個引數只能夠進行展示效果,不能被點選,而高版本中在這個引數上面加了一段邏輯,沒錯。。。就可以點選了,可以獲取焦點的邏輯,系統已經幫我們做了。因為系統幫我們加了兩個設定:
2.為什麼在8.0上面會有個3秒自動消失的結果?
    因為Google預留這個WindowManager.LayoutParams.TYPE_TOAST本質不是給開發者用的,而是給手機廠商用的,結果沒想到國內懸浮框的需求量巨大,想到了這麼一個後門來繞過敏感許可權的申請,所以在7.1之後就慢慢的廢除了,在7.1版本增加了定時消失的功能,並且該定時沒公開。
這裡寫圖片描述
3.為什麼小米和vivo都需要動態配置開啟懸浮框許可權?
    沒有為什麼,大廠就是會玩,自己強行加上了這個功能。MIUI 5之前是可以無許可權開啟的,高版本後就不行了,但有個別型號是可以不需要開通許可權的,比如小米4W;vivo就更奇葩了,無論有沒有增加許可權,但是一定要手動開啟懸浮框的許可權 。
4.為什麼使用type=WindowManager.LayoutParams.TYPE_PHONE需要在配置檔案中增加許可權?
    這個不一定,除了vivo這個奇葩定製除外,絕大部分都要遵循這個規則。
這裡寫圖片描述

最後

根據版本迭代趨勢,我還是建議大家遵循Google大法的開發規則,老老實實的申請許可權。(部分圖片來源於網路)
Demo地址是:https://github.com/LiuLei0571/FloatDemo.git,麻煩各位看官給個小星星==