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上面針對國內市場懸浮窗需求特別修改了懸浮窗的設計。
懸浮窗在國內的市場環境下有幾個問題:
- 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了。
更多文章和互動請關注微信公眾號:anzhuozhimei
推薦閱讀: