Skip to main content

secure_app_locker 1.0.0 copy "secure_app_locker: ^1.0.0" to clipboard
secure_app_locker: ^1.0.0 copied to clipboard

A production-grade secure app locker plugin for Flutter. Provides biometric (Fingerprint, Face ID) and passcode authentication, along with secure screen features like screenshot prevention and backgro [...]

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:secure_app_locker/secure_app_locker.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setSystemUIOverlayStyle(
    const SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      statusBarIconBrightness: Brightness.light,
    ),
  );
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Secure App Locker',
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: const Color(0xFF0F172A),
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF6366F1),
          brightness: Brightness.dark,
        ),
      ),
      home: const SecureAppLockerWrapper(child: SecureAppLockerExample()),
    );
  }
}

class SecureAppLockerExample extends StatefulWidget {
  const SecureAppLockerExample({super.key});

  @override
  State<SecureAppLockerExample> createState() => _SecureAppLockerExampleState();
}

class _SecureAppLockerExampleState extends State<SecureAppLockerExample> {
  bool _isBiometricAvailable = false;
  bool _isSecureScreenEnabled = true;
  bool _isAutoLockEnabled = true;
  Duration? _selectedTimeout = const Duration(seconds: 5);
  SecureAuthResult? _authResult;
  String _errorMessage = '';

  final List<Map<String, dynamic>> _timeoutOptions = [
    {'label': 'Immediate (0s)', 'value': Duration.zero},
    {'label': '5 Seconds', 'value': const Duration(seconds: 5)},
    {'label': '15 Seconds', 'value': const Duration(seconds: 15)},
    {'label': '30 Seconds', 'value': const Duration(seconds: 30)},
    {'label': '1 Minute', 'value': const Duration(minutes: 1)},
  ];

  @override
  void initState() {
    super.initState();
    _checkBiometricAvailability();
    _reinitializePlugin();
  }

  Future<void> _checkBiometricAvailability() async {
    try {
      final available = await SecureAppLocker.isBiometricAvailable();
      if (mounted) {
        setState(() => _isBiometricAvailable = available);
      }
    } catch (e) {
      if (mounted) setState(() => _errorMessage = e.toString());
    }
  }

  Future<void> _reinitializePlugin() async {
    try {
      await SecureAppLocker.initialize(
        secureScreen: _isSecureScreenEnabled,
        autoLockOnResume: _isAutoLockEnabled,
        lockTimeout: _selectedTimeout,
        authReason: 'Verify identity to unlock the secure dashboard',
      );
    } catch (e) {
      if (mounted) setState(() => _errorMessage = e.toString());
    }
  }

