import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/services.dart'; import 'package:flutter_beacon/flutter_beacon.dart'; import 'package:get/get.dart'; import 'package:manager_api/api.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Components/Loading.dart'; import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart'; import 'package:mymuseum_visitapp/Helpers/networkCheck.dart'; import 'package:mymuseum_visitapp/Helpers/requirement_state_controller.dart'; import 'package:mymuseum_visitapp/Helpers/translationHelper.dart'; import 'package:mymuseum_visitapp/Models/visitContext.dart'; import 'package:mymuseum_visitapp/Screens/Visit/visit.dart'; import 'package:mymuseum_visitapp/Services/apiService.dart'; import 'package:mymuseum_visitapp/Services/downloadConfiguration.dart'; import 'package:mymuseum_visitapp/app_context.dart'; import 'package:mymuseum_visitapp/client.dart'; import 'package:mymuseum_visitapp/constants.dart'; import 'package:provider/provider.dart'; import 'configurations_list.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State createState() => _HomePageState(); } class _HomePageState extends State with WidgetsBindingObserver { final controller = Get.find(); StreamSubscription? _streamBluetooth; int currentIndex = 0; List configurations = []; List alreadyDownloaded = []; VisitAppContext? visitAppContext; StreamSubscription? _streamRanging; final _regionBeacons = >{}; final _beacons = []; //final controller = Get.find(); @override void initState() { WidgetsBinding.instance.addObserver(this); super.initState(); listeningState(); } listeningState() async { print('Listening to bluetooth state'); _streamBluetooth = flutterBeacon .bluetoothStateChanged() .listen((BluetoothState state) async { controller.updateBluetoothState(state); await checkAllRequirements(); }); } checkAllRequirements() async { final bluetoothState = await flutterBeacon.bluetoothState; controller.updateBluetoothState(bluetoothState); print('BLUETOOTH $bluetoothState'); final authorizationStatus = await flutterBeacon.authorizationStatus; controller.updateAuthorizationStatus(authorizationStatus); print('AUTHORIZATION $authorizationStatus'); final locationServiceEnabled = await flutterBeacon.checkLocationServicesIfEnabled; controller.updateLocationService(locationServiceEnabled); print('LOCATION SERVICE $locationServiceEnabled'); if (controller.bluetoothEnabled && controller.authorizationStatusOk && controller.locationServiceEnabled) { print('STATE READY'); if (currentIndex == 0) { print('SCANNING'); controller.startScanning(); controller.startStream.listen((flag) { if (flag == true) { initScanBeacon(); } }); } else { print('BROADCASTING'); controller.startBroadcasting(); } } else { print('STATE NOT READY'); controller.pauseScanning(); } } initScanBeacon() async { await flutterBeacon.initializeScanning; if (!controller.authorizationStatusOk || !controller.locationServiceEnabled || !controller.bluetoothEnabled) { print( 'RETURNED, authorizationStatusOk=${controller.authorizationStatusOk}, ' 'locationServiceEnabled=${controller.locationServiceEnabled}, ' 'bluetoothEnabled=${controller.bluetoothEnabled}'); return; } final regions = [ Region( identifier: 'MyMuseumB' ), ]; if (_streamRanging != null) { if (_streamRanging!.isPaused) { _streamRanging?.resume(); return; } } _streamRanging = flutterBeacon.ranging(regions).listen((RangingResult result) { print(result); if (mounted) { setState(() { _regionBeacons[result.region] = result.beacons; _beacons.clear(); _regionBeacons.values.forEach((list) { _beacons.addAll(list); }); _beacons.sort(_compareParameters); }); } }); } pauseScanBeacon() async { _streamRanging?.pause(); if (_beacons.isNotEmpty) { setState(() { _beacons.clear(); }); } } int _compareParameters(Beacon a, Beacon b) { int compare = a.proximityUUID.compareTo(b.proximityUUID); if (compare == 0) { compare = a.major.compareTo(b.major); } if (compare == 0) { compare = a.minor.compareTo(b.minor); } return compare; } @override void didChangeAppLifecycleState(AppLifecycleState state) async { print('AppLifecycleState = $state'); if (state == AppLifecycleState.resumed) { if (_streamBluetooth != null) { if (_streamBluetooth!.isPaused) { _streamBluetooth?.resume(); } } await checkAllRequirements(); } else if (state == AppLifecycleState.paused) { _streamBluetooth?.pause(); } } @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; final appContext = Provider.of(context); visitAppContext = appContext.getContext(); return Scaffold( appBar: /*CustomAppBar( title: TranslationHelper.getFromLocale("visitTitle", appContext), isHomeButton: false, ),*/ AppBar( title: const Text('Flutter Beacon'), centerTitle: false, actions: [ Obx(() { if (!controller.locationServiceEnabled) return IconButton( tooltip: 'Not Determined', icon: Icon(Icons.portable_wifi_off), color: Colors.grey, onPressed: () {}, ); if (!controller.authorizationStatusOk) return IconButton( tooltip: 'Not Authorized', icon: Icon(Icons.portable_wifi_off), color: Colors.red, onPressed: () async { await flutterBeacon.requestAuthorization; }, ); return IconButton( tooltip: 'Authorized', icon: Icon(Icons.wifi_tethering), color: Colors.blue, onPressed: () async { await flutterBeacon.requestAuthorization; }, ); }), Obx(() { return IconButton( tooltip: controller.locationServiceEnabled ? 'Location Service ON' : 'Location Service OFF', icon: Icon( controller.locationServiceEnabled ? Icons.location_on : Icons.location_off, ), color: controller.locationServiceEnabled ? Colors.blue : Colors.red, onPressed: controller.locationServiceEnabled ? () {} : handleOpenLocationSettings, ); }), Obx(() { final state = controller.bluetoothState.value; if (state == BluetoothState.stateOn) { return IconButton( tooltip: 'Bluetooth ON', icon: Icon(Icons.bluetooth_connected), onPressed: () {}, color: Colors.lightBlueAccent, ); } if (state == BluetoothState.stateOff) { return IconButton( tooltip: 'Bluetooth OFF', icon: Icon(Icons.bluetooth), onPressed: handleOpenBluetooth, color: Colors.red, ); } return IconButton( icon: Icon(Icons.bluetooth_disabled), tooltip: 'Bluetooth State Unknown', onPressed: () {}, color: Colors.grey, ); }), ], ), body: SingleChildScrollView( child: SizedBox( width: size.width, height: size.height, child: FutureBuilder( future: getConfigurationsCall(appContext.clientAPI, appContext), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { configurations = List.from(snapshot.data).where((configuration) => configuration.isMobile!).toList(); return RefreshIndicator ( onRefresh: () { setState(() {}); return Future(() => null); }, color: kSecondColor, child: ConfigurationsList( alreadyDownloaded: alreadyDownloaded, configurations: configurations, requestRefresh: () { setState(() {}); // For refresh }, ), ); } else if (snapshot.connectionState == ConnectionState.none) { return Text(TranslationHelper.getFromLocale("noData", appContext)); } else { return Center( child: Container( height: size.height * 0.15, child: Loading() ) ); } } ), ) ), //floatingActionButton: ScannerBouton(appContext: appContext), //floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterFloat, bottomNavigationBar: BottomNavigationBar( currentIndex: currentIndex, onTap: (index) { setState(() { currentIndex = index; }); if (currentIndex == 0) { controller.startScanning(); } else { controller.pauseScanning(); controller.startBroadcasting(); } }, items: [ BottomNavigationBarItem( icon: Icon(Icons.list), label: 'Scan', ), BottomNavigationBarItem( icon: Icon(Icons.bluetooth_audio), label: 'Broadcast', ), ], ), ); } handleOpenLocationSettings() async { if (Platform.isAndroid) { await flutterBeacon.openLocationSettings; } else if (Platform.isIOS) { await showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Location Services Off'), content: Text( 'Please enable Location Services on Settings > Privacy > Location Services.', ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('OK'), ), ], ); }, ); } } handleOpenBluetooth() async { if (Platform.isAndroid) { try { await flutterBeacon.openBluetoothSettings; } on PlatformException catch (e) { print(e); } } else if (Platform.isIOS) { await showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Bluetooth is Off'), content: Text('Please enable Bluetooth on Settings > Bluetooth.'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('OK'), ), ], ); }, ); } } Future?> getConfigurationsCall(Client client, AppContext appContext) async { bool isOnline = await hasNetwork(); if(!isOnline) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(TranslationHelper.getFromLocale("noInternet", appContext)), backgroundColor: kBlue2), ); VisitAppContext visitAppContext = appContext.getContext(); List? configurations; configurations = List.from(await DatabaseHelper.instance.getData(DatabaseTableType.configurations)); alreadyDownloaded = configurations.map((c) => c.id).toList(); return configurations; } return await ApiService.getConfigurations(client, visitAppContext); } }