secure_app_locker
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
One-Line Setup (Recommended)
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.