  Future<void> _authenticate() async {
    setState(() {
      _authResult = null;
      _errorMessage = '';
    });
    try {
      final result = await SecureAppLocker.authenticate(
        reason: 'Manual authentication test',
        biometricOnly: false,
      );
      setState(() => _authResult = result);
    } catch (e) {
      setState(() => _errorMessage = e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final isSmallScreen = size.height < 700;

    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [Color(0xFF0F172A), Color(0xFF1E1B4B), Color(0xFF311042)],
          ),
        ),
        child: SafeArea(
          child: SingleChildScrollView(
            padding: EdgeInsets.symmetric(
              horizontal: size.width * 0.06, // Responsive horizontal padding
              vertical: 20,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                const SizedBox(height: 20),

                // Header
                Center(
                  child: Column(
                    children: [
                      Container(
                        padding: const EdgeInsets.all(20),
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          gradient: const LinearGradient(
                            colors: [Color(0xFF818CF8), Color(0xFFC084FC)],
                          ),
                          boxShadow: [
                            BoxShadow(
                              color: const Color(0xFF818CF8).withOpacity(0.3),
                              blurRadius: 30,
                              offset: const Offset(0, 10),
                            ),
                          ],
                        ),
                        child: const Icon(Icons.lock_person_rounded, size: 52, color: Colors.white),
                      ),
                      const SizedBox(height: 20),
                      const Text(
                        'Secure App Locker',
                        style: TextStyle(fontSize: 26, fontWeight: FontWeight.bold, color: Colors.white),
                      ),
                      const Text(
                        'All-in-One Security Demo',
                        style: TextStyle(fontSize: 14, color: Color(0xFF94A3B8)),
                      ),
                    ],
                  ),
                ),

                const SizedBox(height: 32),

                // Settings Card
                Container(
                  padding: const EdgeInsets.all(20),
                  decoration: BoxDecoration(
                    color: Colors.white.withOpacity(0.08),
                    borderRadius: BorderRadius.circular(24),
                    border: Border.all(color: Colors.white.withOpacity(0.15)),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text(
                        'SECURITY SETTINGS',
                        style: TextStyle(
                          fontSize: 13,
                          fontWeight: FontWeight.bold,
                          color: Color(0xFF818CF8),
                          letterSpacing: 1,
                        ),
                      ),
                      const SizedBox(height: 20),

                      _buildSettingRow(
                        title: 'Secure Screen Protection',
                        subtitle: 'Prevents screenshots & blurs app switcher',
                        value: _isSecureScreenEnabled,
                        onChanged: (val) {
                          setState(() => _isSecureScreenEnabled = val);
                          _reinitializePlugin();
                        },
                      ),

                      const Divider(color: Colors.white12, height: 32),

                      _buildSettingRow(
                        title: 'Auto-Lock on Resume',
                        subtitle: 'Locks app when closed & re-opened',
                        value: _isAutoLockEnabled,
                        onChanged: (val) {
                          setState(() => _isAutoLockEnabled = val);
                          _reinitializePlugin();
                        },
                      ),

                      if (_isAutoLockEnabled) ...[
                        const Divider(color: Colors.white12, height: 32),
                        _buildTimeoutRow(isSmallScreen),
                      ],
                    ],
                  ),
                ),

                const SizedBox(height: 16),

                // Biometrics Status
                Container(
                  padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
                  decoration: BoxDecoration(
                    color: Colors.white.withOpacity(0.06),
                    borderRadius: BorderRadius.circular(16),
                    border: Border.all(color: Colors.white.withOpacity(0.12)),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      const Row(
                        children: [
                          Icon(Icons.fingerprint_rounded, color: Color(0xFF818CF8), size: 22),
                          SizedBox(width: 12),
                          Text('Biometrics Enrolled', style: TextStyle(fontSize: 15)),
                        ],
                      ),
                      Text(
                        _isBiometricAvailable ? 'YES' : 'NO',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          color: _isBiometricAvailable ? const Color(0xFF34D399) : const Color(0xFFF87171),
                        ),
                      ),
                    ],
                  ),
                ),

                const SizedBox(height: 24),

                // Action Buttons
                ElevatedButton.icon(
                  onPressed: () => SecureAppLocker.lock(),
                  icon: const Icon(Icons.lock_outline_rounded),
                  label: const Text('MANUALLY LOCK APP'),
                  style: ElevatedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(vertical: 18),
                    backgroundColor: const Color(0xFFEF4444),
                    foregroundColor: Colors.white,
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
                  ),
                ),

                const SizedBox(height: 12),

                OutlinedButton.icon(
                  onPressed: _authenticate,
                  icon: const Icon(Icons.fingerprint_rounded),
                  label: const Text('MANUAL AUTHENTICATE'),
                  style: OutlinedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(vertical: 18),
                    foregroundColor: Colors.white,
                    side: const BorderSide(color: Color(0xFF475569)),
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  // Reusable Setting Row
  Widget _buildSettingRow({
    required String title,
    required String subtitle,
    required bool value,
    required Function(bool) onChanged,
  }) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
              const SizedBox(height: 4),
              Text(subtitle, style: const TextStyle(fontSize: 12, color: Color(0xFF94A3B8))),
            ],
          ),
        ),
        Switch.adaptive(
          value: value,
          activeTrackColor: const Color(0xFFC084FC).withOpacity(0.5),
          activeThumbColor: const Color(0xFFC084FC),
          onChanged: onChanged,
        ),
      ],
    );
  }

  // Fixed Timeout Row (Responsive)
  Widget _buildTimeoutRow(bool isSmallScreen) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Lock Timeout', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
              SizedBox(height: 4),
              Text(
                'Required background duration to lock',
                style: TextStyle(fontSize: 12, color: Color(0xFF94A3B8)),
              ),
            ],
          ),
        ),
        DropdownButton<Duration?>(
          value: _selectedTimeout,
          dropdownColor: const Color(0xFF1E1B4B),
          underline: const SizedBox(),
          menuMaxHeight: 300,
          items: _timeoutOptions.map((opt) {
            return DropdownMenuItem(
              value: opt['value'] as Duration?,
              child: Text(opt['label'] as String, style: const TextStyle(fontSize: 14)),
            );
          }).toList(),
          onChanged: (val) {
            setState(() => _selectedTimeout = val);
            _reinitializePlugin();
          },
        ),
      ],
    );
  }
}
9
likes
140
points
10
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A production-grade secure app locker plugin for Flutter. Provides biometric (Fingerprint, Face ID) and passcode authentication, along with secure screen features like screenshot prevention and background app switcher blurring.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on secure_app_locker

Packages that implement secure_app_locker