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

Flutter升级Sound Null Safety后flutter_windowmanager失效及API废弃问题的解决方法

解决Flutter空安全升级后flutter_windowmanager插件失效的问题

我来帮你搞定这个问题!首先得说清楚根源:flutter_windowmanager这个插件已经很久没有维护了,既没有适配Flutter的空安全特性,还可能用到了已经被标记为废弃的实现方式,所以升级后就彻底罢工了。

下面给你两个靠谱的解决方案,优先推荐第二个,因为能彻底摆脱依赖不维护插件的麻烦:

方案一:替换为支持空安全的第三方插件

如果你还是想依赖插件,可以找找维护活跃的替代项,比如flutter_windowmanager_null_safe(注意确认它的最新版本是否适配你的Flutter版本),或者secure_screen这类专注于屏幕安全的插件。安装后按照插件文档调用对应的API即可,逻辑和你原来的代码差不多,只是换了个插件包。

不过这类第三方插件也有未来停止维护的风险,所以更推荐下面的方案:

方案二:自己通过MethodChannel实现屏幕安全功能

其实设置禁止截图/录屏的逻辑非常简单,我们可以直接写原生代码实现,完全不依赖第三方插件,还能完美适配空安全。

步骤1:Flutter端创建工具类

先写一个Dart类来封装原生调用:

import 'package:flutter/services.dart';

class SecureScreenManager {
  static const MethodChannel _channel = MethodChannel('secure_screen_channel');

  /// 开启屏幕安全模式(禁止截图/录屏)
  static Future<void> enableSecureMode() async {
    await _channel.invokeMethod('enableSecure');
  }

  /// 关闭屏幕安全模式
  static Future<void> disableSecureMode() async {
    await _channel.invokeMethod('disableSecure');
  }
}

步骤2:Android端实现原生逻辑

打开android/app/src/main/kotlin/[你的包名]/MainActivity.kt(如果是Java项目就打开对应的MainActivity.java),修改代码:

Kotlin版本:

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 = "secure_screen_channel"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "enableSecure" -> {
                    window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
                    result.success(null)
                }
                "disableSecure" -> {
                    window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }
    }
}

Java版本:

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 = "secure_screen_channel";

    @Override
    public void configureFlutterEngine(FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
                .setMethodCallHandler((call, result) -> {
                    switch (call.method) {
                        case "enableSecure":
                            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
                            result.success(null);
                            break;
                        case "disableSecure":
                            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
                            result.success(null);
                            break;
                        default:
                            result.notImplemented();
                    }
                });
    }
}

步骤3:iOS端实现原生逻辑

打开ios/Runner/AppDelegate.swift,修改代码:

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private let CHANNEL = "secure_screen_channel"
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        guard let controller = window?.rootViewController as? FlutterViewController else {
            return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
        let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler { [weak self] call, result in
            guard let self = self else { return }
            switch call.method {
            case "enableSecure":
                self.window?.isSecure = true
                result.success(nil)
            case "disableSecure":
                self.window?.isSecure = false
                result.success(nil)
            default:
                result.notImplemented()
            }
        }
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

步骤4:在页面中调用

现在你可以在需要限制截图的页面里,像之前一样调用方法,记得在页面销毁时关闭安全模式:

@override
void initState() {
  super.initState();
  // 开启禁止截图/录屏
  SecureScreenManager.enableSecureMode();
}

@override
void dispose() {
  // 页面销毁时关闭安全模式,避免影响其他页面
  SecureScreenManager.disableSecureMode();
  super.dispose();
}

这样实现后,不仅完美适配空安全,还能保证功能稳定,因为所有逻辑都是自己可控的,不用担心插件停止维护的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 22:02:46