Android 系统隐藏暗门机制实现:主屏幕点击四角启动隐藏功能

本篇文章将分享如何在 Android 主屏幕(系统桌面)中添加一种通过点击屏幕四角顺序触发的“暗门机制”,即用户按照设定的顺序点击屏幕四个角,即可打开一个隐藏的 Activity。

实现思路概览

通过系统层的 WindowManagerService 中的 DisplayContent.java 实现以下功能:

  1. 注册全局触摸监听器 PointerEventListener

  2. 定义四个角落的点击区域(矩形边界)

  3. 检测用户是否按设定的顺序点击四个角落

  4. 如果顺序正确,启动一个隐藏 Activity

该功能代码位于 framework 层

  • 文件:DisplayContent.java

  • 位置:frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

  • 监听范围:主屏幕(默认 display)

实现步骤


1,关键字段定义

private int mMyIndex; // 当前点击顺序进度
private boolean mInitMyBounds; // 是否已初始化点击区域
private static final int REGION_COUNT = 4;
private MyBounds[] myBounds = new MyBounds[REGION_COUNT]; // 四个点击区域
private int MY_BOUNDS_DELTA = 200; // 点击区域的边长(默认 200px 正方形,200px仅初始化用,后续动态修改)

private class MyBounds {
    public int xMin;
    public int xMax;
    public int yMin;
    public int yMax;
}

2,在DisplayContent.java的构造函数中注册全局监听器

DisplayContent(Display display, RootWindowContainer root,
            @NonNull DeviceStateController deviceStateController) {

......

if (isDefaultDisplay) {
    for (int i = 0; i < REGION_COUNT; i++) {
        myBounds[i] = new MyBounds();
    }
    registerPointerEventListener(mPEL); // 注册 PointerEventListener
}
}

3,区域设定以及初始化,新增两个方法

private void updateMyBounds() {
        mMyIndex = 0;
        MY_BOUNDS_DELTA = mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight ? mDisplayInfo.logicalWidth/10 : mDisplayInfo.logicalHeight/10; //区域边长
        for(int i = 0; i < 4; i++) {
            setMyBounds(i);
        }
    }


private void setMyBounds(int index) { //设置区域
        switch (index) {
            case 0:   //屏幕右下角
                myBounds[index].xMin = mDisplayInfo.logicalWidth - MY_BOUNDS_DELTA;
                myBounds[index].xMax = mDisplayInfo.logicalWidth;
                myBounds[index].yMin = mDisplayInfo.logicalHeight - MY_BOUNDS_DELTA;
                myBounds[index].yMax = mDisplayInfo.logicalHeight;
                break;
            case 1:   //屏幕左上角
                myBounds[index].xMin = 0;
                myBounds[index].xMax = MY_BOUNDS_DELTA;
                myBounds[index].yMin = 0;
                myBounds[index].yMax = MY_BOUNDS_DELTA;
                break;
            case 2:   //屏幕右上角
                myBounds[index].xMin = mDisplayInfo.logicalWidth - MY_BOUNDS_DELTA;
                myBounds[index].xMax = mDisplayInfo.logicalWidth;
                myBounds[index].yMin = 0;
                myBounds[index].yMax = MY_BOUNDS_DELTA;
                break;
            case 3:   //屏幕左下角
                myBounds[index].xMin = 0;
                myBounds[index].xMax = MY_BOUNDS_DELTA;
                myBounds[index].yMin = mDisplayInfo.logicalHeight - MY_BOUNDS_DELTA;
                myBounds[index].yMax = mDisplayInfo.logicalHeight;
                break;
            default:
                break;
        }
    }

4,实现触摸监听逻辑
 

 private PointerEventListener mPEL = new PointerEventListener() {
        @Override
        public void onPointerEvent(MotionEvent motionEvent) {
            if(!mInitMyBounds) {    //区域初始化设定
                mInitMyBounds = true;
                updateMyBounds();
            }
            switch (motionEvent.getActionMasked()) {
                case MotionEvent.ACTION_DOWN: {
                    final int x = (int) motionEvent.getX();
                    final int y = (int) motionEvent.getY();                
                    switch (mMyIndex) { //要按照设定的顺序连续点对
                        case 0:  
                        case 1:
                        case 2:                          
                            if(x > myBounds[mMyIndex].xMin && x < myBounds[mMyIndex].xMax && y > myBounds[mMyIndex].yMin && y < myBounds[mMyIndex].yMax) {
                                mMyIndex++;  //点对就加一
                            } else {
                                mMyIndex = 0; //点错后重置顺序
                            }
                            break;
                        case 3:                           
                            if(x > myBounds[mMyIndex].xMin && x < myBounds[mMyIndex].xMax && y > myBounds[mMyIndex].yMin && y < myBounds[mMyIndex].yMax) {
                              //触发暗门
                                try {
                                    Intent intent = new Intent("android.intent.action");
                                    intent.setPackage("com.******");
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    mWmService.mContext.startActivity(intent);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        default:
                            mMyIndex = 0;
                            break;
                    }
                }
            }
        }
    };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值