Sometimes for security purpose we don’t want user to take screenshot and share further.
Disabling screenshot also disable screen recoding of that app. You might have noticed this feature in OTT media service i.e Netflix, Amazon Prime, Disney plus and many more.
OTT use this feature so that protected content can only seen by their subscribed customer and it restrict us from screen recoding and re-distributing.
Get Started
Flutter ask us to select a programming language from available two options
OS | Native Language 1 | Native Language 2 |
---|---|---|
iOS | Objective C | Swift |
Android | Java | Kotlin |
We mostly prefer Swift for iOS and Kotlin for android. These two respective company also recommend the same. If you see the default option the it comes with the same.
There is two ways to achieve this
- Natively: By touching the native code and touching native programming code.
- Non Natively: By not touching the native and using plugin.
Using plugin you can only do for android and for ios you need to go natively.
Using Plugin
Flutter Windows Manage
This is going to be easy and if you only targeting the android device then this is possibly best solution.
import 'package:flutter/material.dart';
import 'package:flutter_windowmanager/flutter_windowmanager.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isSecureScreen = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Screenshot Secure Demo'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
_isScreenShotAllowed
? 'Secure Mode'
: 'Non Secure Mode'
),
RaisedButton(
onPressed: _toggleScreenShot,
child: const Text('Toggle Secure Mode'),
),
],
),
),
);
}
Future<void> _toggleScreenShot() async {
if (_isSecureScreen == true) {
await FlutterWindowManager
.addFlags(FlutterWindowManager.FLAG_SECURE);
} else {
await FlutterWindowManager
.clearFlags(FlutterWindowManager.FLAG_SECURE);
}
setState(() {
_isSecureScreen = !_isSecureScreen;
});
}
}
I personally prefer the native way and because native code is of one line only. By using native code, I become free from one plugin.
Natively in Android
Let’s open the MainActivity.kt
file and have a look at the file. Probably that might looks something similar to this one.
This file might look little different in your case because flutter recently removed some of the boilerplate code.
Case 1 [Newer Project]
Now flutter provides this boilerplate code in MainActivity.kt
file looks like this.
package com.example.demo_app;
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
Case 2 [Older Project]
In past, flutter used to provide this code in MainActivity.kt
file.
package com.example.demo_app;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
For Case 1 Person
As you have seen above that recent MainActivity.ky
file, flutter has removed some code if you compare from previous. It means we need to include that code by yourself.
Add the missing code by seeing the case 2 code and then all of us will have the code.
For Case 2 Person
There is only one line of code which can do this but in order to add that line we need to add three different imports.
Solution
Let’s add some code and restrict the user from taking screenshot and screen recording.
package com.example.demo_app;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
// Added these three import lines
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.os.Bundle;
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
// Added this line
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
}
There are various flag and each flag has different capabilities.
iOS
I don’t know exactly how to disable screenshot and screen recording in iOS.
I have some knowledge which is not very much helpful but can be used for securing. You can disable screenshot while App switcher(while switching from one app to other app). I learnt this from Internet and tested it on emulator.
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;
}
// </Add>
}
As I don’t have iPhone or iPad, so if somehow make something then it will be difficult for me to test. So, I didn’t look on the internet because before telling to the world about something I need to test it and be sure it’s correct.
Conclusion
Stopping user from taking screenshot or screen recoding is impossible but at some extend we can make it difficult for most of the normal users.
Although it does not guarantee 100% that user will not share but at some extend we make it secure.