Secure Content

Protect sensitive Flutter UI from recording visibility, app switcher previews, and runtime risk states on Android and iOS. On iOS, screenshot events are detected and reported.


Platform Pub Package License: MIT


Screenshots

Android - Screen recording demo

https://user-images.githubusercontent.com/60510869/154502746-830d9198-8f11-46ba-9246-784def00f610.mp4

iOS - Screenshot detection result
iOS - Screen recording demo

https://github.com/user-attachments/assets/0b4e10ac-d592-4b5b-92bf-72f51b2cf570

iOS - App switcher demo

https://github.com/user-attachments/assets/b6ef5914-eb3a-4e17-be0c-2f00538cffec

Features

  • Screenshot detection and recording obscuring
  • App switcher protection with configurable color and optional branding image (iOS)
  • Android 14+ screenshot callback support
  • Biometric/device credential re-auth hooks
  • Inactivity auto-lock for secure areas
  • Integrity risk checks (root/jailbreak/debugger/emulator heuristics)
  • Soft mode events and optional hard-block mode
  • Sensitive clipboard with TTL-based auto-clear
  • Risk-state watermark overlay (only shown when needed)

Installation

dependencies:
  secure_content: ^2.1.0

Quick Start

import 'package:flutter/material.dart';
import 'package:secure_content/secure_content.dart';

SecureContentScope(
  enabled: true,
  protectInAppSwitcher: true,
  appSwitcherColor: Colors.black,
  policy: const SecureContentPolicy(
    requireBiometricOnResume: true,
    inactivityTimeout: Duration(seconds: 30),
    enableIntegrityChecks: true,
    hardBlockOnIntegrityRisk: false,
    enableRiskWatermark: true,
    watermarkText: 'CONFIDENTIAL',
  ),
  onEvent: (event) {
    debugPrint('Secure event: ${event.type.name}');
  },
  child: const YourSensitiveWidget(),
)

Scope and Native Protection

SecureContentScope scopes the Flutter overlay, lock screen, and risk watermark to its child. When the scope is enabled, it also enables native capture protection for the current app window. Native protection is not limited to the scope's child.

App Switcher Branding (iOS)

On iOS, when the app moves to the background, the multitasking snapshot and biometric re-auth moment are covered by a privacy overlay. By default this is a flat appSwitcherColor fill. Pass appSwitcherImageName to center one of your host app's native asset-catalog images on that overlay, rendered as a white-tinted template:

SecureContentScope(
  enabled: true,
  protectInAppSwitcher: true,
  appSwitcherColor: Colors.black,
  // Name of an image in the iOS app's asset catalog (Assets.xcassets).
  appSwitcherImageName: 'AppSwitcherLogo',
  child: const YourSensitiveWidget(),
)

Note: appSwitcherImageName is iOS-only. Android uses FLAG_SECURE for capture and app-switcher protection. When protectInAppSwitcher is true, Android also sets the navigation-bar color to appSwitcherColor. Android does not add a branded app-switcher overlay, and it ignores the image name.

Global Protection

await SecureContent.setGlobalProtection(
  true,
  protectInAppSwitcher: true,
  appSwitcherColor: Colors.black,
);

Clipboard TTL

await SecureContent.setSensitiveClipboard(
  'one-time code: 123456',
  clearAfter: const Duration(seconds: 10),
);

Events

Listen to all secure events globally:

SecureContent.events.listen((event) {
  debugPrint('Secure event: ${event.type.name}');
});

Key event types include:

  • screenshotCaptured
  • recordingStarted / recordingStopped
  • biometricAuthSucceeded / biometricAuthFailed / biometricUnavailable
  • integritySafe / integrityRiskDetected
  • clipboardSet / clipboardCleared
  • idleLockActivated / idleLockReleased

Platform Support

Feature iOS Android
Screenshot Prevention
Screen Recording Obscuring
Screenshot Detection Callback ✅ (Android 14+)
Screen Recording Start Callback
Screen Recording Stop Callback
Biometric Re-Auth
Inactivity Auto-Lock
Integrity Risk Check
Hard Block Mode
Sensitive Clipboard TTL
Risk-State Watermark
App Switcher Protection
Dynamic Security Toggle
Full App Protection

Notes

  • Android screenshot callback requires Android 14+.
  • Visual capture protection does not mute audio in a screen recording. Mute audio separately in the recording or media layer.
  • Android system clipboard "Copied to clipboard" toast is controlled by the OS and cannot be disabled by apps.
  • Integrity checks are heuristic signals, not a guaranteed anti-tamper boundary.
  • The iOS example keeps CocoaPods integration. Flutter 3.44.3 builds with a warning that asks you to remove the CocoaPods integration after all plugins use Swift Package Manager. The warning does not block the current build.

Example

See example/lib/main.dart for a complete implementation including:

  • global protection toggle
  • biometric trigger
  • integrity check trigger
  • clipboard TTL action
  • hard-block mode toggle
  • secure scope with policy

License

This project is licensed under the MIT License - see the LICENSE file for details.

Libraries

secure_content