Flutter中如何阻止或检测带音频的屏幕录制?
解决Flutter应用屏幕录制时音频被捕获的问题
针对你遇到的flutter_windowmanager仅能阻止屏幕内容但无法拦截音频录制的问题,需要针对Android和iOS分别通过原生层API实现检测与拦截,以下是具体方案:
Android 端实现
1. 检测屏幕录制状态并处理音频
Android 10(API 29)及以上可通过AudioManager监听音频捕获状态,结合MethodChannel实现Flutter与原生的通信,在录屏触发时暂停/恢复应用音频:
原生代码(Kotlin)
class MainActivity : FlutterActivity() { private val CHANNEL = "com.app.screen_capture/audio" private var isScreenRecording = false override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) // 注册MethodChannel处理Flutter调用 MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "isScreenRecording" -> result.success(isScreenRecording) else -> result.notImplemented() } } // 监听音频捕获状态,判断是否在录屏 val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager audioManager.registerAudioPlaybackCallback(object : AudioManager.AudioPlaybackCallback() { override fun onPlaybackConfigChanged(configs: MutableList<AudioPlaybackConfiguration>) { super.onPlaybackConfigChanged(configs) isScreenRecording = configs.any { it.clientType == AudioPlaybackConfiguration.CLIENT_TYPE_REMOTE_SUBMIX } // 通知Flutter端录屏状态变化 MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) .invokeMethod("onScreenRecordingChanged", isScreenRecording) } }, Handler(Looper.getMainLooper())) } }
Flutter 端代码
import 'package:flutter/services.dart'; class ScreenAudioGuard { static const MethodChannel _channel = MethodChannel('com.app.screen_capture/audio'); static bool _isRecording = false; static Future<bool> get isScreenRecording async { final bool result = await _channel.invokeMethod('isScreenRecording'); return result; } static void init() { _channel.setMethodCallHandler((call) async { if (call.method == 'onScreenRecordingChanged') { _isRecording = call.arguments as bool; // 录屏状态变化时处理音频 if (_isRecording) { // 暂停应用内所有音频播放 // 例如调用音频播放器的pause()方法 } else { // 恢复音频播放 } } }); } }
2. 强制音频不被捕获
可在原生层设置音频属性,让音频仅输出到扬声器且禁止被录制:
val audioAttributes = AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED) .build() val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager audioManager.setAudioAttributes(audioAttributes)
iOS 端实现
iOS 系统提供UIScreen.capturedDidChangeNotification通知监听录屏状态,同样通过MethodChannel实现跨端通信:
原生代码(Swift)
import UIKit import Flutter class MainViewController: FlutterViewController { private let CHANNEL = "com.app.screen_capture/audio" private var isScreenRecording = false override func viewDidLoad() { super.viewDidLoad() let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: flutterEngine!.binaryMessenger) channel.setMethodCallHandler { [weak self] call, result in guard let self = self else { return } switch call.method { case "isScreenRecording": result.success(self.isScreenRecording) default: result.notImplemented() } } // 监听屏幕录制状态变化 NotificationCenter.default.addObserver( self, selector: #selector(screenCaptureChanged), name: UIScreen.capturedDidChangeNotification, object: nil ) } @objc private func screenCaptureChanged() { isScreenRecording = UIScreen.main.isCaptured let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: flutterEngine!.binaryMessenger) channel.invokeMethod("onScreenRecordingChanged", arguments: isScreenRecording) } }
Flutter 端代码
复用Android端的ScreenAudioGuard类即可,通过监听回调处理音频暂停/恢复逻辑。
替代方案
如果无需保留应用音频,可在检测到录屏时直接静音应用音频输出,避免被录屏捕获。
内容的提问来源于stack exchange,提问作者Imarana
相关产品推荐
相关产品推荐

