1. 程式人生 > >Android P 攔截虛擬按鍵事件

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中攔截對應的方法即可.