This commit is contained in:
Guillaume David 2024-07-08 11:31:02 +02:00
parent e7331e7d93
commit 92957a1903
10 changed files with 424 additions and 23 deletions

View File

@ -14,6 +14,9 @@ PODS:
- permission_handler_apple (9.3.0):
- Flutter
- Polyline (5.1.0)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- Tangram-es (0.17.1)
- url_launcher_ios (0.0.1):
- Flutter
@ -25,6 +28,7 @@ DEPENDENCIES:
- flutter_osm_plugin (from `.symlinks/plugins/flutter_osm_plugin/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
@ -45,6 +49,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/geolocator_apple/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
@ -56,6 +62,7 @@ SPEC CHECKSUMS:
geolocator_apple: 6cbaf322953988e009e5ecb481f07efece75c450
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
Polyline: 2a1f29f87f8d9b7de868940f4f76deb8c678a5b1
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
Tangram-es: 628b634f7fc09d2217469b9914de00d9de49ff9d
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
Yams: e10dae147f517ed57ecae37c5e8681bdf8fcab65

View File

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
class BLEProvider with ChangeNotifier {
List<ScanResult> _scanResults = [];
List<ScanResult> get scanResults => _scanResults;
BLEProvider() {
startScan();
}
void startScan() {
FlutterBluePlus.startScan();
FlutterBluePlus.onScanResults.listen(
(results) {
_scanResults = results;
notifyListeners();
},
onError: (e) => print(e),
);
}
void stopScan() {
FlutterBluePlus.stopScan();
}
}

View File

@ -0,0 +1,46 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class DevicesSaved {
String deviceName = '';
String deviceAddress = '';
String remoteId = '';
bool connected = false;
DevicesSaved(
{required this.deviceName,
required this.deviceAddress,
required this.remoteId});
DevicesSaved.fromJson(Map<String, dynamic> json) {
deviceName = json['deviceName'];
deviceAddress = json['deviceAddress'];
remoteId = json['remoteId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['deviceName'] = deviceName;
data['deviceAddress'] = deviceAddress;
data['remoteId'] = remoteId;
return data;
}
}
Future<List<DevicesSaved>> restoreLocal() async {
final prefs = await SharedPreferences.getInstance();
final String? encodedData = prefs.getString('deviceSaved');
if (encodedData != null) {
final List<dynamic> decodedData = jsonDecode(encodedData);
return decodedData.map((json) => DevicesSaved.fromJson(json)).toList();
}
return [];
}
Future<void> saveLocal(List<DevicesSaved> deviceSaved) async {
final prefs = await SharedPreferences.getInstance();
final String encodedData =
jsonEncode(deviceSaved.map((obj) => obj.toJson()).toList());
await prefs.setString('deviceSaved', encodedData);
}

View File

@ -0,0 +1,19 @@
class GeoPosition {
final double latitude;
final double longitude;
final double altitude;
GeoPosition({
required this.latitude,
required this.longitude,
required this.altitude,
});
factory GeoPosition.fromJson(Map<String, dynamic> json) {
return GeoPosition(
latitude: json['latitude'],
longitude: json['longitude'],
altitude: json['altitude'],
);
}
}

View File

@ -5,12 +5,10 @@ import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
class DeviceAdvertizinScan extends StatefulWidget {
const DeviceAdvertizinScan(
{super.key,
required this.title,
required this.deviceName,
required this.deviceAddress,
required this.remoteId});
final String title;
final String deviceName;
final String deviceAddress;
final String remoteId;
@ -45,13 +43,14 @@ class _DeviceAdvertizinScanState extends State<DeviceAdvertizinScan> {
Widget build(BuildContext context) {
FlutterBluePlus.onScanResults.listen((results) {
setState(() {
if (results.length > 0) value = results[0].toString();
if (results.length > 0) value = results[0].advertisementData.toString();
});
});
return Scaffold(
appBar: AppBar(
title: Text(widget.title, style: const TextStyle(color: Colors.white)),
title: Text("Valeur de la trame publicitaire",
style: const TextStyle(color: Colors.white)),
backgroundColor: Colors.blue,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
@ -70,20 +69,34 @@ class _DeviceAdvertizinScanState extends State<DeviceAdvertizinScan> {
children: [
Container(
alignment: Alignment.topCenter,
child: Text('Advertizin data value for ${widget.deviceName}' +
' with remoteId ${widget.remoteId}')),
child: Column(
children: [
Text(widget.deviceName),
Text(widget.deviceAddress),
Text(widget.remoteId),
],
)),
Container(
margin: const EdgeInsets.all(10),
child:
//Text centré
Center(
child: Text(
"La trame publicitaire est en cours de réception et actualisée en temps réel.",
style: const TextStyle(
color: Colors.green,
),
textAlign: TextAlign.center),
)),
Container(
margin: const EdgeInsets.all(10),
child: CircularProgressIndicator()),
Container(
margin: const EdgeInsets.all(10),
alignment: Alignment.center,
child: Text(value,
style: const TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold))),
Container(child: CircularProgressIndicator()),
Spacer(),
Container(
child: Text(
'La trame publicitaire est en cours de réception et actualisée en temps réel.')),
color: Colors.black, fontWeight: FontWeight.bold))),
],
),
);

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:gps_map_flowpoint/class/devicesSaved.dart';
import 'package:gps_map_flowpoint/deviceAdvertizinScan.dart';
import 'package:gps_map_flowpoint/deviceFlowMap.dart';
@ -13,15 +14,22 @@ class DeviceSelection extends StatefulWidget {
}
class _DeviceSelectionState extends State<DeviceSelection> {
// List to hold the scanned devices
List<ScanResult> scanResults = [];
TextEditingController tecSearch = TextEditingController();
bool isScanning = false;
List<DevicesSaved> devicesSaved = [];
// Initialize Bluetooth scanning and subscription in initState
@override
void initState() {
super.initState();
restoreLocal().then((value) {
print(value.length);
setState(() {
devicesSaved = value;
});
});
FlutterBluePlus.isSupported.then((isSupported) {
if (!isSupported) {
showDialog(
@ -64,14 +72,114 @@ class _DeviceSelectionState extends State<DeviceSelection> {
.contains(tecSearch.text.toLowerCase()))
.toList();
//Saved devices list is connected ?
devicesSaved.forEach((element) {
element.connected = scanResults
.where((result) => result.device.remoteId.str == element.remoteId)
.length >
0;
});
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("Selection de l'appareil BLE",
style: TextStyle(color: Colors.white)),
title: Text("Eagle Tr@cker", style: TextStyle(color: Colors.white)),
),
body: Column(
children: [
//List of devices saved in local storage by card
devicesSaved.length > 0
? Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Appareils sauvegardés',
style: TextStyle(
fontSize: 18.0, fontWeight: FontWeight.bold)),
),
ListView.builder(
shrinkWrap: true,
itemCount: devicesSaved.length,
itemBuilder: (context, index) {
DevicesSaved device = devicesSaved[index];
return Card(
child: ListTile(
title: Row(children: [
Icon(Icons.circle,
color: devicesSaved[index].connected
? Colors.green
: Colors.orange,
size: 10.0),
Text(device.deviceName)
]),
subtitle: Text(device.deviceAddress),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () async {
devicesSaved.removeAt(index);
await saveLocal(devicesSaved);
setState(() {
devicesSaved = devicesSaved;
});
},
child: Icon(Icons.delete)),
GestureDetector(
onTap: () {
//Stop scanning when a device is selected
FlutterBluePlus.stopScan();
setState(() {
isScanning = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DeviceAdvertizinScan(
deviceName: device.deviceName,
deviceAddress:
device.deviceAddress,
remoteId: device.remoteId,
)),
);
},
child: Icon(Icons.info_outline),
),
GestureDetector(
onTap: () {
//Stop scanning when a device is selected
FlutterBluePlus.stopScan();
setState(() {
isScanning = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DeviceFlowMap(
title: 'GPS Map Flowpoint',
deviceName: device.deviceName,
deviceAddress: device.deviceAddress,
),
),
);
},
child: Icon(Icons.map_outlined),
),
],
),
));
},
),
],
)
: Container(),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Recherche d\' appareils BLE',
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextFormField(
@ -95,6 +203,36 @@ class _DeviceSelectionState extends State<DeviceSelection> {
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () async {
if (devicesSaved
.where((element) =>
element.deviceAddress ==
result.device.remoteId.str)
.length >
0) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text('Cet appareil est déjà sauvegardé'),
),
);
return;
}
devicesSaved.add(DevicesSaved(
deviceName: result.device.platformName,
deviceAddress: result.device.remoteId.str,
remoteId: result.device.remoteId.str,
));
await saveLocal(devicesSaved);
setState(() {
devicesSaved = devicesSaved;
});
;
},
child: Icon(Icons.add),
),
GestureDetector(
onTap: () {
//Stop scanning when a device is selected
@ -106,7 +244,6 @@ class _DeviceSelectionState extends State<DeviceSelection> {
context,
MaterialPageRoute(
builder: (context) => DeviceAdvertizinScan(
title: 'Advertising Frame View',
deviceName: result.device.platformName,
deviceAddress: result.device.remoteId.str,
remoteId: result.device.remoteId.str,
@ -139,7 +276,10 @@ class _DeviceSelectionState extends State<DeviceSelection> {
),
],
),
title: Text(result.device.platformName),
title: Row(children: [
Icon(Icons.circle, color: Colors.green, size: 10.0),
Text(result.device.platformName)
]),
subtitle: Text(result.device.remoteId.str),
);
},

View File

@ -1,8 +1,17 @@
import 'package:flutter/material.dart';
import 'package:gps_map_flowpoint/class/BLEProvider.dart';
import 'package:gps_map_flowpoint/deviceSelection.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => BLEProvider()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@ -13,7 +22,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'GPD Map Flowpoint',
title: 'GPS Map Flowpoint',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,

View File

@ -7,10 +7,12 @@ import Foundation
import flutter_blue_plus
import geolocator_apple
import shared_preferences_foundation
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterBluePlusPlugin.register(with: registry.registrar(forPlugin: "FlutterBluePlusPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}

View File

@ -73,6 +73,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
fixnum:
dependency: transitive
description:
@ -272,6 +288,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.12.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
@ -280,6 +304,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.0"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
permission_handler:
dependency: transitive
description:
@ -328,6 +376,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.1"
platform:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
@ -336,6 +392,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
provider:
dependency: "direct main"
description:
name: provider
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
url: "https://pub.dev"
source: hosted
version: "6.1.2"
routing_client_dart:
dependency: transitive
description:
@ -344,6 +408,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.5"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
url: "https://pub.dev"
source: hosted
version: "2.2.3"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
sky_engine:
dependency: transitive
description: flutter
@ -517,6 +637,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.1"
win32:
dependency: transitive
description:
name: win32
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
url: "https://pub.dev"
source: hosted
version: "5.5.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.4"
sdks:
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.19.0"
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"

View File

@ -38,6 +38,8 @@ dependencies:
flutter_blue_plus: ^1.32.7
flutter_osm_plugin: ^0.70.4
geolocator: ^12.0.0
shared_preferences: ^2.2.3
provider: ^6.1.2
dev_dependencies:
flutter_test: