Android 13 定制开发:实现 Power 键仅关闭背光且支持触摸唤醒
2025-11-09 / 龙之叶   

背景与需求

在 Android 13 的定制开发过程中,我们遇到了一个特殊需求:硬件层面要求按下 Power 键时,系统不应执行标准的关屏操作(即不断开 mini 信号),而仅关闭屏幕背光。此外,当用户触摸屏幕时,需要能够唤醒屏幕并点亮背光。

实现步骤

1. 修改 Power 键短按策略

首先,我们需要修改系统对 Power 键短按的默认行为。在 Android 系统中,这一行为由 frameworks\base\core\res\res\values\config.xml 文件中的 config_shortPressOnPowerBehavior 参数控制。

修改前

1
2
3
4
5
6
7
8
9
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
1 - Go to sleep (doze)
2 - Really go to sleep (don't doze)
3 - Really go to sleep and go home (don't doze)
4 - Go to home
5 - Dismiss IME if shown. Otherwise go to home
-->
<integer name="config_shortPressOnPowerBehavior">1</integer>

修改后:

1
<integer name="config_shortPressOnPowerBehavior">0</integer>

通过将 config_shortPressOnPowerBehavior 的值设置为 0,我们禁用了 Power 键的默认关屏行为。

2. 自定义 Power 键事件处理

接下来,我们需要在 frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java 文件中自定义 Power 键的事件处理逻辑。

2.1 新增背光与 MIPI 信号控制方法

首先,我们新增了 switchBacklight()brightScreen() 方法来控制屏幕背光和 MIPI 信号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
private static final String backlightGpio = "/sys/class/backlight/backlight/bl_power"; // PWM反向,0=亮屏,1=黑屏
private static final String mipiSignalGpio = "/sys/class/gpio/gpio114/value"; // MIPI信号,1=亮,0=灭

private static void switchBacklight() {
int currentBacklight = readGpio(backlightGpio);
if (currentBacklight == 0) { // 当前是亮屏,改为黑屏
writeGpio(backlightGpio, "1");
writeGpio(mipiSignalGpio, "0");
} else {
writeGpio(mipiSignalGpio, "1");
writeGpio(backlightGpio, "0");
}
}

private static void brightScreen() {
int currentBacklight = readGpio(backlightGpio);
if (currentBacklight != 0) {
writeGpio(mipiSignalGpio, "1");
writeGpio(backlightGpio, "0");
}
}

private static boolean writeGpio(String filePath, String value){
File file = new File(filePath);
if(!file.exists()){
return false;
}

OutputStreamWriter ops = null;
try {
ops = new OutputStreamWriter(new FileOutputStream(file));
ops.write(value);
ops.flush();
return true;
} catch (Exception e) {
Log.e("GPIO", "write fail", e);
} finally {
if(ops != null){
try {
ops.close();
} catch (IOException e) {
}
}
}
return false;
}


private static int readGpio(String filePath){
File file = new File(filePath);
if(!file.exists()){
return -1;
}

BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = br.readLine();
if(line != null){
return Integer.parseInt(line);
}
} catch (Exception e) {
Log.e("GPIO", "reader fail", e);
} finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
}
}
}
return -1;
}

2.2 修改 Power 键事件处理逻辑

powerPress() 方法中,我们根据 mShortPressOnPowerBehavior 的值来决定如何处理 Power 键的短按事件。
由于我们已经将 config_shortPressOnPowerBehavior 设置为 0,因此这里会调用我们新增的 switchBacklight() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void powerPress(long eventTime, int count, boolean beganFromNonInteractive) {
// 原有代码省略...

if (count == 1 && interactive && !beganFromNonInteractive) {
if (mSideFpsEventHandler.onSinglePressDetected(eventTime)) {
Slog.i(TAG, "Suppressing power key because the user is interacting with the " + "fingerprint sensor");
return;
}
switch (mShortPressOnPowerBehavior) {
case SHORT_PRESS_POWER_NOTHING:
switchBacklight(); // 调用新增的背光控制方法
break;
// 其他 case 省略...
}
}

// 原有代码省略...
}

3. 实现触摸唤醒功能

为了实现触摸唤醒功能,我们需要在 PhoneWindowManager 类中注册一个全局的触摸事件监听器。

3.1 新增触摸事件监听器

1
2
3
4
5
6
7
8
private WindowManagerPolicy.PointerEventListener mPointerEventListener = new WindowManagerPolicy.PointerEventListener() {
@Override
public void onPointerEvent(MotionEvent motionEvent) {
if (motionEvent.() == MotionEvent.ACTION_DOWN) {
brightScreen(); // 触摸时点亮屏幕
}
}
};

3.2 注册触摸事件监听器

PhoneWindowManagerinit() 方法中,我们注册了上述的触摸事件监听器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void init(Context context, IWindowManager windowManager, WindowManagerFuncs windowManagerFuncs) {
mContext = context;
mWindowManager = windowManager;
mWindowManagerFuncs = windowManagerFuncs;

// 注册触摸事件监听器
mWindowManagerFuncs.registerPointerEventListener(mPointerEventListener, DEFAULT_DISPLAY);

mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
// 原有代码省略...
}

总结

通过上述步骤,我们成功实现了 Android 13 下的 Power 键仅关闭背光且支持触摸唤醒的功能。具体来说,我们修改了 Power 键的短按策略,自定义了 Power 键的事件处理逻辑,并新增了背光与 MIPI 信号的控制方法。同时,我们还通过注册全局触摸事件监听器实现了触摸唤醒功能。这一解决方案满足了硬件层面的特殊需求,提升了用户体验。

本文链接:
http://longzhiye.top/2025/11/09/2025-11-09/