網(wǎng)站首頁 編程語言 正文
需求
設(shè)備有一個按鍵,我們定義為了 KEYCODE_DPAD_CENTER(23),長按 5s,實現(xiàn)系統(tǒng)自動重啟。
原理
在 Framework 層,查找長按電源鍵關(guān)機相關(guān)邏輯,可以看到按鍵經(jīng)過一堆處理之后會來到 (/frameworks/base/services/core/java/com/android/server/policy/)PhoneWindowManager.java 定義的 interceptKeyBeforeQueueing函數(shù)中,這里還需注意另一個函數(shù)為 interceptKeyBeforeDispatching,注意區(qū)別。在按鍵按下時延時5s發(fā)送特定消息,在收到消息時實現(xiàn)功能,在按鍵抬起時撤銷延時發(fā)送的消息。下面直接說具體做法。
添加消息邏輯
首先定義一個屬于自己的消息,可以看到,在 PhoneWindowManager.java 第820行附近,定義了一堆 private static final int MSG_XXXX = XX;
,我們需要在最后這里添加一個自己的 private static final int MSG_MY_REBOOT = 999;
定義為999是為了避免與現(xiàn)有值重復(fù)。 接下來,在 handleMessage
方法中,添加該消息的處理:
private class PolicyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_ENABLE_POINTER_LOCATION: enablePointerLocation(); break; // Add start case MSG_MY_REBOOT: mWindowManagerFuncs.reboot(false); break; // Add end ... // 省略若干行 } } }
這里直接調(diào)用了 mWindowManagerFuncs
的 reboot
方法,傳 false
進去,表現(xiàn)為不彈窗直接進入重啟過程,顯示“系統(tǒng)重啟中”頁面。傳 true
進去,則彈窗提示將要關(guān)機,點是關(guān)機重啟、點否取消。
添加按鍵處理
首先定義兩個函數(shù),分別進行 KeyDown 和 KeyUp 時的處理。這兩個函數(shù)要寫在 PhoneWindowManager 類中,注意不要寫進了它的內(nèi)部類里面,其實源碼中包含很多類似的 interceptXxxKeyDown
方法,寫到與他們并列的位置即可。
// ..... // Add start private void interceptCenterKeyDown() { Message msg = mHandler.obtainMessage(MSG_MY_REBOOT); msg.setAsynchronous(true); mHandler.sendMessageDelay(msg, 5000); // 5000ms = 5seconds } private void interceptCenterKeyUp() { mHandler.removeMessages(MSG_MY_REBOOT); } // Add end private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { // 省略若干行
調(diào)用按鍵處理
最后,在 interceptKeyBeforeQueueing
中添加對按鍵的攔截及處理調(diào)用
@Override public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { if (!mSystemBooted) { // If we have not yet booted, don't let key events do anything return 0; } final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; // 省略若干行 switch (keyCode) { case KeyEvent.KEYCODE_BACK: { if (down) { interceptBackKeyDown(); } else { boolean handled = interceptBackKeyUp(event); // Don't pass back press to app if we've already handled it via long press if (handled) { result &= ~ACTION_PASS_TO_USER; } } break; } // Add start case KeyEvent.KEYCODE_DPAD_CENTER: { if (down) { interceptCenterKeyDown(); } else { interceptCenterKeyUp(); } break; } // Add end case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: // 省略若干行 } }
這里,因為在一般情況下,我們需要把這個按鍵消息發(fā)送給應(yīng)用層,因此這里我們不進行 result &= ~ACTION_PASS_TO_USER
的操作。
這樣,整個長按重啟功能就實現(xiàn)了。
原文鏈接:https://juejin.cn/post/7135094307689594910
相關(guān)推薦
- 2022-07-09 二分查找實現(xiàn)及優(yōu)化思考
- 2022-08-02 Android開發(fā)自定義雙向SeekBar拖動條控件_Android
- 2022-04-03 Rust?連接?SQLite?數(shù)據(jù)庫的過程解析_相關(guān)技巧
- 2023-03-05 useCallback和useMemo的正確用法詳解_React
- 2022-07-24 python單向循環(huán)鏈表實例詳解_python
- 2023-03-28 Python?獲取當(dāng)前路徑3種方法_python
- 2022-08-28 flask?route對協(xié)議作用及設(shè)計思路_python
- 2022-04-29 Go語言中的通道channel詳情_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支