Android P 攔截虛擬按鍵事件
最近有一個奇怪的需求,當儲存空間不足時,需要一個提醒框.此提醒框出現時只能點選提供的button才能跳轉到釋放檔案空間的地方.觸發其他地方要求無響應(包括虛擬按鍵). 此做法有兩種,一種是使用懸浮框. 一種是對話方塊.不管是那種做法,都需要遮蔽虛擬按鍵的響應. 一.尋找解決方案. (1)使用SDK自帶工具hierarchyviewer 檢視虛擬按鍵的佈局,發現Back/Home/Recents 三個按鈕都使用KeyButtonView. 並檢視到對應的view id ,分別是R.id.back/R.id.home/R.id.recent_apps. (2)根據(1)所帶的線索,在全域性程式碼中搜索發現是對應的程式碼在SystemUI中. 二.分析程式碼邏輯. 虛擬按鍵主要事件是點選,長按,以及觸控. 對應的程式碼 SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { ... prepareNavigationBarView();//初始化預先設定 ... } private void prepareNavigationBarView() { ... // recents新增事件 ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton(); recentsButton.setOnClickListener(this::onRecentsClick); recentsButton.setOnTouchListener(this::onRecentsTouch); recentsButton.setLongClickable(true); recentsButton.setOnLongClickListener(this::onLongPressBackRecents); // back新增事件 ButtonDispatcher backButton = mNavigationBarView.getBackButton(); backButton.setLongClickable(true); // home新增事件 ButtonDispatcher homeButton = mNavigationBarView.getHomeButton(); homeButton.setOnTouchListener(this::onHomeTouch); homeButton.setOnLongClickListener(this::onHomeLongClick); // accessibility新增事件 ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton(); accessibilityButton.setOnClickListener(this::onAccessibilityClick); accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick); updateAccessibilityServicesState(mAccessibilityManager); ButtonDispatcher rotateSuggestionButton = mNavigationBarView.getRotateSuggestionButton(); rotateSuggestionButton.setOnClickListener(this::onRotateSuggestionClick); rotateSuggestionButton.setOnHoverListener(this::onRotateSuggestionHover); updateScreenPinningGestures(); } 程式碼中已經顯示了對應事件,我們做一些巨集開關進行攔截和放過就可以. 三. 修改了NavigationBarFragment.java事件處理,但是,發現home鍵位和back鍵,還不能捕捉. 檢視原始碼,發現KeyButtonView.java重寫了onTouchEvent方法,自身對touch事件進行了攔截. 在KeyButtonView.java中onTouchEvent方法進行巨集變數進行攔截,測試OK. 四.總結: 攔截虛擬按鍵事件只要在KeyButtonView.java和NavigationBarFragment.java中攔截對應的方法即可.