基于Flutter的iOS/Android应用录屏阻止方案及iOS11回调利用问询
Hey there! Let's walk through exactly how to block screen recording in your Flutter app across iOS and Android, and answer your specific question about leveraging the iOS 11+ screen recording callback.
iOS 平台:利用 iOS 11+ 录屏回调实现防护
First things first: iOS doesn’t allow apps to directly block users from screen recording due to system-level restrictions. However, we can use iOS 11+’s built-in screen capture detection tools (like the UIScreen.isCaptured property or system notifications) to detect when recording starts, then take protective actions—like showing a full-screen overlay, hiding sensitive content, or prompting the user to stop recording—to indirectly prevent unauthorized capture.
实现步骤(Flutter + 原生iOS结合)
Set up a native iOS listener for screen capture events
In your iOSAppDelegate.swiftor a dedicated handler class, listen for theUIScreenCapturedDidChangeNotificationsystem notification and send updates to Flutter via an EventChannel:import UIKit import Flutter class ScreenCaptureHandler: NSObject, FlutterStreamHandler { private var eventSink: FlutterEventSink? private var notificationObserver: NSObjectProtocol? func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { eventSink = events // Send initial capture state events(UIScreen.main.isCaptured) // Listen for state changes notificationObserver = NotificationCenter.default.addObserver( forName: UIScreen.capturedDidChangeNotification, object: nil, queue: .main ) { [weak self] _ in self?.eventSink?(UIScreen.main.isCaptured) } return nil } func onCancel(withArguments arguments: Any?) -> FlutterError? { if let observer = notificationObserver { NotificationCenter.default.removeObserver(observer) } eventSink = nil return nil } }Register the EventChannel in
AppDelegate:func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let controller = window?.rootViewController as! FlutterViewController let screenCaptureChannel = FlutterEventChannel( name: "com.yourapp/screen_capture", binaryMessenger: controller.binaryMessenger ) screenCaptureChannel.setStreamHandler(ScreenCaptureHandler()) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) }Handle capture events in Flutter
Subscribe to the event stream in your Flutter code and trigger protective actions when recording is detected:import 'package:flutter/services.dart'; class ScreenCaptureManager { static const EventChannel _eventChannel = EventChannel('com.yourapp/screen_capture'); static Stream<bool>? _screenCaptureStream; static Stream<bool> get screenCaptureStream { _screenCaptureStream ??= _eventChannel.receiveBroadcastStream().map((event) => event as bool); return _screenCaptureStream!; } } // Use in your widget @override void initState() { super.initState(); ScreenCaptureManager.screenCaptureStream.listen((isCapturing) { if (isCapturing) { // Show overlay, hide sensitive content, or show a warning setState(() => _showRecordingBlocker = true); } else { setState(() => _showRecordingBlocker = false); } }); }
Android 平台:使用 FLAG_SECURE 阻止录屏
Android allows direct blocking of screen recording/screenshots using the WindowManager.LayoutParams.FLAG_SECURE flag. You can implement this via a MethodChannel to native code or use a Flutter plugin for simplicity.
方法1:原生代码 + MethodChannel
In your Android MainActivity.kt, add methods to toggle the secure window flag:
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.yourapp/screen_secure" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "enableSecureWindow" -> { window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) result.success(true) } "disableSecureWindow" -> { window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) result.success(true) } else -> result.notImplemented() } } } }
Call these methods from Flutter:
import 'package:flutter/services.dart'; class ScreenSecureManager { static const MethodChannel _channel = MethodChannel('com.yourapp/screen_secure'); static Future<void> enableSecureWindow() async { await _channel.invokeMethod('enableSecureWindow'); } static Future<void> disableSecureWindow() async { await _channel.invokeMethod('disableSecureWindow'); } } // Enable in your widget's initState @override void initState() { super.initState(); ScreenSecureManager.enableSecureWindow(); } // Optional: Disable when widget is disposed @override void dispose() { ScreenSecureManager.disableSecureWindow(); super.dispose(); }
方法2:使用 Flutter 插件
If you want to skip writing native code, use a plugin like flutter_windowmanager to set the flag directly:
import 'package:flutter_windowmanager/flutter_windowmanager.dart'; // Enable secure window await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE); // Disable secure window await FlutterWindowManager.clearFlags(FlutterWindowManager.FLAG_SECURE);
Key Notes
- iOS: You can’t fully block recording, only detect and mitigate it—this is an intentional Apple restriction to preserve user control.
- Android:
FLAG_SECUREblocks all screen capture methods (system screenshots, third-party recorders), but test on custom ROMs as some may have compatibility quirks. - Extra Protection: Always add a secondary layer of security (like blurring sensitive content) even after implementing these measures.
内容的提问来源于stack exchange,提问作者Anthony

