π΅ Secure Your Flutter App from Screenshots & Screen Recording on Android
In todayβs world, protecting sensitive data inside your mobile app is more important than ever. Whether you're displaying confidential documents, private messages, or financial information, preventing users from taking screenshots or recording the screen can be crucial.
In this tutorial, weβll show you how to implement secure screen protection in Flutter using native Android functionality with just a few lines of code.
π This guide uses Androidβs
FLAG_SECURE
API to prevent screenshots and screen recording β all integrated seamlessly into your Flutter project.
π What You'll Build
A simple Flutter app with a toggle switch that enables or disables secure screen mode at runtime.
π Features:
- π‘οΈ Prevent screenshots and screen recording on Android
- π± Toggle secure screen mode dynamically
- π Clean, reusable code using
MethodChannel
π Prerequisites
- Flutter SDK installed
- Android device/emulator (iOS doesn't support
FLAG_SECURE
) - Basic understanding of platform channels in Flutter
π§± Project Structure Overview
lib/ βββ controller/ β βββ screen_security.dart # Dart bridge for secure screen control βββ home_screen.dart # UI with toggle switch for secure mode
android/ βββ app/src/main/kotlin/com/example/secure_screen/ βββ MainActivity.kt # Native Android implementation
βοΈ Step 1: Add Native Android Code
Update your MainActivity.kt
to handle secure mode toggle using a method channel:
// android/app/src/main/kotlin/com/example/secure_screen/MainActivity.kt
package com.example.secure_screen
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 = "screen_security"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
when (call.method) {
"enableSecureMode" -> {
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
result.success(null)
}
"disableSecureMode" -> {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
result.success(null)
}
else -> result.notImplemented()
}
}
}
}
π§© Step 2: Create the Flutter Bridge Now letβs connect Flutter to the native code.
// lib/controller/screen_security.dart
import 'package:flutter/services.dart';
class ScreenSecurity {
static const _channel = MethodChannel('screen_security');
static Future<void> enableSecureMode() async {
await _channel.invokeMethod('enableSecureMode');
}
static Future<void> disableSecureMode() async {
await _channel.invokeMethod('disableSecureMode');
}
}
This ScreenSecurity class provides easy-to-use Dart methods for toggling secure mode.
π§ͺ Step 3: Build the UI with Toggle Switch Letβs wire it all up with a SwitchListTile in your home screen:
// lib/home_screen.dart
import 'package:flutter/material.dart';
import 'controller/screen_security.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool isSecureModeEnabled = false;
@override
void dispose() {
ScreenSecurity.disableSecureMode(); // Clean up
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Secure Screen Demo')),
body: Center(
child: SwitchListTile(
value: isSecureModeEnabled,
onChanged: (v) {
setState(() {
isSecureModeEnabled = v;
if (v) {
ScreenSecurity.enableSecureMode();
} else {
ScreenSecurity.disableSecureMode();
}
});
},
title: const Text('Enable Secure Mode'),
),
),
);
}
}
π± Platform Support
Platform | Status |
---|---|
β Android | Supported via FLAG_SECURE |
β iOS | Not Supported (iOS doesnβt allow controlling screenshots programmatically) |
β Best Practices Use secure mode when displaying sensitive content like:
-
Documents
-
Private messages
-
Financial or medical data
Always disable secure mode when it's no longer needed, such as in dispose().
π Credits Built with β€οΈ using Flutter + native Android integration.
π¦ Source Code: GitHub Repository