冻结屏幕很多第一次听到以为是Android一种异常现象,实则不然,就是防止用户在做一些非法操作导致问题防止安全漏洞问题。
1、主要通过用户行为比如禁止下拉状态栏和按键以及onTouch事件拦截等,不知道请看这篇文章(Touch事件传递流程、事件分发中的onTouch 和onTouchEvent 有什么区别,又该如何使用?_事件分发中的ontouch和ontouchevent有什么区别,又该如何使用?-CSDN博客
主要修改代码
PhoneWindowManager # interceptKeyBeforeDispatching # interceptKeyBeforeQueueing # interceptMotionBeforeQueueingNonInteractive #
ViewGroup #onInterceptTouchEvent
StatusBar # onTouchEvent
PhoneStatusBarView # onTouchEvent
2308 freeze Screen system_process E set freezeScreen Status Success
2024-05-23 11:49:52.744 1331-4710 unfreeze Screen system_process E set isUnfreezeScreen Status Success=
2024-05-23 11:52:36.634 1331-2308 freeze Screen system_process E set freezeScreen Status Success
2、实现逻辑比较简单 代码如下图所示 通过系统属性persist.xxx.screen_frozen去控制
ViewGroup.java
代码路径frameworks/base/core/java/android/view/ViewGroup.java 在onInterceptTouchEvent进行拦截
public boolean onInterceptTouchEvent(MotionEvent ev) {boolean isFreezeScreen = SystemProperties.getBoolean("persist.xxx.screen_frozen", false);Log.e("ZM","onInterceptTouchEvent="+isFreezeScreen);if(isFreezeScreen == true){Log.e("ZM","onInterceptTouchEvent isFreezeScreen="+isFreezeScreen);return true;}if (ev.isFromSource(InputDevice.SOURCE_MOUSE)&& ev.getAction() == MotionEvent.ACTION_DOWN&& ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)&& isOnScrollbarThumb(ev.getX(), ev.getY())) {return true;}return false;}
3、/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
# onTouchEvent设置为true表示拦截此事件 不再往下传递。
@Overridepublic boolean onTouchEvent(MotionEvent event) {boolean isFreezeScreen = SystemProperties.getBoolean("persist.xxx.screen_frozen", false);Log.e("ZM","PhoneStatusBarView="+isFreezeScreen);if(isFreezeScreen == true){Log.e("ZM","onTouchEvent PhoneStatusBarView isFreezeScreen="+isFreezeScreen);return true;}if (mTouchEventHandler == null) {Log.w(TAG,String.format("onTouch: No touch handler provided; eating gesture at (%d,%d)",(int) event.getX(),(int) event.getY()));return true;}return mTouchEventHandler.handleTouchEvent(event);}
4、PhoneWindowManager里面拦截 按键KeyUp/KeyDown事件代码
+ // 添加一个标志来控制是否启用锁定
+ // private boolean isScreenLocked = true;
+ //zm fix
+ private static final String SYS_PROP_SCREEN_FROZEN = "persist.xxx.screen_frozen";
+
+ private boolean mScreenFrozen = false;/*** Keyguard stuff
@@ -2664,8 +2670,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {@Overridepublic long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,int policyFlags) {
+ mScreenFrozen = SystemProperties.getBoolean(SYS_PROP_SCREEN_FROZEN, false);final boolean keyguardOn = keyguardOn();final int keyCode = event.getKeyCode();
+ Log.e("ZM", "interceptKeyBeforeDispatching Block Home key2 mScreenFrozen="+mScreenFrozen);
+ if (mScreenFrozen) {
+ // 禁止所有按键输入
+ Log.e("ZM", "free Screen interceptKeyBeforeDispatching Block Home key"+event.toString());
+ if (keyCode == KeyEvent.KEYCODE_BACK ||
+ keyCode == KeyEvent.KEYCODE_APP_SWITCH || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME
+ keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_HOME) {
+ Log.e("ZM", "free Screen interceptKeyBeforeDispatching Block Home key2===="+event.toString());
+ return -1; // Prevent the key event from being dispatched
+ }
+ }final int repeatCount = event.getRepeatCount();final int metaState = event.getMetaState();final int flags = event.getFlags();
@@ -3504,6 +3522,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {/** {@inheritDoc} */@Overridepublic int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
+ mScreenFrozen = SystemProperties.getBoolean(SYS_PROP_SCREEN_FROZEN, false);
+ Log.e("ZM", "free Screen interceptKeyBeforeQueueing KeyEvent="+mScreenFrozen);
+ if (mScreenFrozen) {
+ // 禁止所有按键输入
+ int keyCode = event.getKeyCode();
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+ keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_HOME) {
+ Log.e("ZM", "free Screen interceptKeyBeforeQueueing KeyEvent="+event.toString());
+ return 0;
+ }
+ Log.e("ZM", "free Screen interceptKeyBeforeQueueing KeyEvent2="+event.toString());
+ }final int keyCode = event.getKeyCode();final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
@@ -4092,6 +4122,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {@Overridepublic int interceptMotionBeforeQueueingNonInteractive(int displayId, long whenNanos,int policyFlags) {
+ if (mScreenFrozen) {
+ //zm fix
+ Log.e("ZM","interceptMotionBeforeQueueingNonInteractive=====");
+ return 0;
+ }
5、apk调用代码也比较简单示例如下
/*** 冻结屏幕*/public void freezeScreen() {SystemProperties.set("persist.xxx.screen_frozen", "true");Log.e("freeze Screen", "set freezeScreen Status Success");}/*** 屏幕是否冻结** @return*/public boolean isFreezeScreen() {// 获取系统属性 persist.xxx.screen_frozen 的值String value = SystemProperties.get("persist.sys.screen_frozen", "false");Log.e("isFreezeScreen","value="+value);// 将属性值转换为布尔值return Boolean.parseBoolean(value);}/*** 解冻屏幕*/public void unfreezeScreen() {SystemProperties.set("persist.xxx.screen_frozen", "false");Log.e("unfreeze Screen", "set isUnfreezeScreen Status Success=");}
最后别忘记记得把屏幕保持常亮哈,转载请注明出现高通 Android 12/13冻结屏幕-CSDN博客,谢谢!
最后补充:
// 设置屏幕常亮
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
记得加系统签名哈
android:sharedUserId="android.uid.system"