Android懸浮窗自己踩的2個小坑

語言: CN / TW / HK

最近在做一個全局懸浮窗的基於ChatGPT應用快Ai,需要懸浮於其他應用上面,方便從懸浮窗ChatGPT返回的內容可以拖拽到其他應用內部。自身應用透明,通過WindowManger添加懸浮窗。類似現在很多應用跳轉到其他應用,會懸浮一個小按鈕,方便用户點擊調回自身一樣。只不過快Ai窗口比較大,但不全屏。

碰到以下幾個問題:

1、懸浮窗中EditText無法獲得彈出鍵盤

主要是沒有明白下面兩個屬性的作用,在網上搜索之後直接設置了。

  • WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

設置FLAG_NOT_FOCUSABLE,懸浮窗外的點擊才有效,會把事件分發給懸浮窗底層的其他應用Activity。如果設置了FLAG_NOT_FOCUSABLE,那麼屏幕上彈窗之外的地方能夠點擊、但是彈窗上的EditText鍵盤也不會彈出來。

此時懸浮窗外的事件是不會觸發懸浮窗內ViewonToucheEvent函數,可以通過添加WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH標誌位,但無法攔截事件。

  • WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

    屏幕上彈窗之外的地方能夠點擊、彈窗上的EditText也可以輸入、鍵盤能夠彈出來。

所以根據業務需要,我只需要添加WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL標誌位即可。

2、懸浮窗無法錄音

通過Activity調起Service,然後在Service通過WindowManager進行添加懸浮窗。在進行沒有任何操作,可以正常調起科大訊飛進行錄音。

問題點一:同事為了解決我還沒來得及修復的windowManger.removeView改成exitProcess問題,強行各種修改,最終還調用了activityfinish函數,把activity幹掉。最終導致無法調起科大訊飛的語音識別。總是報錄音權限問題,找不到任何的問題點,最後代碼回退,定位到Activity被幹掉,同事也承認他的愚蠢行為。

問題點二:在進行一些操作,例如授權跳轉到設置之後,退出設置回到原先界面,調不錄音,還是權限。定位答應透明Activity的生命週期,發現onResume函數沒有被調用到,所以應用現在在後台運行。

所以就一頓頓頓搜索,官方文檔: Android 9 對後台運行的應用增加了權限限制。

image.png

解決方法:

  1. 聲明為系統應用,沒問題。但我們想做通用軟件。
  2. 增加前台服務。實測沒效果。
  3. 在2的基礎上,再添加一個屬性:android:foregroundServiceType="microphone"。完美。 <service android:name=".ui.service.AiService" android:foregroundServiceType="microphone" />

image.png

希望本文對君有用!