如何在Flutter桌面应用中禁止截图与屏幕录制?
Flutter桌面应用禁止截图与屏幕录制实现方案
Flutter本身没有跨平台API直接实现禁止截图/录屏的功能,需要结合各桌面平台的原生API,通过MethodChannel与Flutter端通信完成。以下分平台给出具体实现步骤:
一、Flutter端基础配置
先创建MethodChannel,用于调用原生平台的禁止截图方法:
import 'package:flutter/services.dart'; class ScreenProtection { static const MethodChannel _channel = MethodChannel('screen_protection'); // 启用屏幕保护(禁止截图/录屏) static Future<void> enableProtection() async { try { await _channel.invokeMethod('enableProtection'); } on PlatformException catch (e) { print('启用保护失败: ${e.message}'); } } // 关闭屏幕保护 static Future<void> disableProtection() async { try { await _channel.invokeMethod('disableProtection'); } on PlatformException catch (e) { print('关闭保护失败: ${e.message}'); } } }
在需要启用保护的页面,直接调用ScreenProtection.enableProtection()即可。
二、各平台原生实现
1. macOS平台
macOS可通过设置窗口的sharingType为NSWindowSharingNone,阻止系统和第三方工具捕获窗口内容:
- 打开
macos/Runner/AppDelegate.swift - 注册MethodChannel实现动态控制:
import Cocoa import FlutterMacOS @NSApplicationMain class AppDelegate: FlutterAppDelegate { override func applicationDidFinishLaunching(_ aNotification: Notification) { super.applicationDidFinishLaunching(aNotification) guard let controller = window?.contentViewController as? FlutterViewController else { return } let channel = FlutterMethodChannel(name: "screen_protection", binaryMessenger: controller.engine.binaryMessenger) channel.setMethodCallHandler { [weak self] call, result in guard let window = self?.window else { result(FlutterError(code: "NO_WINDOW", message: "无法获取窗口", details: nil)) return } switch call.method { case "enableProtection": window.sharingType = .none result(nil) case "disableProtection": window.sharingType = .default result(nil) default: result(FlutterMethodNotImplemented) } } } }
2. Windows平台
Windows使用Win32 API的SetWindowDisplayAffinity函数,设置窗口显示亲和力为WDA_MONITOR,阻止截图和录屏:
- 打开
windows/runner/flutter_window.cpp - 在窗口初始化后注册MethodChannel:
#include <windows.h> #include "flutter_window.h" #include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow() {} FlutterWindow::~FlutterWindow() {} bool FlutterWindow::OnCreate() { if (!Win32Window::OnCreate()) { return false; } RECT frame = GetClientArea(); flutter_controller_ = std::make_unique<FlutterEngine>( L"flutter_window", flutter::DartProject::GetDefaultForCurrentDirectory()); flutter_controller_->engine()->SetNextFrameCallback([&]() { this->Show(); }); flutter_controller_->InitializeSize(frame.right - frame.left, frame.bottom - frame.top); RegisterPlugins(flutter_controller_->engine()); HWND hwnd = GetHandle(); // 注册MethodChannel用于动态控制 auto channel = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>( flutter_controller_->engine()->messenger(), "screen_protection", &flutter::StandardMethodCodec::GetInstance()); channel->SetMethodCallHandler( [hwnd](const flutter::MethodCall<flutter::EncodableValue>& call, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { if (call.method_name() == "enableProtection") { BOOL success = SetWindowDisplayAffinity(hwnd, WDA_MONITOR); success ? result->Success() : result->Error("SET_FAILED", "设置窗口保护失败"); } else if (call.method_name() == "disableProtection") { BOOL success = SetWindowDisplayAffinity(hwnd, WDA_NONE); success ? result->Success() : result->Error("SET_FAILED", "取消窗口保护失败"); } else { result->NotImplemented(); } }); return true; }
注意:SetWindowDisplayAffinity需要Windows 10 1607及以上版本支持。
3. Linux平台
Linux桌面环境(GNOME、KDE等)没有统一的禁止截图/录屏API,实现兼容性较差:
可尝试通过GTK设置窗口私有属性,阻止部分系统级截图工具:
- 打开
linux/runner/main.cc - 在窗口初始化时添加属性设置:
#include <gtk/gtk.h> #include "flutter/generated_plugin_registrant.h" int main(int argc, char** argv) { gtk_init(&argc, &argv); GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); // 设置窗口私有属性尝试阻止截图 g_object_set(G_OBJECT(window), "gtk-extended-window-private", TRUE, NULL); GtkWidget* flutter_view = flutter_view_new(gtk_window_get_display(GTK_WINDOW(window))); gtk_container_add(GTK_CONTAINER(window), flutter_view); flutter::FlutterEngine engine; engine.Initialize(); RegisterPlugins(&engine); gtk_widget_show_all(window); gtk_main(); return 0; }
说明:该方案仅对部分系统工具生效,无法覆盖所有第三方截图软件。
三、局限性说明
- 以上方案仅能阻止软件层面的截图/录屏,无法对抗硬件级别的捕获设备(如外接摄像头拍摄屏幕)。
- 部分第三方工具可能绕过系统限制,无法完全杜绝截图行为。
内容的提问来源于stack exchange,提问作者Adnan
相关产品推荐
相关产品推荐

