منع لقطة الشاشه على الاندرويد و ios بدون مشاكل في تطبيق flutter
منع لقطة الشاشه من العناصر الاساسيه التي تعتمد عليها التطبيقات التعليميه بشكل كبير جدا فهي تقوم بجعل المستخدم غير قادر على اخذ لقطة شاشه او حتى تسجيل فيديو للتطبيق واذا قام بذلك فسوف تظهر شاشه سوداء ولا يظهر اي شيئ وهذا لان المحتوى يكون محمي وفي هذا المقال سوف نشرح لكم كيف تقوم بمنع تسجيل الشاشه فيديو وصورة من خلال Android و ios بكل سهوله من خلال اكواد بسيطة سوف نشاركها معكم في هذه المقاله .
disable screen shot for android
اذا كنت ترغب بمنع تسجيل الشاشه لاجهزة الاندرويد فيفضل وضع الكود الداخل بداخل صفحة main وهيا الصفحه التي تبدء اثناء عمل التطبيق حتى لا يتمكن المستخدم من تسجيل الفيديو للتطبيق او حتى اخذ لقطة شاشه لتطبيقك اثناء عمله .
android.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
disableScreenShot();
runApp(const MyApp());
}
Future<void> disableScreenShot() async {
await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
}
disable screen shot for ios
والطريقه هيا ان نسال سؤال لماذا نريد منع screenshot or record مثلا لدي مقطع فيديو لا اريد المستخدم اخذ لقطة شاشه منه على سبيل المثال حسنا ما رايك ان تعرف هلل المستخدم يقوم بعمل record ولا لا بمعنى نقوم بعمل detect للريكورد وبناءا ننفذ action مثل قفل التطبيق او حتى نقله الى صفحة اخرى تخربه ان هذا غير مسموح به في التطبيق وهناك باكدج مخصصه لاجهزة ios تقوم بعمل هذا الغرض وهيا ios_insecure_screen_detector وهيا توفر function ترجع bool هل بيتم التسجيل او لا ;()await _insecureScreenDetector.isCaptured ولكن مشكلتها انها لا توفر stream او listener فسوف تضطر هنا لعمل (تعديل بسيط هنا تستطيع تكوين stream عن طريقtimer كما هو موضح واذا رايت ان while مكلفة فيمكنك تنفيذ اي فكرة اخرى تحلو لك) نقوم بعمل نحن stream والكود متوفر في الاسفل وبهذا نستطيع منع screen record في الوقت الذي نريده اما بالنسبة لسكرين شوت هنستخدم بكدج اخرى توفر function مباشرة للمنع والغاء المنع اسم البكدج : screen_protector ملوحظة استخدم الاكواد هذه في ios version الخاصه بالتطبيق وبالنسبة للاندريود استخدم flutter_windowmanager
.
ios.dart
// ************* Prevent ScreenShot ************//
// package name : screen_protector
// https://pub.dev/packages/screen_protector
await ScreenProtector.preventScreenshotOn(); // prevent screenshot on ios
await ScreenProtector.preventScreenshotOff();// allow screenshot on ios
// *************. Prevent ScreenRecord ************//
// package name : ios_insecure_screen_detector
// https://pub.dev/packages/ios_insecure_screen_detector
// create stream to listen to changes of screenCapture
Stream<bool> checkIfScreenRecording() async* {
final IosInsecureScreenDetector insecureScreenDetector =
IosInsecureScreenDetector();
await insecureScreenDetector.initialize();
while (true) {
await Future.delayed(const Duration(seconds: 5)); // to avoid memory leak
bool isCaptured = await insecureScreenDetector.isCaptured();
log("isCaptured :$isCaptured");
yield isCaptured;
}
}
// Usage
late StreamSubscription<bool> streamSubscription;
@override
void initState() {
super.initState();
// For iOS only.
if (Platform.isIOS) {
streamSubscription = checkIfScreenRecording().listen((isRecording) {
if (isRecording) {
exit(0); // exit the app or whatever action you need add here
}
});
}
}
@override
void dispose() {
// don't forget to cancel the streamSubscription
if (Platform.isIOS) {
streamSubscription.cancel();
}
super.dispose();
}
طريقة اخرى للاندرويد و ios
بالنسبة لمنصفة ios فالامر مختلف قليلا فسوف نحتاج الى كتابة كود native كما هو موضح لتنفيذ هذه العملية والكود موجود كما هو موضح بالصورة في الجزء السفلي وايضا سوف تجد الكود بالاسفل اذا كنت ترغب بنسخه وهذا الكود يمنع لقطة الشاشه لل ios بشكل قوي وبهذا يكون لديك كود مسؤول عن الاندرويد واخر لانظمة الماك يمكنك استخدام كلا الطرق في تطبيقك اذا كنت ترغب باستخراج نسخه تعمل على كلا المنصات .
no_screen
void main() async {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
if (Platform.isAndroid) {
await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
}
});
await initAppModule();
notificationInitialization();
await CacheHelper.init();
customErrorScreen();
runApp(const MyApp());
}
// ------------- for ios :- Ios / Runner / AppDelegate.
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
self.window.makeSecure()
GMSServices.provideAPIKey("YOUR-API-KEY")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
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)
}
}