flutter_screenguard
A Native screenshot blocking plugin for Flutter developer, with powerful event detection capabilities.
โจ Features
- ๐ก๏ธ Block screenshots with customizable color overlay, blur effect, or image overlay
- ๐ธ Screenshot detection โ listen for screenshot events with optional captured file info
- ๐ฅ Screen recording detection โ detect when screen recording starts/stops
- ๐ Event logging โ track and retrieve screenguard logs from native storage
- ๐ง Highly configurable โ fine-tune behavior per platform with
initSettings
๐ Requirements
| Platform | Minimum Version |
|---|---|
| Flutter | โฅ 3.7.0 |
| Dart | โฅ 3.4.0 < 4.0.0 |
| iOS | โฅ 12.0 |
| Android compileSdk | 34 |
| Java | 17 |
| Android Gradle Plugin | โฅ 8.3.0 |
| Gradle wrapper | โฅ 7.6 |
๐ฆ Installation
Add flutter_screenguard to your pubspec.yaml:
dependencies:
flutter_screenguard: ^2.0.0
Or install via CLI:
flutter pub add flutter_screenguard
โ ๏ธ Post-Installation Setup (Android) (v1.0.0 only)
Important
You must complete these steps on Android for color overlay and blur effects to work properly. v2.0.0+ no longer need to do this step!
1. Register the overlay Activity
Open android/app/src/main/AndroidManifest.xml and add ScreenGuardColorActivity inside the <application> tag:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application ...>
<activity
android:name=".MainActivity" ...>
...
</activity>
<!-- Add this โ -->
<activity android:name="com.screenguard.flutter_screenguard.ScreenGuardColorActivity"
android:theme="@style/Theme.AppCompat.Translucent"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
android:exported="false"
/>
</application>
</manifest>
Open up your_project_path/android/app/src/main/res/values/styles.xml and add style Theme.AppCompat.Translucent like below
<resource>
<style name="AppTheme">your current app style theme.............</style>
+ <style name="Theme.AppCompat.Translucent">
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ <item name="android:windowSoftInputMode">adjustResize</item>
+ </style>
</resource>
๐ Usage
Import
import 'package:flutter_screenguard/flutter_screenguard.dart';
Basic Setup
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final FlutterScreenguard _screenguard;
final GlobalKey _globalKey = GlobalKey();
StreamSubscription? _screenshotSub;
StreamSubscription? _recordingSub;
@override
void initState() {
super.initState();
// Pass globalKey if you plan to use registerWithBlurView
_screenguard = FlutterScreenguard(globalKey: _globalKey);
_initScreenGuard();
}
Future<void> _initScreenGuard() async {
// โ Initialize settings (required before calling any register method)
await _screenguard.initSettings(
displayOverlay: true,
displayScreenguardOverlayAndroid: true,
timeAfterResume: 2000,
);
// Listen for screenshot events
_screenshotSub = _screenguard.onScreenshotCaptured.listen((event) {
debugPrint('Screenshot captured: $event');
});
// Listen for screen recording events
_recordingSub = _screenguard.onScreenRecordingCaptured.listen((event) {
debugPrint('Recording event: $event');
});
// โฃ Activate screen protection (pick one)
await _screenguard.register(color: Colors.black);
}
@override
void dispose() {
_screenguard.unregister();
_screenshotSub?.cancel();
_recordingSub?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return RepaintBoundary(
key: _globalKey, // Required for blur effect
child: Scaffold(
body: Center(child: Text('Protected Content')),
),
);
}
}
Note
You must call initSettings() before any register* method, or an exception will be thrown.
๐ API Reference
initSettings
Initialize the screen guard with configuration options. Must be called first.
await _screenguard.initSettings(
enableCapture: false,
enableRecord: false,
enableContentMultitask: false,
displayOverlay: false,
displayScreenguardOverlayAndroid: true,
timeAfterResume: 1000,
getScreenshotPath: false,
limitCaptureEvtCount: 0,
trackingLog: false,
);
| Parameter | Type | Default | Description |
|---|---|---|---|
enableCapture |
bool? |
false |
Enable screenshot capture detection |
enableRecord |
bool? |
false |
Enable screen recording detection |
enableContentMultitask |
bool? |
false |
Show content in multitask/app switcher (iOS only) |
displayOverlay |
bool? |
false |
Display overlay when user captures the screen (iOS only) |
displayScreenguardOverlayAndroid |
bool? |
true |
Display overlay when returning from background (Android only) |
timeAfterResume |
int? |
1000 |
Delay (ms) before the overlay disappears when returning to the app |
getScreenshotPath |
bool? |
false |
Include file path in screenshot event data |
limitCaptureEvtCount |
int? |
0 |
Max number of screenshot events to trigger (0 = unlimited) |
trackingLog |
bool? |
false |
Save events to native storage for later retrieval |
register
Activate screen protection with a solid color overlay.
await _screenguard.register(color: Colors.red);
await _screenguard.register(color: Color(0xFFFFFC31));
| Parameter | Type | Required | Description |
|---|---|---|---|
color |
Color |
โ | Background color for the protection overlay |
registerWithBlurView
Activate screen protection with a blurred snapshot of the current screen.
Important
You must wrap your root widget with RepaintBoundary and pass its GlobalKey to FlutterScreenguard (via constructor or method parameter).
// GlobalKey provided in constructor
await _screenguard.registerWithBlurView(radius: 25);
// Or provide GlobalKey per-call
await _screenguard.registerWithBlurView(radius: 25, globalKey: myKey);
| Parameter | Type | Required | Description |
|---|---|---|---|
radius |
num |
โ | Blur radius. Recommended range: 15โ50 |
globalKey |
GlobalKey? |
โ | Override the key passed in the constructor |
Tip
A radius below 15 is too subtle โ content remains readable. Above 50 is overkill โ content shrinks and disappears. The sweet spot is 15โ50.
registerWithImage
Activate screen protection with a custom image overlay.
Uses SDWebImage on iOS and Glide on Android for fast loading and caching.
await _screenguard.registerWithImage(
uri: 'https://example.com/logo.png',
width: 150,
height: 300,
alignment: Alignment.center,
color: Colors.black,
);
| Parameter | Type | Required | Description |
|---|---|---|---|
uri |
String |
โ | URL of the image to display |
width |
double |
โ | Width of the image |
height |
double |
โ | Height of the image |
color |
Color? |
โ | Background color (default: Colors.black) |
alignment |
Alignment? |
โ | Image position using Flutter Alignment constants |
top |
double? |
โ | Custom top position |
left |
double? |
โ | Custom left position |
bottom |
double? |
โ | Custom bottom position |
right |
double? |
โ | Custom right position |
Note
alignment takes priority over manual positioning (top, left, bottom, right). Set alignment to null if you want to use custom positions.
registerWithoutEffect
Activate screen protection without any visual overlay. (Android only)
await _screenguard.registerWithoutEffect();
unregister
Deactivate all screen protection and clean up.
await _screenguard.unregister();
onScreenshotCaptured
A Stream<Map<String, dynamic>> that emits events when a screenshot is captured.
_screenguard.onScreenshotCaptured.listen((event) {
debugPrint('Screenshot: $event');
// event may contain: path, name, type (if getScreenshotPath is enabled)
});
onScreenRecordingCaptured
A Stream<Map<String, dynamic>> that emits events when screen recording starts or stops.
_screenguard.onScreenRecordingCaptured.listen((event) {
final isRecording = event['isRecording'] as bool;
debugPrint('Recording: $isRecording');
});
| Key | Type | Description |
|---|---|---|
isRecording |
bool |
true = recording started, false = recording stopped |
activationStatus |
Map |
Contains method (String) and isActivated (bool) |
getScreenGuardLogs
Retrieve stored event logs from native storage. Requires trackingLog: true in initSettings.
final logs = await _screenguard.getScreenGuardLogs(maxCount: 50);
for (final log in logs) {
debugPrint('Log: $log');
}
| Parameter | Type | Required | Description |
|---|---|---|---|
maxCount |
int |
โ | Maximum number of log entries to retrieve |
๐งช Testing
iOS Simulator
Navigate to Device โ Trigger Screenshot in the Simulator menu (iOS 14+).
Android Emulator
- Use an emulator with Google Play Services and install a third-party screenshot/recording app (e.g., XRecorder, AZ Screen Recorder).
- Android 12+ emulators have built-in screenshot and screen recording in the Quick Settings Panel.
โก Limitations
| Limitation | Details |
|---|---|
| Minimum OS | Screenshot blocking requires iOS 13+ / Android 8+ |
| Single registration | Call only one register* method at a time. Call unregister() before switching |
๐ License
MIT License ยฉ 2024 Goosebump
See LICENSE for details.