secure_app_locker

pub package License: MIT Platform

An all-in-one security plugin for Flutter. Unlike other packages that only provide biometric authentication, secure_app_locker gives your application an entire security layer with a single initialization call — covering biometric authentication, secure screen protection, auto-lock on resume, and background timeout lock.


Why secure_app_locker?

Most developers using local_auth still have to build from scratch:

  • ❌ A Lock Screen overlay widget
  • ❌ Automatic timeout-based lock logic
  • ❌ Screenshot & app switcher protection
  • ❌ Lifecycle state tracking

With secure_app_locker you get all of that in one line:

await SecureAppLocker.initialize(
  secureScreen: true,
  autoLockOnResume: true,
  lockTimeout: const Duration(minutes: 5),
  authReason: 'Verify your identity to continue',
);

Perfect for: Banking Apps · Fintech · Crypto Wallets · Healthcare · Enterprise CRMs · Inventory Systems · HR Apps


Features

Feature Android iOS
🔐 Biometric Auth (Fingerprint / Face ID) ✅ ✅
⌨️ Device Passcode / PIN Fallback ✅ ✅
🚫 Screenshot Block ✅ —
🌫️ App Switcher Blur (Background Preview) ✅ ✅
🔄 Auto-Lock on Resume ✅ ✅
⏱️ Configurable Background Timeout ✅ ✅
🖼️ Built-in Lock Screen Overlay Widget ✅ ✅
🎨 Custom Lock Screen Widget Support ✅ ✅

Getting Started

1. Add Dependency

dependencies:
  secure_app_locker: ^1.0.0

2. Android Setup

a) Add the biometric permission to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.USE_BIOMETRIC"/>

b) Inherit from FlutterFragmentActivity in your MainActivity.kt:

import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity : FlutterFragmentActivity()

3. iOS Setup

Add the Face ID usage description to your ios/Runner/Info.plist:

<key>NSFaceIDUsageDescription</key>
<string>We need your Face ID to unlock the application and secure your data.</string>

Usage

Wrap your app's home screen with SecureAppLockerWrapper and call initialize() during startup:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await SecureAppLocker.initialize(
    secureScreen: true,        // Block screenshots + blur app switcher
    autoLockOnResume: true,    // Lock when app returns from background
    lockTimeout: Duration(minutes: 5), // Only lock if backgrounded >5 min
    authReason: 'Verify your identity to access your secure vault',
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const SecureAppLockerWrapper(
        child: HomePage(),  // Your home screen here
      ),
    );
  }
}

The SecureAppLockerWrapper automatically overlays the built-in premium lock screen when the app is locked, and calls unlock() when the user taps the unlock button.


Custom Lock Screen

You can provide your own lock screen widget:

SecureAppLockerWrapper(
  lockedScreen: const MyCustomLockScreen(),
  child: const HomePage(),
)

Manual Lock & Unlock

// Instantly lock the application
SecureAppLocker.lock();

// Trigger the authentication prompt to unlock
final success = await SecureAppLocker.unlock();

Manual Authentication

Prompt for biometrics or passcode without locking the app:

final SecureAuthResult result = await SecureAppLocker.authenticate(
  reason: 'Confirm your identity to proceed',
  biometricOnly: false, // false = allow passcode fallback
);

switch (result) {
  case SecureAuthResult.success:
    print('Access Granted');
  case SecureAuthResult.canceled:
    print('User canceled');
  case SecureAuthResult.notAvailable:
    print('Biometrics not available');
  case SecureAuthResult.passcodeNotSet:
    print('No passcode set on device');
  case SecureAuthResult.error:
    print('Authentication error');
}

Check Biometric Availability

final bool available = await SecureAppLocker.isBiometricAvailable();

Reactive Lock State

Listen to the current lock state in your UI:

ValueListenableBuilder<bool>(
  valueListenable: SecureAppLocker.isLocked,
  builder: (context, isLocked, _) {
    return Text(isLocked ? 'App is Locked' : 'App is Unlocked');
  },
);

Secure Screen Standalone

Enable or disable screenshot protection independently:

await SecureAppLocker.setSecureScreen(true);  // Enable
await SecureAppLocker.setSecureScreen(false); // Disable

API Reference

SecureAppLocker.initialize({...})

Parameter Type Default Description
secureScreen bool false Blocks screenshots (Android) & blurs app switcher preview
autoLockOnResume bool false Locks app when resumed from background
lockTimeout Duration? null Background duration before locking. null = lock immediately on any resume
biometricOnly bool false Restrict auto-unlock to biometrics only (no passcode fallback)
authReason String 'Authenticate...' Message displayed on the authentication dialog

SecureAuthResult Enum

Value Description
success Authentication succeeded
canceled User dismissed the prompt
notAvailable No biometric hardware or no biometrics enrolled
passcodeNotSet No device passcode is configured
error Unexpected authentication failure

Roadmap

  • v1.0 ✅ Biometric Auth + Secure Screen + Auto-Lock + Timeout Lock
  • v1.3 — PIN Lock Screen
  • v2.0 — Pattern Lock, Root/Jailbreak Detection, Fake Overlay Detection

License

MIT License. See LICENSE.