冻结屏幕很多第一次听到以为是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表示拦截此事件 不再往下传递。
@Override
public 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 {
@Override
public 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} */
@Override
public 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 {
@Override
public 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"