simple_biometric 0.0.1 copy "simple_biometric: ^0.0.1" to clipboard
simple_biometric: ^0.0.1 copied to clipboard

A biometric Flutter plugin.

example/lib/main.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:simple_biometric/simple_biometric.dart';
import 'package:simple_biometric/enums.dart';

void main() {
  runApp(const LoginApp());
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Biometric Login',
      home: LoginPage(),
    );
  }
}

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

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  final SimpleBiometric _simpleBiometric = SimpleBiometric();
  bool _isBiometricAvailable = false;
  bool _biometricEnabled = false;
  String _biometricType = "";

  @override
  void initState() {
    super.initState();
    _simpleBiometric.getIOSBiometricType().then((value) {
      setState(() {
        _biometricType = value == IOSBiometricType.faceId
            ? "Face Id"
            : value == IOSBiometricType.touchId
                ? "Touch ID"
                : "";
      });
    });
    _checkBiometricAvailability().then((value) {
      setState(() {
        _isBiometricAvailable = value;
      });
    });
  }

  Future<bool> _checkBiometricAvailability() async {
    bool isBiometricAvailable = false;
    if (Platform.isAndroid) {
      final res = await _simpleBiometric.isAndroidBiometricHardwareAvailable();
      isBiometricAvailable = res;
    } else if (Platform.isIOS) {
      final iosBiometricType = await _simpleBiometric.getIOSBiometricType();
      isBiometricAvailable = iosBiometricType != IOSBiometricType.none;
    }
    return isBiometricAvailable;
  }

  Future<void> _authenticate() async {
    if (_biometricEnabled) {
      try {
        final result = await _simpleBiometric.showBiometricPrompt(
          title: 'Biometric Authentication',
          description: 'Authenticate using your biometric credential',
          cancelText: 'Cancel',
        );

        if (result == BiometricStatusResult.authSuccess) {
          // Authentication successful, navigate to next screen
          //print('Authentication successful');
        } else if (result == BiometricStatusResult.noBiometrics) {
          // No biometrics available
          //print('No biometrics available');
          if (context.mounted) {
            showDialog(
              context: context,
              builder: (context) => AlertDialog(
                title: const Text('No Biometrics Available'),
                content: const Text(
                    'Please go to settings and set up your biometric authentication.'),
                actions: [
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop(); // Close the dialog
                      // Optionally, open the device settings
                      // You can use a plugin like `app_settings` to open the device settings
                    },
                    child: const Text('OK'),
                  ),
                ],
              ),
            );
          }
        } else if (result == BiometricStatusResult.noHardware) {
          // Biometric hardware not available
          //print('Biometric hardware not available');
        } else {
          // Authentication failed or unknown error
          //print('Authentication failed');
        }
      } catch (e) {
        // Error occurred during authentication
        if (e is PlatformException && e.code == 'AUTH_ERROR') {
          final errorMessage =
              e.message ?? 'Authentication error. Please try again later.';
          if (context.mounted) {
            showDialog(
              context: context,
              builder: (context) => AlertDialog(
                title: const Text('Error'),
                content: Text(errorMessage),
                actions: [
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop(); // Close the dialog
                    },
                    child: const Text('OK'),
                  ),
                ],
              ),
            );
          }
        }
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Biometric Login'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            TextField(
              controller: _usernameController,
              decoration: const InputDecoration(labelText: 'Username'),
            ),
            TextField(
              controller: _passwordController,
              decoration: const InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            ElevatedButton(
              onPressed: _authenticate,
              child: const Text('Login'),
            ),
            if (Platform.isAndroid && _isBiometricAvailable == false)
              const SizedBox.shrink(),
            if ((Platform.isAndroid || Platform.isIOS) && _isBiometricAvailable)
              CheckboxListTile(
                title: Text(
                    'Enable ${Platform.isAndroid ? "biometric" : "$_biometricType access"}'),
                value: _biometricEnabled,
                onChanged: (value) {
                  setState(() {
                    _biometricEnabled = value!;
                  });
                },
              ),
          ],
        ),
      ),
    );
  }
}