You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter多页面应用如何实现指定页面锁屏时可唤起?

实现Flutter指定页面锁屏唤起,其余页面受锁屏保护的方案

要实现仅特定页面可在锁屏状态下唤起,其余页面保持锁屏保护,不能全局配置showWhenLocked和turnScreenOn,需要通过动态权限控制+原生MethodChannel调用来实现,以下是具体步骤:

Android原生端配置与代码实现

  1. 添加必要权限到AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Android 10及以上无需`DISABLE_KEYGUARD`权限,系统API已做兼容 -->
  1. 在MainActivity中实现MethodChannel通信,处理锁屏显示逻辑
import android.app.KeyguardManager
import android.content.Context
import android.os.Build
import android.os.PowerManager
import android.view.WindowManager
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example/lock_screen"
    private lateinit var powerManager: PowerManager
    private lateinit var wakeLock: PowerManager.WakeLock
    private lateinit var keyguardManager: KeyguardManager

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "showWhenLocked" -> {
                    // 适配Android版本,开启锁屏显示与屏幕唤醒
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
                        setShowWhenLocked(true)
                        setTurnScreenOn(true)
                    } else {
                        window.addFlags(
                            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                            or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                        )
                    }
                    
                    // 解锁锁屏(Android 10+使用官方推荐API)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        keyguardManager.requestDismissKeyguard(this, null)
                    } else {
                        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
                    }
                    
                    // 保持屏幕唤醒,设置10分钟超时可按需调整
                    wakeLock = powerManager.newWakeLock(
                        PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, 
                        "MyApp::WakeLockTag"
                    )
                    wakeLock.acquire(10*60*1000L)
                    result.success(true)
                }
                "hideWhenLocked" -> {
                    // 恢复默认锁屏保护
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
                        setShowWhenLocked(false)
                        setTurnScreenOn(false)
                    } else {
                        window.clearFlags(
                            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                            or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                            or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        )
                    }
                    
                    // 释放唤醒锁,避免电量消耗
                    if (::wakeLock.isInitialized && wakeLock.isHeld) {
                        wakeLock.release()
                    }
                    result.success(true)
                }
                else -> result.notImplemented()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 页面销毁时确保释放唤醒锁
        if (::wakeLock.isInitialized && wakeLock.isHeld) {
            wakeLock.release()
        }
    }
}

Flutter端代码实现

  1. 创建MethodChannel工具类,封装原生调用
import 'package:flutter/services.dart';

class LockScreenManager {
  static const MethodChannel _channel = MethodChannel('com.example/lock_screen');

  static Future<bool> enableLockScreenDisplay() async {
    try {
      return await _channel.invokeMethod('showWhenLocked');
    } on PlatformException catch (_) {
      return false;
    }
  }

  static Future<bool> disableLockScreenDisplay() async {
    try {
      return await _channel.invokeMethod('hideWhenLocked');
    } on PlatformException catch (_) {
      return false;
    }
  }
}
  1. 在目标页面的生命周期中调用权限控制方法
class TargetLockPage extends StatefulWidget {
  const TargetLockPage({super.key});

  @override
  State<TargetLockPage> createState() => _TargetLockPageState();
}

class _TargetLockPageState extends State<TargetLockPage> {
  @override
  void initState() {
    super.initState();
    // 页面初始化时开启锁屏显示权限
    LockScreenManager.enableLockScreenDisplay();
  }

  @override
  void dispose() {
    // 页面销毁时恢复默认锁屏保护
    LockScreenManager.disableLockScreenDisplay();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('锁屏可访问页面')),
      body: const Center(
        child: Text('此页面可在锁屏状态下弹出显示'),
      ),
    );
  }
}
  1. 触发页面跳转逻辑(如收到服务器信号时)
    当收到服务器数据或触发信号时,直接导航到目标页面即可,页面初始化时会自动处理锁屏显示:
// 示例:服务器信号触发后的页面跳转
void onServerSignalReceived() {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (_) => const TargetLockPage()),
  );
}

关键注意事项

  • 版本兼容:代码已适配Android 8.0到最新版本的API差异,确保全版本可用。
  • 资源释放:必须在页面销毁时调用disableLockScreenDisplay,否则其他页面会继承锁屏显示权限,导致应用整体不受保护。
  • 唤醒锁超时:设置合理的唤醒锁超时时间,避免不必要的电量消耗。
  • 后台唤起:如果是通过后台推送触发页面跳转,需要确保后台服务能正确唤起Flutter页面(可配合WorkManager或推送服务的后台唤醒能力)。

内容的提问来源于stack exchange,提问作者Subbu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:23:17