本篇文章将分享如何在 Android 主屏幕(系统桌面)中添加一种通过点击屏幕四角顺序触发的“暗门机制”,即用户按照设定的顺序点击屏幕四个角,即可打开一个隐藏的 Activity。
实现思路概览
通过系统层的 WindowManagerService 中的 DisplayContent.java 实现以下功能:
-
注册全局触摸监听器
PointerEventListener -
定义四个角落的点击区域(矩形边界)
-
检测用户是否按设定的顺序点击四个角落
-
如果顺序正确,启动一个隐藏 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;
}
}
}
}
};

4万+

被折叠的 条评论
为什么被折叠?



