diff --git a/lib/bluetooth_connection_screen.dart b/lib/bluetooth_connection_screen.dart deleted file mode 100644 index 193242f..0000000 --- a/lib/bluetooth_connection_screen.dart +++ /dev/null @@ -1,169 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_blue_plus/flutter_blue_plus.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'dart:async'; - -class BluetoothConnectionScreen extends StatefulWidget { - const BluetoothConnectionScreen({super.key}); - - @override - State createState() => _BluetoothConnectionScreenState(); -} - -class _BluetoothConnectionScreenState extends State { - List scanResults = []; - bool isScanning = false; - StreamSubscription? scanSubscription; - StreamSubscription? isScanningSubscription; - - @override - void initState() { - super.initState(); - // Monitorar se o sistema está escaneando - isScanningSubscription = FlutterBluePlus.isScanning.listen((scanning) { - if (mounted) { - setState(() { - isScanning = scanning; - }); - } - }); - - // Ouvir os resultados do scan globalmente - scanSubscription = FlutterBluePlus.scanResults.listen((results) { - if (mounted) { - setState(() { - scanResults = results; - }); - } - }); - } - - @override - void dispose() { - scanSubscription?.cancel(); - isScanningSubscription?.cancel(); - super.dispose(); - } - - Future startScan() async { - // 1. Pedir permissões (necessário no Android) - Map statuses = await [ - Permission.bluetoothScan, - Permission.bluetoothConnect, - Permission.location, - ].request(); - - if (statuses[Permission.bluetoothScan]!.isGranted && - statuses[Permission.bluetoothConnect]!.isGranted && - statuses[Permission.location]!.isGranted) { - - setState(() { - scanResults.clear(); - }); - - // 2. Iniciar o scan - try { - await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15)); - } catch (e) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Erro ao buscar: $e')), - ); - } - } - } else { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Permissões negadas')), - ); - } - } - } - - Future connectToDevice(BluetoothDevice device) async { - try { - await device.connect(); - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Conectado a ${device.platformName.isEmpty ? 'Dispositivo' : device.platformName}')), - ); - } - } catch (e) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Falha ao conectar: $e')), - ); - } - } - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Conexão Bluetooth'), - backgroundColor: Colors.grey[850], - foregroundColor: Colors.white, - ), - backgroundColor: Colors.grey[900], - body: Column( - children: [ - const SizedBox(height: 20), - Center( - child: Column( - children: [ - const Icon( - Icons.bluetooth, - size: 80, - color: Colors.white, - ), - const SizedBox(height: 10), - ElevatedButton.icon( - onPressed: isScanning ? null : startScan, - icon: isScanning - ? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.black)) - : const Icon(Icons.search), - label: Text(isScanning ? 'Buscando...' : 'Procurar Dispositivos'), - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - foregroundColor: Colors.black, - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), - textStyle: const TextStyle(fontSize: 18), - ), - ), - ], - ), - ), - const SizedBox(height: 20), - Expanded( - child: scanResults.isEmpty && !isScanning - ? const Center( - child: Text( - "Nenhum dispositivo encontrado.\nClique em procurar.", - textAlign: TextAlign.center, - style: TextStyle(color: Colors.white70), - ), - ) - : ListView.builder( - itemCount: scanResults.length, - itemBuilder: (context, index) { - final device = scanResults[index].device; - final name = device.platformName.isEmpty ? 'Desconhecido' : device.platformName; - return Card( - color: Colors.white10, - margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - child: ListTile( - title: Text(name, style: const TextStyle(color: Colors.white)), - subtitle: Text(device.remoteId.toString(), style: const TextStyle(color: Colors.white70)), - trailing: const Icon(Icons.link, color: Colors.blue), - onTap: () => connectToDevice(device), - ), - ); - }, - ), - ), - ], - ), - ); - } -} diff --git a/lib/bluetooth_screen.dart b/lib/bluetooth_screen.dart deleted file mode 100644 index c2fe2f3..0000000 --- a/lib/bluetooth_screen.dart +++ /dev/null @@ -1,335 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_blue_plus/flutter_blue_plus.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'dart:async'; -import 'constants/app_colors.dart'; -import 'constants/app_strings.dart'; - -class BluetoothScreen extends StatefulWidget { - const BluetoothScreen({super.key}); - - @override - State createState() => _BluetoothScreenState(); -} - -class _BluetoothScreenState extends State { - List _scanResults = []; - bool _isScanning = false; - StreamSubscription? _scanResultsSubscription; - StreamSubscription? _isScanningSubscription; - - @override - void initState() { - super.initState(); - - _scanResultsSubscription = FlutterBluePlus.scanResults.listen((results) { - if (mounted) { - List sortedResults = List.from(results); - sortedResults.sort((a, b) { - bool aHasName = _hasRealName(a); - bool bHasName = _hasRealName(b); - - if (aHasName && !bHasName) return -1; - if (!aHasName && bHasName) return 1; - return 0; - }); - - setState(() { - _scanResults = sortedResults; - }); - } - }); - - _isScanningSubscription = FlutterBluePlus.isScanning.listen((state) { - if (mounted) { - setState(() { - _isScanning = state; - }); - } - }); - } - - bool _hasRealName(ScanResult r) { - return r.advertisementData.advName.isNotEmpty || r.device.platformName.isNotEmpty; - } - - @override - void dispose() { - _scanResultsSubscription?.cancel(); - _isScanningSubscription?.cancel(); - super.dispose(); - } - - Future startScan() async { - Map statuses = await [ - Permission.bluetoothScan, - Permission.bluetoothConnect, - Permission.location, - ].request(); - - if (statuses[Permission.bluetoothScan]!.isGranted && - statuses[Permission.bluetoothConnect]!.isGranted) { - - try { - _scanResults.clear(); - await FlutterBluePlus.startScan( - timeout: const Duration(seconds: 15), - androidUsesFineLocation: true, - continuousUpdates: true, - ); - - Future.delayed(const Duration(seconds: 8), () { - if (mounted && _scanResults.isEmpty && _isScanning) { - _showSnackBar(AppStrings.noDevicesFound, AppColors.coral); - } - }); - - } catch (e) { - _showSnackBar("${AppStrings.scanError}$e", AppColors.error); - } - } else { - _showSnackBar(AppStrings.permissionsDenied, AppColors.coral); - } - } - - Future stopScan() async { - try { - await FlutterBluePlus.stopScan(); - } catch (e) { - _showSnackBar("${AppStrings.stopScanError}$e", AppColors.error); - } - } - - Future connectToDevice(BluetoothDevice device) async { - try { - String name = device.platformName.isNotEmpty ? device.platformName : AppStrings.defaultDeviceName; - _showSnackBar("${AppStrings.connectingTo}$name...", AppColors.white.withValues(alpha: 0.7)); - await device.connect(); - _showSnackBar(AppStrings.connectedSuccess, AppColors.success); - } catch (e) { - _showSnackBar("${AppStrings.connectFail}$e", AppColors.error); - } - } - - String _getDeviceName(ScanResult r) { - if (r.advertisementData.advName.isNotEmpty) { - return r.advertisementData.advName; - } else if (r.device.platformName.isNotEmpty) { - return r.device.platformName; - } else { - String id = r.device.remoteId.toString(); - return "${AppStrings.deviceIdPrefix}${id.length > 5 ? id.substring(id.length - 5) : id}]"; - } - } - - void _showSnackBar(String message, Color color) { - if (!mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(message), - backgroundColor: color, - duration: const Duration(seconds: 3), - behavior: SnackBarBehavior.floating, - ), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text(AppStrings.bluetoothTitle, style: TextStyle(fontWeight: FontWeight.bold)), - centerTitle: true, - backgroundColor: AppColors.transparent, - elevation: 0, - foregroundColor: AppColors.white, - ), - extendBodyBehindAppBar: true, - backgroundColor: AppColors.background, - body: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - AppColors.coral.withValues(alpha: 0.1), - AppColors.background, - ], - ), - ), - child: Column( - children: [ - const SizedBox(height: 100), - - Center( - child: Column( - children: [ - Container( - padding: const EdgeInsets.all(25), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: _isScanning - ? AppColors.coral.withValues(alpha: 0.1) - : AppColors.backgroundGrey.withValues(alpha: 0.3), - border: Border.all( - color: _isScanning ? AppColors.coral : AppColors.backgroundGrey, - width: 2, - ), - ), - child: Icon( - _isScanning ? Icons.bluetooth_searching : Icons.bluetooth, - size: 60, - color: _isScanning ? AppColors.coral : AppColors.white.withValues(alpha: 0.7), - ), - ), - const SizedBox(height: 30), - - SizedBox( - width: 220, - height: 50, - child: ElevatedButton( - onPressed: _isScanning ? stopScan : startScan, - style: ElevatedButton.styleFrom( - backgroundColor: _isScanning ? AppColors.backgroundGrey : AppColors.white, - foregroundColor: _isScanning ? AppColors.white : AppColors.background, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(25), - ), - elevation: 0, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (_isScanning) - const Padding( - padding: EdgeInsets.only(right: 10), - child: SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator( - strokeWidth: 2, - color: AppColors.white, - ), - ), - ), - Text( - _isScanning ? AppStrings.stopSearch : AppStrings.startSearch, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - letterSpacing: 1.2, - ), - ), - ], - ), - ), - ), - ], - ), - ), - - const SizedBox(height: 40), - - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: Row( - children: [ - Text( - _isScanning ? AppStrings.searching : AppStrings.nearbyDevices, - style: const TextStyle( - color: AppColors.white, - fontSize: 14, - fontWeight: FontWeight.w500, - ), - ), - const Spacer(), - if (_isScanning) - Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), - decoration: BoxDecoration( - color: AppColors.coral.withValues(alpha: 0.2), - borderRadius: BorderRadius.circular(10), - ), - child: const Text( - AppStrings.active, - style: TextStyle(color: AppColors.coral, fontSize: 10, fontWeight: FontWeight.bold), - ), - ), - ], - ), - ), - const SizedBox(height: 15), - - Expanded( - child: _scanResults.isEmpty && !_isScanning - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.bluetooth_disabled, size: 40, color: AppColors.white.withValues(alpha: 0.1)), - const SizedBox(height: 16), - Text( - AppStrings.startSearchInstruction, - style: TextStyle(color: AppColors.white.withValues(alpha: 0.3)), - ), - ], - ), - ) - : ListView.builder( - padding: const EdgeInsets.only(top: 0, bottom: 20), - itemCount: _scanResults.length, - itemBuilder: (context, index) { - final r = _scanResults[index]; - final name = _getDeviceName(r); - final isUnknown = name.startsWith(AppStrings.deviceIdPrefix); - - return Container( - margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 6), - decoration: BoxDecoration( - color: AppColors.backgroundGrey.withValues(alpha: 0.2), - borderRadius: BorderRadius.circular(15), - ), - child: ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - leading: CircleAvatar( - backgroundColor: AppColors.backgroundGrey.withValues(alpha: 0.3), - child: Icon( - isUnknown ? Icons.devices_other : Icons.bluetooth, - color: isUnknown ? AppColors.white.withValues(alpha: 0.4) : AppColors.white, - size: 20 - ), - ), - title: Text( - name, - style: TextStyle( - color: isUnknown ? AppColors.white.withValues(alpha: 0.5) : AppColors.white, - fontWeight: FontWeight.w600, - fontSize: 15, - ), - ), - subtitle: Text( - r.device.remoteId.toString(), - style: TextStyle(color: AppColors.white.withValues(alpha: 0.3), fontSize: 11), - ), - trailing: ElevatedButton( - onPressed: () => connectToDevice(r.device), - style: ElevatedButton.styleFrom( - backgroundColor: AppColors.coral, - foregroundColor: AppColors.white, - padding: const EdgeInsets.symmetric(horizontal: 12), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), - elevation: 0, - ), - child: const Text(AppStrings.connect, style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold)), - ), - ), - ); - }, - ), - ), - ], - ), - ), - ); - } -}