首页 > 其他分享 >Android 11 关于按键拦截/按键事件处理分享

Android 11 关于按键拦截/按键事件处理分享

时间:2024-08-02 17:39:40浏览次数:10  
标签:11 事件处理 KeyEvent int text add 按键 new event

系统在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java处理按键事件,不管是物理按键还是
SystemUI的nav_bar上的虚拟按键(使用了KeyEvent类中的,比如:KeyEvent.KEYCODE_VOLUME_UP).

主要注意的有两个函数:
interceptKeyBeforeDispatching 分发之前拦截事件

interceptKeyBeforeQueueing 加入队列之前拦截事件

长按物理音量上键弹出重启Dialog,去除Dialog界面部分选项

    @Override
    public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
            int policyFlags) {
        final boolean keyguardOn = keyguardOn();
        final int keyCode = event.getKeyCode();
        final int repeatCount = event.getRepeatCount();
        final int metaState = event.getMetaState();
        final int flags = event.getFlags();
        final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
        final boolean canceled = event.isCanceled();
        final int displayId = event.getDisplayId();

        if (true) {
            Log.d("tag", "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
                    + repeatCount + " keyguardOn=" + keyguardOn + " canceled=" + canceled);
        }

        //add text
        Log.d("tag", "policyFlags:" + policyFlags);//长按和短按会产生不同的policyFlags
        //短按流程 按下 down=true repeatCount=0 2次  抬起 down=false repeatCount=0
        //长按流程 按下 down=true repeatCount++ 不断自增  抬起 down=false repeatCount=0
        if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {//1107296256  long  //1644167168 short
            if (policyFlags == 1107296256 || policyFlags == 1644167168) {
                if (repeatCount == 20) {
                    mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
                    mHandler.sendEmptyMessageDelayed(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS, 2000 * 1);
                }
                return -1;
            }
        }
        //add text

        //infrare simulate mouse
        boolean isBox = "box".equals(SystemProperties.get("ro.target.product"));
        if(isBox){
        ...
    }

//
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
->
powerLongPress();                          
||
showGlobalActions();

frameworks/base/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
//dialog所有菜单选项
    <string-array translatable="false" name="config_globalActionsList">
        <item>emergency</item>
        <item>lockdown</item>
        <item>power</item>
        <item>restart</item>
        <item>logout</item>
        <item>screenshot</item>
        <item>bugreport</item>
    </string-array>


    @VisibleForTesting
    protected void createActionItems() {
        // Simple toggle style if there's no vibrator, otherwise use a tri-state
        if (!mHasVibrator) {
            mSilentModeAction = new SilentModeToggleAction();
        } else {
            mSilentModeAction = new SilentModeTriStateAction(mAudioManager, mHandler);
        }
        mAirplaneModeOn = new AirplaneModeAction();
        onAirplaneModeChanged();

        mItems.clear();
        mOverflowItems.clear();
        mPowerItems.clear();
        String[] defaultActions = {"restart"};//getDefaultActions();//add text

        ShutDownAction shutdownAction = new ShutDownAction();
        RestartAction restartAction = new RestartAction();
        ArraySet<String> addedKeys = new ArraySet<String>();
        List<Action> tempActions = new ArrayList<>();
        CurrentUserProvider currentUser = new CurrentUserProvider();

        //add text
        // make sure emergency affordance action is first, if needed
        /*if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
            addIfShouldShowAction(tempActions, new EmergencyAffordanceAction());
            addedKeys.add(GLOBAL_ACTION_KEY_EMERGENCY);
        }*/
        //add text

        for (int i = 0; i < defaultActions.length; i++) {
            String actionKey = defaultActions[i];
            if (addedKeys.contains(actionKey)) {
                // If we already have added this, don't add it again.
                continue;
            }
    ...
}
    
    //点击dialog外,让它消失
    protected static ActionsDialog mDialog;//add static 
    
    private void initializeLayout() {
            setContentView(com.android.systemui.R.layout.global_actions_grid_v2);
            fixNavBarClipping();
            mControlsView = findViewById(com.android.systemui.R.id.global_actions_controls);
            mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view);
            mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
                @Override
                public boolean dispatchPopulateAccessibilityEvent(
                        View host, AccessibilityEvent event) {
                    // Populate the title here, just as Activity does
                    event.getText().add(mContext.getString(R.string.global_actions));
                    return true;
                }
            });
            //add text
            ViewGroup black_view = findViewById(com.android.systemui.R.id.global_actions_grid_root);
            black_view.setClickable(true);
            black_view.setOnClickListener(v -> {
                if (mDialog != null) mDialog.dismiss();
                //dismissDialog();
            });
            //add text
            mGlobalActionsLayout.setRotationListener(this::onRotate);
            mGlobalActionsLayout.setAdapter(mAdapter);



