模拟Power长按事件实现应用调用


需求场景

应用层模拟实现 物理Power按键长按功能。用户关机、重启界面功能就不需要再长按物理按键了

需求的目的:

  • 物理按键长按到弹框的逻辑源码流程梳理:因为弹框是在SystemUI
    里面的一个弹框,按键反馈是在Framework里面的。外部调用是在其它app或者也在Framework里面的。如何模调用或者间接调用SystemUI里面的成功提醒弹框。
  • 举了一个例子,物理按键流程和SystemUI调用,整体梳理起来。

参考资料

个人以前写得总结,可参考,就是让两个东西融合进来,进一步整理。
KeyCode及KeyCode分发机制
MTK Android12 关机界面全屏展示
其它参考资料:
Android U Input 系统:单按键手势功能
RK3568 Android12 长按power键功能设置
Android11 关机界面修改-Android关机界面

源码分析

按键长按流程

关注PhoneWindowManager.java 长按相关的常量

 // must match: config_LongPressOnPowerBehavior in config.xml
    // The config value can be overridden using Settings.Global.POWER_BUTTON_LONG_PRESS
    static final int LONG_PRESS_POWER_NOTHING = 0;
    static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
    static final int LONG_PRESS_POWER_SHUT_OFF = 2;
    static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
    static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
    static final int LONG_PRESS_POWER_ASSISTANT = 5; // Settings.Secure.ASSISTANT

    // must match: config_veryLongPresOnPowerBehavior in config.xml
    // The config value can be overridden using Settings.Global.POWER_BUTTON_VERY_LONG_PRESS
    static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
    static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;

查看配置

frameworks/base/core/res/res/values/config.xml

在线源码查看config.xml

  <!-- Control the behavior when the user long presses the power button.
            0 - Nothing
            1 - Global actions menu
            2 - Power off (with confirmation)
            3 - Power off (without confirmation)
            4 - Go to voice assist
            5 - Go to assistant (Settings.Secure.ASSISTANT)
    -->
    <integer name="config_longPressOnPowerBehavior">5</integer>	
	
	

举例,不同的默认显示不同的效果,下面实际配置后的显示如下。
比如1 和 2 的配置,分别显示如下:
参考
在这里插入图片描述
在这里插入图片描述
所以, 在实际项目中的配置根据项目需要进行配置,这里我们项目配置的是1

加载长按配置

  mLongPressOnPowerBehavior = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_longPressOnPowerBehavior);

获取当前长按配置:

private int getResolvedLongPressOnPowerBehavior() {
   
        if (FactoryTest.isLongPressOnPowerOffEnabled()) {
   
            return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
        }

        // If the config indicates the assistant behavior but the device isn't yet provisioned, show
        // global actions instead.
        if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_ASSISTANT && !isDeviceProvisioned()) {
   
            return LONG_PRESS_POWER_GLOBAL_ACTIONS;
        }

        // If long press to launch assistant is disabled in settings, do nothing.
        if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_GO_TO_VOICE_ASSIST
                && !isLongPressToAssistantEnabled(mContext)) {
   
            return LONG_PRESS_POWER_NOTHING;
        }

        return mLongPressOnPowerBehavior;
    }

是否有长按配置:

 private boolean hasLongPressOnPowerBehavior() {
   
        return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING;
    }
	

SingleKeyGestureDetector 手势按键

SingleKeyGestureDetector 在线源码
手势按键,就说这个Power按键的功能逻辑判断都是在这里封装的。短按/长按/双击/多次单击的 逻辑判断。

长按回调

回归到PhoneWindowManager 类的中回调Power长按事件

@Override
        void onLongPress(long eventTime) {
   
            if (mSingleKeyGestureDetector.beganFromNonInteractive()
                    && !mSupportLongPressPowerWhenNonInteractive) {
   
                Slog.v(TAG, "Not support long press power when device is not interactive.");
                return;
            }

            powerLongPress(eventTime);  //最终指向:powerLongPress
        }
		

一个内部类实现:

 /**
     * Rule for single power key gesture.
     */
    private final class PowerKeyRule extends SingleKeyGestureDetector.SingleKeyRule {
   
        PowerKeyRule() {
   
            super(KEYCODE_POWER);
        }

        @Override
        boolean supportLongPress() {
   
            return hasLongPressOnPowerBehavior();
        }

        @Override
        boolean supportVeryLongPress() {
   
            return hasVeryLongPressOnPowerBehavior();
        }


        @Override
        int getMaxMultiPressCount() {
   
            return getMaxMultiPressPowerCount();
        }

        @Override
        void onPress(long downTime, int displayId) {
   
            if (mShouldEarlyShortPressOnPower) {
   
                return;
            }
            powerPress(downTime, 1 /*count*/, displayId);
        }

        @Override
        long getLongPressTimeoutMs() {
   
            if (getResolvedLongPressOnPowerBehavior() == LONG_PRESS_POWER_ASSISTANT) {
   
                return mLongPressOnPowerAssistantTimeoutMs;
            } else {
   
                return super.getLongPressTimeoutMs();
            }
        }

        @Override
        void onLongPress(long eventTime) {
   
            if (mSingleKeyGestureDetector.beganFromNonInteractive()
                    && !mSupportLongPressPowerWhenNonInteractive) {
   
                Slog.v(TA
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值