我正在制作Flutter应用程序,并且需要确保用户无法捕获该应用程序的屏幕截图(任何屏幕)。有什么办法可以在Flutter中实现这一目标,还是需要为Android和IOS编写本机代码?
小智 47
仅在iOS中,只需在AppDelegate中修改即可。并且不再需要任何插件
import UIKit
import Flutter
import Firebase
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
self.window.makeSecure() //Add this line
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
//And this extension
extension UIWindow {
func makeSecure() {
let field = UITextField()
field.isSecureTextEntry = true
self.addSubview(field)
field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.layer.superlayer?.addSublayer(field.layer)
field.layer.sublayers?.first?.addSublayer(self.layer)
}
}
Run Code Online (Sandbox Code Playgroud)
Vla*_*lad 14
2023 年 7 月更新:
我注意到,苹果开始使用下面的黑客技术拒绝应用程序。所以如果你仍然想阻止截图,我认为可以使用iOS API参数isCaptured 。我还没有测试过它,但作为一个想法,您可以使用 Flutter Method Channels 来获取/设置此属性。
在iOS上,我已在扩展/sf/answers/4693842471/的帮助下禁用了截屏。请执行以下步骤:
添加属性AppDelegate:
var field = UITextField()
在didFinishLaunchingWithOptions调用下一个方法时:addSecuredView()
private func addSecuredView() {
if (!window.subviews.contains(field)) {
window.addSubview(field)
field.centerYAnchor.constraint(equalTo: window.centerYAnchor).isActive = true
field.centerXAnchor.constraint(equalTo: window.centerXAnchor).isActive = true
window.layer.superlayer?.addSublayer(field.layer)
field.layer.sublayers?.first?.addSublayer(window.layer)
}
Run Code Online (Sandbox Code Playgroud)
}
重写委托方法:
override func applicationWillResignActive(_ application: UIApplication) {
field.isSecureTextEntry = false
}
override func applicationDidBecomeActive(_ application: UIApplication) {
field.isSecureTextEntry = true
}
Run Code Online (Sandbox Code Playgroud)
现在,当您在应用程序中进行屏幕截图或录制屏幕视频时,您将看到黑色图像或视频。希望它会有所帮助,因为我花了 2 天的时间试图让它发挥作用)
满的AppDelegate:
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var field = UITextField()
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
#if !DEBUG
addSecuredView()
#endif
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func applicationWillResignActive(_ application: UIApplication) {
field.isSecureTextEntry = false
}
override func applicationDidBecomeActive(
_ application: UIApplication
) {
field.isSecureTextEntry = true
}
private func addSecuredView() {
if (!window.subviews.contains(field)) {
window.addSubview(field)
field.centerYAnchor.constraint(equalTo: window.centerYAnchor).isActive = true
field.centerXAnchor.constraint(equalTo: window.centerXAnchor).isActive = true
window.layer.superlayer?.addSublayer(field.layer)
field.layer.sublayers?.first?.addSublayer(window.layer)
}
}
}
Run Code Online (Sandbox Code Playgroud)
Pri*_*ain 13
对于安卓:
将名为flutter_windowmanager的 flutter 包添加到pubspec.yaml 中
在 Flutter 项目的 pubspec.yaml 文件中导入其最新版本并运行 pub get。然后将以下代码添加到initState()要禁用屏幕截图和屏幕录制的小部件的方法中。
Future<void> secureScreen() async {
await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
}
@override
void initState() {
secureScreen();
super.initState();
}
@override
void dispose(){
super.dispose();
await FlutterWindowManager.clearFlags(FlutterWindowManager.FLAG_SECURE);
}
Run Code Online (Sandbox Code Playgroud)
如果您想让整个应用程序屏幕截图禁用,只需在 main.dart 文件中的函数securescreen(内调用 ) 方法(上面定义) 。main()
对于 iOS:
然后运行 flutter pub get。
Future<void> secureScreen() async {
await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
}
@override
void initState() {
secureScreen();
super.initState();
}
@override
void dispose(){
super.dispose();
await FlutterWindowManager.clearFlags(FlutterWindowManager.FLAG_SECURE);
}
Run Code Online (Sandbox Code Playgroud)
///Define a streamSubscription in order to receive changes
late StreamSubscription<bool> _screenRecordsSubscription;
///Get the instance of plugin for multiple use.
FlutterPreventScreenCapture preventScreenCapture =
FlutterPreventScreenCapture();
///is Recording is set to false initially.
bool isRecording = false;
Run Code Online (Sandbox Code Playgroud)
这样您就可以收听屏幕录制状态。
如果您想检查一次屏幕录制状态:
updateRecordStatus(bool record) {
isRecording = record;
setState(() {});
}
@override
void initState() {
///Though listening to the screen record, it is recommended to check the screen record status on the first launch.
checkScreenRecord();
///Initialize screenRecordSubscription to regularly listen to the changes
_screenRecordsSubscription =
preventScreenCapture.screenRecordsIOS.listen(updateRecordStatus);
super.initState();
}
Run Code Online (Sandbox Code Playgroud)
最后一件事是不要忘记在 dispose 方法中取消订阅:
Future<void> checkScreenRecord() async {
final recordStatus = await preventScreenCapture.checkScreenRecord();
debugPrint('Is screen being recorded: $recordStatus');
isRecording = recordStatus;
setState(() {});
}
Run Code Online (Sandbox Code Playgroud)
扑
方法1:使用screen_protector这个包
方法二:
整个申请
打开AppDelegate文件并添加UITextField变量。
private var textField = UITextField()
Run Code Online (Sandbox Code Playgroud)
在文件中创建一个函数AppDelegate。
// Screenshot Prevent Functions
private func makeSecureYourScreen() {
if (!self.window.subviews.contains(textField)) {
self.window.addSubview(textField)
textField.centerYAnchor.constraint(equalTo: self.window.centerYAnchor).isActive = true
textField.centerXAnchor.constraint(equalTo: self.window.centerXAnchor).isActive = true
self.window.layer.superlayer?.addSublayer(textField.layer)
textField.layer.sublayers?.first?.addSublayer(self.window.layer)
}
}
Run Code Online (Sandbox Code Playgroud)
在函数中调用这个方法didFinishLaunchingWithOptions。
makeSecureYourScreen()
Run Code Online (Sandbox Code Playgroud)
在特定屏幕中 - 使用方法通道
打开AppDelegate文件并添加UITextField变量。
private var textField = UITextField()
Run Code Online (Sandbox Code Playgroud)
在文件中创建一个函数AppDelegate。
// Screenshot Prevent Functions
private func makeSecureYourScreen() {
if (!self.window.subviews.contains(textField)) {
self.window.addSubview(textField)
textField.centerYAnchor.constraint(equalTo: self.window.centerYAnchor).isActive = true
textField.centerXAnchor.constraint(equalTo: self.window.centerXAnchor).isActive = true
self.window.layer.superlayer?.addSublayer(textField.layer)
textField.layer.sublayers?.first?.addSublayer(self.window.layer)
}
}
Run Code Online (Sandbox Code Playgroud)
在函数中调用这个方法didFinishLaunchingWithOptions。
makeSecureYourScreen()
Run Code Online (Sandbox Code Playgroud)
另外,在函数中添加您的方法通道代码didFinishLaunchingWithOptions。
let controller : FlutterViewController = self.window?.rootViewController as! FlutterViewController
let securityChannel = FlutterMethodChannel(name: "secureScreenshotChannel", binaryMessenger: controller.binaryMessenger)
securityChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
if call.method == "secureiOS" {
self.textField.isSecureTextEntry = true
} else if call.method == "unSecureiOS" {
self.textField.isSecureTextEntry = false
}
})
Run Code Online (Sandbox Code Playgroud)
Add your code below code to your flutter files to disable the screenshot on a specific screen.
// Declare your method channel varibale here
var iosSecureScreenShotChannel = const MethodChannel('secureScreenshotChannel');
Run Code Online (Sandbox Code Playgroud)
现在添加代码以initState防止截图
@override
void initState() {
// this method to user can't take screenshots of your application
iosSecureScreenShotChannel.invokeMethod("secureiOS");
// TODO: implement initState
super.initState();
}
Run Code Online (Sandbox Code Playgroud)
添加代码以dispose允许在另一个屏幕上截图。
@override
void dispose() {
// this method to the user can take screenshots of your application
iosSecureScreenShotChannel.invokeMethod("unSecureiOS");
// TODO: implement dispose
super.dispose();
}
Run Code Online (Sandbox Code Playgroud)
您可以禁用屏幕截图和视频捕获,例如Netflix app和Disney Hotstar应用程序。
我已经在我的应用程序中尝试过了,效果很好。
import android.view.WindowManager.LayoutParams;getWindow().addFlags(LayoutParams.FLAG_SECURE);而已。;)
通过执行以下两个步骤可以非常轻松地防止屏幕截图。
我正在使用 VS 代码。
步骤 1使用路径打开文件“mainActivity.kt”android\app\src\main\kotlin\com\example\auth_email\MainActivity.kt
步骤 2添加两行
(a) import android.view.WindowManager.LayoutParams;
(b) getWindow().addFlags(LayoutParams.FLAG_SECURE); in MainActivity: FlutterActivity() section
Run Code Online (Sandbox Code Playgroud)
重新启动应用程序
对于 Flutter2 项目
方法 1:使用包flutter_windowmanager
方法二:
在 Android 中使用 kotlin
Step 1 使用路径打开文件“mainActivity.kt”
android\app\src\main\kotlin\com\example\auth_email\MainActivity.kt
步骤 2 导入库
import android.view.WindowManager.LayoutParams
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
步骤 3 在主要活动类中
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
window.addFlags(LayoutParams.FLAG_SECURE)
super.configureFlutterEngine(flutterEngine)
}
}
Run Code Online (Sandbox Code Playgroud)
在 iOS Swift 中: AppDelegate.swift 文件
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// <Add>
override func applicationWillResignActive(
_ application: UIApplication
) {
self.window.isHidden = true;
}
override func applicationDidBecomeActive(
_ application: UIApplication
) {
self.window.isHidden = false;
}
}
Run Code Online (Sandbox Code Playgroud)
对我有用的是在 MainActivity.java 文件中编写以下代码。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
Run Code Online (Sandbox Code Playgroud)
并导入这些包!
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.os.Bundle; // required for onCreate parameter
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1929 次 |
| 最近记录: |