//衍生案例1: 长按电源键直接关机不弹出dialog
    void showGlobalActionsInternal() {
        //add text
        /*if (mGlobalActions == null) {
            mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
        }
        final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
        mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
        // since it took two seconds of long press to bring this up,
        // poke the wake lock so they have some time to see the dialog.
        mPowerManager.userActivity(SystemClock.uptimeMillis(), false);*/
        
        mPowerManager.shutdown(false,null,false);//add text
        //add text
    }
//也可以修改属性实现
./frameworks/base/core/res/res/values/config.xml
    <!-- Control the behavior when the user long presses the power button.
            0 - Nothing
            1 - Global actions menu - 长按电源按钮将显示一个包含各种全局操作选项的菜单
            2 - Power off (with confirmation) 长按电源按钮将触发设备的关机动作,弹出需要用户确认的dialog
            3 - Power off (without confirmation) 长按电源按钮将触发设备的关机动作,不需要用户确认
            4 - Go to voice assist 长按电源按钮将启动语音助手
            5 - Go to assistant (Settings.Secure.ASSISTANT) 长按电源按钮将启动设备的默认助手应用程序
    -->
    <integer name="config_longPressOnPowerBehavior">1</integer>    
   
//衍生案例2: 长按power键按住三秒即可自动关机
    <integer name="config_longPressOnPowerBehavior">3</integer>   //先去掉dialog 
    
    @Override
    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
            ...
            case KeyEvent.KEYCODE_POWER: {
                //add text 长按3s关机,达不到3s取消
                if (down) {
                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageDelayed(msg,3000);
                } else {
                        mHandler.removeMessages(MSG_POWER_LONG_PRESS);
                }
                //add text
                break;
            }
            
            //注释掉原来的逻辑
            /*case KeyEvent.KEYCODE_POWER: {
                EventLogTags.writeInterceptPower(
                        KeyEvent.actionToString(event.getAction()),
                        mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
                // Any activity on the power button stops the accessibility shortcut
                cancelPendingAccessibilityShortcutAction();
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false; // wake-up will be handled separately
                if (down) {
                    interceptPowerKeyDown(event, interactive);
                } else {
                    interceptPowerKeyUp(event, interactive, canceled);
                }
                break;
            }*/
}

Adroid11.0长按power键关机流程分析
Android 设备按键处理

一些按键模拟案例

    @Override
    public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
            int policyFlags) {
            ...
           } else if (keyCode == KeyEvent.KEYCODE_MENU) {
            // Hijack modified menu keys for debugging features
            final int chordBug = KeyEvent.META_SHIFT_ON;

            //add text 模拟长按
            if (event.getAction() == KeyEvent.ACTION_UP && (event.getEventTime() - event.getDownTime() > 800)) {
                Log.d(TAG,"this is a KEYCODE_MENU's long press");
                //to do
                return -1;
            }
            //add text

            ...
            
    }

标签:11,事件处理,KeyEvent,int,text,add,按键,new,event
From: https://www.cnblogs.com/kato-T/p/18339253

