import 'package:flutter/material.dart'; import 'package:nfc_manager/nfc_manager.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'NFC Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), useMaterial3: true, ), home: const NfcExamplePage(), ); } } class NfcExamplePage extends StatefulWidget { const NfcExamplePage({super.key}); @override State createState() => _NfcExamplePageState(); } class _NfcExamplePageState extends State { String _status = 'App ready'; String _tagInfo = ''; bool _isSessionStarted = false; @override void initState() { super.initState(); NfcManager.instance.isAvailable().then((available) { setState(() { _status = available ? 'NFC disponible' : 'NFC non disponible'; }); }); } void _startSession() async { bool available = await NfcManager.instance.isAvailable(); if (!available) { setState(() => _status = 'NFC non disponible'); return; } setState(() { _status = 'En attente d\'un tag NFC... Approchez le tag'; _tagInfo = ''; _isSessionStarted = true; }); // pollingOptions is required on some platforms (Android) to specify techs NfcManager.instance.startSession( onDiscovered: (dynamic tag) async { String info = ''; // Avoid direct access to tag.data to prevent analyzer issues. // We stringify the tag and attempt to extract 'id' if it's a Map. try { info += 'Raw tag: ${tag.toString()}\n'; if (tag is Map && tag.containsKey('id')) { info += 'ID : ${tag['id']}\n'; } } catch (_) { info += 'Impossible de parser le tag\n'; } // If the tag contains NDEF info, it is usually present in tag.data // We stringify whatever data is available. setState(() { _tagInfo = info.isNotEmpty ? info : 'Tag détecté (détails indisponibles)'; _status = 'Tag détecté'; }); // stop session (no errorMessage parameter in some versions) await NfcManager.instance.stopSession(); setState(() => _isSessionStarted = false); }, // Use default polling options as a set pollingOptions: { NfcPollingOption.iso14443, NfcPollingOption.iso15693, NfcPollingOption.iso18092, }, ); } void _stopSession() async { await NfcManager.instance.stopSession(); setState(() { _status = 'Session arrêtée'; _isSessionStarted = false; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('NFC Manager Demo')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text('Status: $_status'), const SizedBox(height: 12), Expanded( child: SingleChildScrollView( child: Text(_tagInfo.isEmpty ? 'Aucun tag lu pour le moment.' : _tagInfo), ), ), const SizedBox(height: 12), Row( children: [ Expanded( child: ElevatedButton( onPressed: _isSessionStarted ? null : _startSession, child: const Text('Démarrer session NFC'), ), ), const SizedBox(width: 12), Expanded( child: ElevatedButton( onPressed: _isSessionStarted ? _stopSession : null, style: ElevatedButton.styleFrom(backgroundColor: Colors.red), child: const Text('Arrêter'), ), ), ], ), const SizedBox(height: 8), Text('Remarques:\n- Testez sur un appareil réel avec NFC activé.\n- L\'émulateur Android ne prend généralement pas en charge le NFC.'), ], ), ), ); } }