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

希望本文對君有用!