相关文章

  • Win11不在C盘安装WSL2(Linux环境),安装Nvidia驱动和默认使用Win11的网络代理服务
    众所周知,WSL2为Windows用户提供了一个强大、高效且灵活的Linux环境,特别适合开发者使用。它结合了Windows和Linux的优点,为用户提供了更加全面和高效的工作环境。但缺点也很明显,那就是默认安装在本来空间就不富裕的C盘。本次我们在非C盘的盘符快速安装基于wsl2的linux开......
  • 表面贴装型晶体振荡器(汽车电子用)DSO221SX/DSO211SX:汽车电子系统的精准时间之源
    在现代汽车电子领域,精确的时间同步和稳定的频率控制是确保各种系统高效、可靠运行的关键。表面贴装型晶体振荡器DSO221SX/DSO211SX凭借其卓越的性能和出色的特性,成为了汽车电子系统中不可或缺的重要组成部分。一、汽车电子中晶体振荡器的重要性随着汽车技术的不断发展,汽......
  • 吴恩达深度学习deeplearning.ai学习笔记(一)3.9 3.10 3.11
    3.9神经网络的梯度下降法对于单隐层神经网络而言,主要参数就是,并且输入特征的维度可以记为,第一层有个隐藏单元,第二层有个输出单元,目前仅仅见过只有一个输出单元的情况;的维度是,的维度是,的维度是,的维度是,成本函数为:训练神经网络时,随机初始化参数很重要,而不是全令其为0;每个梯......
  • 51单片机之LED篇(二)独立按键
    一、独立按键的介绍1.1独立按键的基本原理相当于一种电子开关,按下时开关接通,松开时开关断开。开关功能:独立按键内部通常包含一个有弹性的金属片,当按键被按下时,金属片与触点接触,电路连通;当按键松开时,金属片恢复原状,电路断开。电平变化:在51单片机系统中,独立按键通常一端接......
  • Oracle归档日志异常增长问题的排查过程 转载 : https://blog.csdn.net/3moods/article
    Oracle归档日志是Oracle数据库的重要功能,用于将数据库的重做日志文件(RedoLog)保存到归档日志文件(ArchiveLog)中。归档日志的作用是提供数据库的备份和恢复功能,以及支持数据库的持续性和数据完整性。当数据库处于归档模式时,数据库引擎会将已经写满的重做日志文件保存到归档日志文件......
  • 实在RPA助力中国烟草11省40余家企业,实现多业务流程自动化
    近年来,为深入贯彻行业数字化转型战略部署和发展新质生产力体制机制,诸多省市烟草公司及中烟公司大力推进烟草行业数字化转型,然而烟草行业在数字化转型过程中始终存在一个核心痛点,即数据整合的复杂性、系统间的兼容性问题,以及伴随的调用数据、处理数据的安全性问题。这就要求烟......
  • windows无法连接到打印机0x0000011b原因分析及完美解决方法
         日常办公和生活中,打印机是不可或缺的重要设备。然而,在添加打印机过程中,经常会遇各种问题。然后我们在添加打印机遇到最多的多种错误:windows无法连接到打印机0x0000011b。0x0000011b有更新补丁导致的、有访问共享打印机服务异常、有访问共享打印机驱动异常等问题导......
  • FPGA知识基础之--500ms计数器,边沿检测,按键消抖
    目录前言一、边沿检测1.1使用背景1.2方法:打拍法1.2.1背景1.2.2原理1.2.3上升沿二、计数器2.1原理2.2RTL代码三、按键消抖前言一、边沿检测1.1使用背景在我们设计电路时,经常会遇到需要继续检测上升沿和下降沿的电路,因此需要对边沿继续检测1.2方法:打......
  • Android 11.0 Launcher修改density禁止布局改变功能实现
    1.前言在11.0的系统rom定制化开发中,在关于Launcher3的定制化功能中,在有些功能需要要求改变系统原有的density屏幕密度,这样就会造成Launcher3的布局变化,所以就不符合要求,接下来就来看下如何禁止改变density造成Launcher3布局功能改变的实现2.Launcher修改density禁止布局改......
  • PCIe学习笔记(11)
    TPH规则•TPH指定了两种格式。所有提供TPH的请求都必须使用Baseline(基线)TPH格式。带有可选TPHTLP前缀的格式扩展了TPH字段,为SteetingTag(转向标签,ST)字段提供了额外的位,此时,TLPheaderByte0-3如下图。•可选的TPHTLPPrefix用于扩展TPH字段。◦TPHTLP前缀的存在是......