Android 去除“Viewing full screen”彈窗

原文鏈接:https://blog.csdn.net/u011386173/article/details/84568092

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/u011386173/article/details/84568092
這篇文章可結合Android9.0 完全隱藏導航欄、狀態欄

Android應用設置沉浸式全屏時,一般會使用到如下的Flag:

View.SYSTEM_UI_FLAG_IMMERSIVE或View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY以及View.SYSTEM_UI_FLAG_HIDE_NAVIGATION。

使用了以上的Flag組合後呢,系統會彈窗提示用戶當前是全屏顯示,彈框如下:

大標題是Viewing full screen,小字部分是Swipe down from the top to exit full screen.”的提示,即從上往下滑動可退出全屏。

這個提示是友好的,但是大多數情況下,這個提示框可能因爲擋住了要顯示的內容而不滿足全屏要求。那麼如何去除“Viewing full screen”彈窗呢?要去除這個彈框,就先要從這個彈框出現的位置開始分析。

在/framework/base/servics/core/java/com/server/policy/ImmersiveModeConfirmation.java中有如下函數:

1、首先看看這個isImmersiveMode參數,系統是如何判斷當前是否爲沉浸式的呢?
【/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java】的函數updateSystemBarsLw:

vis就是來判斷顯示界面設置給systemUiVisibility 的flag的。看看isImmersiveMode:

也就是如果systemUiVisibility設置了SYSTEM_UI_FLAG_HIDE_NAVIGATION + SYSTEM_UI_FLAG_IMMERSIVE、SYSTEM_UI_FLAG_IMMERSIVE_STICKY中的一個或兩個,且存在NavigationBar,那麼就是沉浸式模式。

2、再看一下mHandler中是如何處理H.SHOW消息的


再看看handleShow函數:

噹噹噹,這個時候那個彈窗就顯示出來了。

解決方案
既然我們要解決彈窗顯示的問題,那麼根據以上顯示彈窗的分析,方案就來了。

①mHandler中接收到消息後不做show confirmation的操作;

②彈窗顯示後就調用其隱藏的操作;

③不發送顯示彈框的消息SHOW到mHandler中。

接下來分析一下這三種方案:

①mHandler中接收到消息後不做show confirmation的操作
因爲這個文件是framework層的,所以就是要修改系統源碼。而且一旦接收到消息後不做show confirmation的操作,那麼系統中的所有應用沉浸式全屏的時候都不會彈出提示框,而非當前的沉浸式全屏引用。這樣的需求一般不是我們所需要的,不過當然也是一種方案,這種方案對於看不到系統源碼的開發者來說並不友好。修改方案如下:

②彈窗顯示後就調用其隱藏的操作
其實從剛剛的源碼分析可以看到,因此彈框,也就是handleHide裏做的事。而這個handleHide被執行到,就需要給mHandler發送HIDE消息。But, 發送HIDE消息的就兩處:

第一處:這個要屏幕沉浸式顯示的模式變更後纔會執行(即退出沉浸式模式)。

第二處:很明顯,這是和VR相關的,我們一般用不到。

那麼,我們可以試試不通過發送消息,而是直接執行handleHide裏的操作呀!!!

好的,這個函數是私有的。如果APP想調用,可以通過反射。=-=,這個類好像是不對外的吧,反正反射也沒有啥用。。。親測沒成功。。。。

③不發送顯示彈框的消息SHOW到mHandler中
終極方法終於來了!!!

在ImmersiveModeConfirmation.java文件中,有且僅有一處發送了SHOW消息:

沒錯!!就是這個函數。那麼爲了不發送SHOW消息,所以就要if條件不滿足。

通過分析,這個navBarEmpty條件最容易被APP修改,我們只要讓這個值爲true就好了。

那麼來看看這個參數navBarEmpty的由來:

【/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java】

函數updateSystemBarsLw:

來看看isNavBarEmpty是個什麼鬼:

沒錯,這要這個isNavBarEmpty返回true,就不會show 彈出了。

從這個函數可以看到,只要在應用界面顯示的systemUiVisibility參數中加上這三個FLAG那麼這個函數就會返回true。從而那個Viewing Full Screen的彈窗也不會出現了(親測有用)。

修改如下:

WindowManager.LayoutParams lp = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
lp.systemUiVisibility = View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_BACK | View.STATUS_BAR_DISABLE_RECENT |
              View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |View.SYSTEM_UI_FLAG_FULLSCREEN |
              View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
               View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
這種方法,並不是對所有應用起作用。而僅僅是對自己的沉浸式全屏應用其作用,當應用退出時,這個彈窗還是對其他應用有效的。o(* ̄︶ ̄*)o
————————————————
版權聲明:本文爲CSDN博主「明朗晨光」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u011386173/article/details/84568092

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章