Android O实现Framework层CENTER键长按功能方法
需求
设备有一个按键,我们定义为了 KEYCODE_DPAD_CENTER(23),长按 5s,实现系统自动重启。
原理
在 Framework 层,查找长按电源键关机相关逻辑,可以看到按键经过一堆处理之后会来到 (/frameworks/base/services/core/java/com/android/server/policy/)PhoneWindowManager.java 定义的 interceptKeyBeforeQueueing函数中,这里还需注意另一个函数为 interceptKeyBeforeDispatching,注意区别。在按键按下时延时5s发送特定消息,在收到消息时实现功能,在按键抬起时撤销延时发送的消息。下面直接说具体做法。
添加消息逻辑
首先定义一个属于自己的消息,可以看到,在 PhoneWindowManager.java 第820行附近,定义了一堆 private static final int MSG_XXXX = XX;
,我们需要在最后这里添加一个自己的 private static final int MSG_MY_REBOOT = 999;
定义为999是为了避免与现有值重复。 接下来,在 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 ... // 省略若干行 } } }
这里直接调用了 mWindowManagerFuncs
的 reboot
方法,传 false
进去,表现为不弹窗直接进入重启过程,显示“系统重启中”页面。传 true
进去,则弹窗提示将要关机,点是关机重启、点否取消。
添加按键处理
首先定义两个函数,分别进行 KeyDown 和 KeyUp 时的处理。这两个函数要写在 PhoneWindowManager 类中,注意不要写进了它的内部类里面,其实源码中包含很多类似的 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) { // 省略若干行
调用按键处理
最后,在 interceptKeyBeforeQueueing
中添加对按键的拦截及处理调用
@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: // 省略若干行 } }
这里,因为在一般情况下,我们需要把这个按键消息发送给应用层,因此这里我们不进行 result &= ~ACTION_PASS_TO_USER
的操作。
这样,整个长按重启功能就实现了。
更多关于Android CENTER键长按功能的资料请关注脚本之家其它相关文章!
相关文章
Android开发之超强图片工具类BitmapUtil完整实例
这篇文章主要介绍了Android开发之超强图片工具类BitmapUtil,结合完整实例形式分析了Android图片的常用操作技巧,包括图片的加载、转换、缩放、计算等相关操作技巧,需要的朋友可以参考下2017-11-11Android调试出现The selected device is incompatible问题解决
这篇文章主要介绍了Android调试出现The selected device is incompatible问题解决的相关资料,需要的朋友可以参考下2017-01-01Android ListView里控件添加监听方法的实例详解
这篇文章主要介绍了Android ListView里控件添加监听方法的实例详解的相关资料,这里提供实例帮助大家学习理解这部分内容,需要的朋友可以参考下2017-08-08Android TabHost选项卡标签图标始终不出现的解决方法
这篇文章主要介绍了Android TabHost选项卡标签图标始终不出现的解决方法,涉及Android界面布局相关属性与状态设置操作技巧,需要的朋友可以参考下2019-03-03Android使用ViewPager实现类似laucher左右拖动效果
这篇文章主要为大家详细介绍了Android使用ViewPager实现类似laucher左右拖动效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2018-05-05
最新评论