網站首頁 編程語言 正文
Android 無障礙的全局懸浮窗可以在屏幕上添加 UI 供用戶進行快捷操作,可以展示在所有應用程序之上長期展示。另一方面,在一些自動化場景下,可以用來屏蔽用戶行為,防止用戶手動操作打斷自動化流程。
無障礙添加 UI
無障礙服務添加 UI 十分簡單,使用 LayoutInflater 在 AccessibilityService 的 onServiceConnected
添加一個 UI:
// in AccessibilityService, service 代表 AccessibilityService 的子類實例 private fun initView() { // 在屏幕頂部添加一個 View val wm = service.getSystemService(AccessibilityService.WINDOW_SERVICE) as? WindowManager val lp = WindowManager.LayoutParams().apply { type = TYPE_ACCESSIBILITY_OVERLAY // 因為此權限才能展示處理 layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES format = PixelFormat.TRANSLUCENT flags = flags or FLAG_LAYOUT_NO_LIMITS or FLAG_NOT_TOUCHABLE or // 透傳觸摸事件 FLAG_NOT_FOCUSABLE or // 透傳輸入事件 FLAG_LAYOUT_IN_SCREEN width = MATCH_PARENT height = MATCH_PARENT } // 通過 LayoutInflater 創建 View val rootView = LayoutInflater.from(service).inflate(R.layout.float_layer, null) wm?.addView(rootView, lp) }
然后在自定義的無障礙服務中去調用這個方法:
class MyAccessibilityService: AccessibilityService() { override fun onServiceConnected() { super.onServiceConnected() initView() } // ... }
需要注意的是,這里不能將 initView
添加到 onCreate
生命周期中,官方文檔也有一些放在 onCreate 中的操作,但實際上都會導致 crash 。
java.lang.RuntimeException: Unable to create service com.chunyu.accessibilitydemo.service.AccessibilityDemoService: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
無障礙服務所有的初始化工作,都要放在 onServiceConnected
中執行。這樣就可以將自定義的 UI 展示到屏幕上了。
關于無障礙服務的配置,可以參考官方 API 。
配置分析
從使用上來看,無障礙蒙層是通過 WindowManager 添加到屏幕上的。而關鍵的一些信息在 WindowManager.LayoutParams 配置的數據中。
Type
Window 有一個關鍵的屬性 type ,它被定義在 WindowManager 的內部類 LayoutParams 中,它可以控制 Window 的顯示次序。主要分為三種:
- Application Window:應用程序窗口 1-99 ,應用程序窗口一般位于最底層。
- System Window:系統窗口 2000-2999 ,系統級窗口一般位于最頂層,不會被其他的window遮住。
- Sub Window:子窗口 1000-1999,子窗口一般是顯示在應用窗口之上。
從三種窗口的值也可推斷出,type 的值越大,Window 就越靠近用戶。
在上面的使用中,我們將 type 設置為 TYPE_ACCESSIBILITY_OVERLAY
,它的值是 2032 ,是一個系統窗口,所以可以展示在應用程序之上。 TYPE_ACCESSIBILITY_OVERLAY
,是無障礙服務用來展示 UI 專用的 窗口類型 。使用它可以在所有的應用程序上展示蒙層。
Flag
flag 中包含了兩個關鍵的值 FLAG_NOT_TOUCHABLE
和 FLAG_NOT_FOCUSABLE
,和一些其他的 flag 。配置這兩個內容,蒙層將不會影響任何用戶操作。
FLAG_NOT_TOUCHABLE
:可以將 Window 設置為永不接收觸摸事件,從而能夠將觸摸事件透傳給蒙層遮蓋住的區域,不阻塞用戶操作。FLAG_NOT_FOCUSABLE
:可以將 Window 設置為永不獲取按鍵輸入焦點,用戶無法向這個 Window 發送按鍵或其他的按鈕時間,而被它覆蓋的內容可以接收并響應事件。FLAG_LAYOUT_NO_LIMITS
:允許窗口延伸到屏幕之外。FLAG_LAYOUT_IN_SCREEN
:將窗口放置在整個屏幕中,忽略來自父窗口的任何約束。
LayoutInDisplayCutoutMode
這個屬性可以用來控制 Window 在劉海屏的布局方式。
-
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
:僅當劉海屏完全包含在系統欄中時,才允許窗口擴展到劉海區域。 否則,窗口的布局使其不與劉海區域重疊。 -
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
:允許 Window 延伸到短的一側邊緣的劉海區域。 -
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
:Window 不允許延伸到劉海屏區域。 -
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
:允許 Window 延伸到所有的屏幕邊緣劉海區域。
原文鏈接:https://juejin.cn/post/7108668826727743519
相關推薦
- 2022-06-29 徹底掌握C語言strcpy函數的用法_C 語言
- 2022-09-26 使用JDBC連接數據庫執行sql語句,創建數據庫連接池
- 2022-01-16 DOM簡介及獲取元素方法屬性總結
- 2022-06-28 python神經網絡使用tensorflow實現自編碼Autoencoder_python
- 2022-07-04 如何生成對角矩陣?numpy.diag_python
- 2022-06-29 Python解決非線性規劃中經濟調度問題_python
- 2022-03-18 linux下修改文件權限chmod命令詳細解析_Linux
- 2024-07-15 Spring Boot多環境指定yml或者properties
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支