flutter_biometric_auth_plus 0.0.2
flutter_biometric_auth_plus: ^0.0.2 copied to clipboard
Enhanced biometric authentication with fallback options and better error handling for Flutter applications.
import 'package:flutter/material.dart';
import 'package:flutter_biometric_auth_plus/flutter_biometric_auth_plus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Biometric Auth Plus Example',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const BiometricAuthDemo(),
);
}
}
class BiometricAuthDemo extends StatefulWidget {
const BiometricAuthDemo({super.key});
@override
State<BiometricAuthDemo> createState() => _BiometricAuthDemoState();
}
class _BiometricAuthDemoState extends State<BiometricAuthDemo> {
String _status = 'Ready';
List<BiometricAuthType> _availableBiometrics = [];
bool _isLoading = false;
@override
void initState() {
super.initState();
_checkBiometrics();
}
Future<void> _checkBiometrics() async {
setState(() {
_isLoading = true;
_status = 'Checking biometrics...';
});
try {
final bool isAvailable = await BiometricAuth.isBiometricsAvailable();
final List<BiometricAuthType> biometrics =
await BiometricAuth.getAvailableBiometrics();
final String strength = await BiometricAuth.getBiometricStrength();
setState(() {
_availableBiometrics = biometrics;
_status = isAvailable
? 'Biometrics available (Strength: $strength)'
: 'Biometrics not available';
_isLoading = false;
});
} catch (e) {
setState(() {
_status = 'Error checking biometrics: $e';
_isLoading = false;
});
}
}
Future<void> _authenticate() async {
setState(() {
_isLoading = true;
_status = 'Authenticating...';
});
try {
final AuthResult result = await BiometricAuth.authenticate(
reason: 'Please authenticate to access the app',
);
setState(() {
_status = result.isSuccess
? 'Authentication successful using ${result.biometricType.displayName}'
: 'Authentication failed';
_isLoading = false;
});
} on BiometricException catch (e) {
setState(() {
_status = 'Biometric error: ${e.message}';
_isLoading = false;
});
} catch (e) {
setState(() {
_status = 'Unexpected error: $e';
_isLoading = false;
});
}
}
Future<void> _authenticateWithFallback() async {
setState(() {
_isLoading = true;
_status = 'Authenticating with fallback...';
});
try {
final AuthResult result = await BiometricAuth.authenticateWithFallback(
reason: 'Please authenticate to access the app',
);
setState(() {
if (result.isSuccess) {
if (result.data?['fallbackUsed'] == true) {
_status = 'Authenticated using device passcode';
} else {
_status = 'Authenticated using biometrics';
}
} else {
_status = 'Authentication failed';
}
_isLoading = false;
});
} on BiometricException catch (e) {
setState(() {
_status = 'Biometric error: ${e.message}';
_isLoading = false;
});
} catch (e) {
setState(() {
_status = 'Unexpected error: $e';
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Biometric Auth Demo'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Status: $_status',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
if (_availableBiometrics.isNotEmpty) ...[
Text(
'Available biometrics:',
style: Theme.of(context).textTheme.titleSmall,
),
const SizedBox(height: 4),
...(_availableBiometrics
.map((type) => Text('• ${type.displayName}'))),
],
],
),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _isLoading ? null : _checkBiometrics,
child: const Text('Check Biometrics'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: _isLoading || _availableBiometrics.isEmpty
? null
: _authenticate,
child: const Text('Authenticate'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: _isLoading ? null : _authenticateWithFallback,
child: const Text('Authenticate with Fallback'),
),
if (_isLoading) ...[
const SizedBox(height: 16),
const Center(child: CircularProgressIndicator()),
],
],
),
),
);
}
}