如何在.NET MAUI中关闭Android屏幕且不锁定手机?
Android 实现屏幕熄灭后响应触摸并执行拍照+播放声音的方案
针对你的需求(每日运行8-12小时、屏幕非必需、点击触发拍照+发声、追求低功耗),以下是几个可行的实现方案:
方案一:通过窗口标志+唤醒锁实现(无需额外系统权限)
这是普通应用最易落地的方式,核心思路是用窗口标志强制熄灭屏幕,同时保持轻量唤醒锁监听触摸事件。
步骤1:申请必要权限
在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
步骤2:实现屏幕熄灭逻辑
在主Activity中通过WindowManager参数强制关闭屏幕:
private void turnScreenOff() { WindowManager.LayoutParams params = getWindow().getAttributes(); params.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_OFF; params.flags |= WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; getWindow().setAttributes(params); }
步骤3:监听触摸事件并触发操作
用全屏透明View覆盖屏幕,监听触摸动作:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置全屏透明 getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); getWindow().setStatusBarColor(Color.TRANSPARENT); // 绑定触摸监听 View rootView = findViewById(R.id.root_view); rootView.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { // 临时唤醒屏幕 PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "App:WakeLock" ); wakeLock.acquire(3000); // 保持唤醒3秒完成操作 // 执行拍照逻辑(替换为你的相机调用代码) takePhoto(); // 执行播放声音逻辑(替换为你的音频播放代码) playSound(); // 操作完成后再次熄灭屏幕 turnScreenOff(); wakeLock.release(); return true; } return false; }); // 启动时直接熄灭屏幕 turnScreenOff(); }
注意事项
- 必须用全屏透明View配合窗口标志,才能在屏幕熄灭时捕获触摸事件
- 拍照、音频播放逻辑要轻量化,避免长时间占用硬件资源
方案二:通过设备管理员权限实现(更稳定的系统级控制)
如果能引导用户授予设备管理员权限,可获得更稳定的屏幕控制能力,功耗表现也更好。
步骤1:注册设备管理员
创建设备管理员接收器:
public class MyDeviceAdminReceiver extends DeviceAdminReceiver { // 保持空实现即可 }
在AndroidManifest.xml中注册:
<receiver android:name=".MyDeviceAdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>
创建res/xml/device_admin.xml配置文件:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <force-lock /> </uses-policies> </device-admin>
步骤2:请求用户授权
在Activity中触发授权流程:
private void requestDeviceAdmin() { Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); ComponentName adminComponent = new ComponentName(this, MyDeviceAdminReceiver.class); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminComponent); intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "需要设备管理员权限控制屏幕熄灭"); startActivityForResult(intent, 1001); }
步骤3:控制屏幕
授权成功后,直接通过DevicePolicyManager锁定屏幕:
private void turnScreenOffWithAdmin() { DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); ComponentName adminComponent = new ComponentName(this, MyDeviceAdminReceiver.class); if (dpm.isAdminActive(adminComponent)) { dpm.lockNow(); // 直接熄灭并锁定屏幕 } } // 唤醒屏幕逻辑同方案一
注意事项
- 设备管理员权限需要用户手动授权,会增加操作成本
- 锁定屏幕后需结合KeyguardManager解锁,再用方案一的透明View监听触摸
功耗优化建议
- 唤醒锁仅在触发操作时临时持有,完成后立即释放
- 拍照、音频播放完成后及时关闭硬件资源(如相机实例、音频播放器)
- 声明前台服务(
android:foregroundServiceType="camera")保持进程存活,减少系统杀后台概率
内容的提问来源于stack exchange,提问作者Alberto Rivera
相关产品推荐
相关产品推荐

