Android我還可以相信你多少系列文章四之懸浮窗
懸浮窗應該算各大廠商最先開始對應用下手的地方。
懸浮窗之所以討人厭同樣是因為被濫用,就像狗皮膏藥一樣貼在螢幕的上下左右,不管切換到哪個應用始終顯示在最上層。懸浮窗的需求有點從電腦端延續的味道,以前桌面上經常跑出來個獅子,有個懸浮球,或者歌詞。但那個時候佔用桌面面積小,相比手機螢幕尺寸,現在的懸浮窗很容易覆蓋住真正內容。那Android上面懸浮窗最初設計是想解決什麼問題呢?
懸浮窗也即一個Window。Window Type有很多種,比如TYPE_PHONE,TYPE_TOAST,TYPE_SYSTEM_ALERT等,用在來電,低電量顯示,狀態列,短暫toast提醒等。Android系統給每一種Window型別定義了一個高度,依次從上往下顯示。官方文件描述是這樣的:
下面這些值是系統定義的window型別,他們不是給普通應用用的。
既然不是預定義給應用用的,為啥應用能用呢?
從原始碼來看(摘自4。4版本,6。0以後版本許可權管理更加嚴格),TYPE_TOAST的註釋表明似乎是一段未寫完的程式碼。而像TYPE_PHONE這類則是需要SYSTEM_ALERT_WINDOW許可權,在6。0之前這是非常容易獲取到的,只要在Manifest裡面申明下即可。6。0以後需要執行時動態申請這個許可權,申請方式跟普通的地理位置許可權還不太一樣,如下的方式:
if
(!
Settings
。
canDrawOverlays
(
MainActivity
。
this
))
{
Intent
intent
=
new
Intent
(
Settings
。
ACTION_MANAGE_OVERLAY_PERMISSION
,
Uri
。
parse
(
“package:”
+
getPackageName
()));
startActivityForResult
(
intent
,
10
);
}
為什麼TYPE_TOAST不需要許可權仍然不得而知。事實上從某一次跟官方的現場交流會上,官方人員也承認懸浮窗事實上也不是設計給應用用的。而且當他們驚訝的發現國內市場懸浮窗的需求如此強大之後,他們做了一件驚人的改變:就是在Android O上面針對國內市場懸浮窗需求特別修改了懸浮窗的設計。
在Android O上面特別增加了TYPE_APPLICATION_OVERLAY來滿足懸浮窗需求。需要注意的是即使你的應用TargetSdk不是等於O版本,可以繼續使用TYPE_PHONE(O版本已廢棄),但會顯示在TYPE_APPLICATION_OVERLAY下面(所以想要顯示在最上面要儘快適配O版本)。在使用TYPE_APPLICATION_OVERLAY的時候,系統還會進行提示是否允許該應用顯示懸浮窗。
懸浮窗在國內的市場環境下有幾個問題:
6。0以下即使Manifest裡面定義了,也會被廠商自己擴展出來的懸浮窗開關預設禁掉
TYPE_TOAST在MIUI等機器上面被當做等同於TYPE_PHONE需要SYSTEM_ALERT_WINDOW許可權
開發者需要做的事情:
優先使用TYPE_TOAST,但需要注意4。4版本之前無法接收事件也即無法互動以及MIUI問題。
6。0及以後使用動態許可權申請一般不會有問題,6。0之前可以根據機型動態下發許可權開啟頁面的路徑,來做到提醒使用者去開啟許可權。儘可能引導使用者,否則就等著來反饋為啥顯示不了。
留意Android O對懸浮窗做出的重大修改對自己造成的影響
TYPE_TOAST在7。1版本上面還有一些小修改,一個uid只能加一個;曾經比較流行將Toast作為一個單例,隱藏toast的時候修改view的visibility為gone來替換removeView,然後透過不斷setText和setVisibility為VISIBILE來實現Toast內容快速切換(原生Toast必須要等duration時長消失後再出現下一個)。使用這種方式在7。1版本上面會出現問題,該版本上面在應用失去焦點的時候會有個定時器自動隱藏掉這個Toast Window,setText和setVisibility無法恢復顯示這個Window了。
WindowManagerService裡面有兩處判斷焦點失去之後起定時器隱藏Toast Window。我們可以顯示removeView之後再addView來進行相容。
更多文章和互動請關注微信公眾號:anzhuozhimei
上一篇:漁灣風景名勝區
下一篇:我們真的知道如何供養佛菩薩嗎?