Android 12下如何关闭电源菜单?Java安全应用开发求助
解决Android新版本关闭电源菜单的可行方案
方案1:优化AccessibilityService实现
- 确保AccessibilityService的配置文件
accessibility_service_config.xml包含系统对话框监听权限,精准锁定SystemUI相关窗口:<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews" android:canPerformGestures="true" android:packageNames="com.android.systemui"/> - 在服务逻辑中匹配电源菜单的窗口类名(不同厂商可能有差异,比如
com.android.systemui.power.PowerMenuActivity),优先用返回键动作,无效则模拟手势:@Override public void onAccessibilityEvent(AccessibilityEvent event) { if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) return; AccessibilityNodeInfo rootNode = getRootInActiveWindow(); if (rootNode == null) return; String pkgName = rootNode.getPackageName().toString(); String className = rootNode.getClassName().toString(); if ("com.android.systemui".equals(pkgName) && className.contains("PowerMenu")) { // 先尝试全局返回动作 boolean backSuccess = performGlobalAction(GLOBAL_ACTION_BACK); if (!backSuccess) { // 模拟返回键手势(坐标可根据屏幕适配调整) GestureDescription.Builder gestureBuilder = new GestureDescription.Builder(); Path path = new Path(); path.moveTo(100, getResources().getDisplayMetrics().heightPixels / 2); gestureBuilder.addStroke(new GestureDescription.StrokeDescription(path, 0, 150)); dispatchGesture(gestureBuilder.build(), null, null); } } }
方案2:借助Device Policy Manager(需设备管理员权限)
如果你的安全类应用可以获取设备管理员授权,可直接调用锁屏方法关闭电源菜单:
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminReceiver = new ComponentName(this, YourDeviceAdminReceiver.class); if (dpm.isAdminActive(adminReceiver)) { dpm.lockNow(); }
注:此方法会直接触发锁屏,适合安全场景,但需要用户手动在系统设置中授权设备管理员权限。
方案3:反射调用系统窗口服务(兼容性有限)
通过反射调用系统窗口服务的closeSystemDialogs方法,指定关闭全局动作对话框:
try { Class<?> serviceManagerCls = Class.forName("android.os.ServiceManager"); Method getServiceMethod = serviceManagerCls.getMethod("getService", String.class); IBinder windowBinder = (IBinder) getServiceMethod.invoke(null, "window"); Class<?> windowManagerStubCls = Class.forName("android.view.IWindowManager$Stub"); Method asInterfaceMethod = windowManagerStubCls.getMethod("asInterface", IBinder.class); Object windowManager = asInterfaceMethod.invoke(null, windowBinder); Method closeDialogsMethod = windowManager.getClass().getMethod("closeSystemDialogs", String.class); closeDialogsMethod.invoke(windowManager, "globalactions"); } catch (Exception e) { e.printStackTrace(); }
注:该方法依赖系统内部API,不同厂商和版本可能失效,需谨慎使用并做适配测试。
关键注意事项
- 所有方案都需要对应权限:AccessibilityService需用户在系统设置手动开启;Device Policy Manager需用户授权设备管理员。
- 不同Android版本和厂商的电源菜单实现差异大,需针对目标机型做适配验证。
内容的提问来源于stack exchange,提问作者Sandu Moise Noaptes
相关产品推荐
相关产品推荐

