Flutter如何实现仅指定页面在手机锁屏状态下可见
Flutter实现单页面锁屏可访问,其他页面保持锁定
针对你的需求,我们可以通过Flutter与原生平台通信的方式,动态控制页面的锁屏访问权限,无需修改Flutter单Activity架构,仅让SecondScreen在锁屏状态下可操作,其他页面保持正常锁定。
Android 端实现步骤
1. 恢复AndroidManifest默认配置
移除之前添加的全局android:showWhenLocked="true"和android:turnScreenOn="true"属性,保持MainActivity配置默认。
2. Flutter 端修改SecondScreen
通过MethodChannel与原生通信,在页面进入时开启锁屏访问权限,页面销毁时关闭:
class _SecondScreenState extends State<SecondScreen> { static const MethodChannel _lockChannel = MethodChannel('lock_screen_control'); @override void initState() { super.initState(); // 页面进入时启用锁屏访问 _enableLockScreenAccess(); } @override void dispose() { // 页面销毁时关闭锁屏访问 _disableLockScreenAccess(); super.dispose(); } Future<void> _enableLockScreenAccess() async { try { await _lockChannel.invokeMethod('enable'); } on PlatformException catch (e) { print('开启锁屏访问失败: ${e.message}'); } } Future<void> _disableLockScreenAccess() async { try { await _lockChannel.invokeMethod('disable'); } on PlatformException catch (e) { print('关闭锁屏访问失败: ${e.message}'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('SECOND SCREEN')), body: const Center( child: Text('THIS IS SECOND SCREEN THAT SHOULD BE ACCESSIBLE EVEN WHEN PHONE IS LOCKED'), ), ); } }
3. Android 原生代码实现权限控制
修改MainActivity.kt(或Java版本),实现MethodChannel的方法处理:
Kotlin版本
import android.os.Build 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 = "lock_screen_control" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "enable" -> { enableLockScreenAccess() result.success(null) } "disable" -> { disableLockScreenAccess() result.success(null) } else -> result.notImplemented() } } } private fun enableLockScreenAccess() { 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 ) } } private fun disableLockScreenAccess() { 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 ) } } }
Java版本
import android.os.Build; import android.view.WindowManager; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugin.common.MethodChannel; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "lock_screen_control"; @Override public void configureFlutterEngine(FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler((call, result) -> { switch (call.method) { case "enable": enableLockScreenAccess(); result.success(null); break; case "disable": disableLockScreenAccess(); result.success(null); break; default: result.notImplemented(); } }); } private void enableLockScreenAccess() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setShowWhenLocked(true); setTurnScreenOn(true); } else { getWindow().addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ); } } private void disableLockScreenAccess() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setShowWhenLocked(false); setTurnScreenOn(false); } else { getWindow().clearFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ); } } }
iOS 端实现步骤
1. Flutter 端代码复用
直接使用上面修改后的SecondScreen代码,无需额外改动。
2. iOS 原生代码实现权限控制
修改AppDelegate.swift,处理MethodChannel调用:
import UIKit import Flutter import UserNotifications @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { private let CHANNEL = "lock_screen_control" override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller = window?.rootViewController as! FlutterViewController let methodChannel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) methodChannel.setMethodCallHandler { [weak self] call, result in guard let self = self else { return } switch call.method { case "enable": self.enableLockScreenAccess() result.success(nil) case "disable": self.disableLockScreenAccess() result.success(nil) default: result.notImplemented() } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func enableLockScreenAccess() { // 防止屏幕自动休眠 UIApplication.shared.isIdleTimerDisabled = true // 发送静默通知唤醒锁屏状态的屏幕 let content = UNMutableNotificationContent() content.title = "" content.body = "" content.sound = .none let request = UNNotificationRequest(identifier: "wake_screen", content: content, trigger: nil) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("唤醒屏幕失败: \(error.localizedDescription)") } } } private func disableLockScreenAccess() { UIApplication.shared.isIdleTimerDisabled = false } }
关键说明
- Android端:当用户从
SecondScreen返回MyHomePage时,dispose方法会自动调用关闭权限,恢复正常锁屏状态。 - iOS端:通过
isIdleTimerDisabled保持屏幕唤醒,静默通知用于触发锁屏状态下的屏幕亮起。 - 整个方案基于Flutter单Activity架构,无需新增页面载体,仅在目标页面动态切换权限,完全符合需求。
内容的提问来源于stack exchange,提问作者Subbu
相关产品推荐
相关产品推荐

