import 'dart:async'; import 'dart:math'; import 'package:fforte/l10n/app_localizations.dart'; import 'package:fforte/screens/helper/snack_bar_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:geolocator/geolocator.dart'; import 'package:latlong2/latlong.dart'; class Tracking extends StatefulWidget { final LatLng startPosition; final TextEditingController weg; const Tracking({super.key, required this.startPosition, required this.weg}); @override State createState() => _TrackingState(); } class _TrackingState extends State { List pathList = []; StreamSubscription? positionStream; bool positionStreamRunning = false; Random rand = Random(); @override void initState() { // TODO debugging (i guess) pathList.add( LatLng(widget.startPosition.latitude, widget.startPosition.longitude), ); if (widget.weg.text.isNotEmpty) { for (var element in widget.weg.text.split(";")) { List posSplit = element.split(","); try { posSplit[0] = posSplit[0].substring(0, 9); posSplit[1] = posSplit[1].substring(0, 9); } on RangeError { // ignore because the double is short enough then } pathList.add( LatLng(double.parse(posSplit.first), double.parse(posSplit[1])), ); } } super.initState(); } @override void dispose() { if (positionStream != null) positionStream!.cancel(); bool isFirst = true; if (pathList.isNotEmpty) { for (var pos in pathList) { if (!isFirst) { widget.weg.text += ";"; } else { isFirst = false; } widget.weg.text += "${pos.latitude},${pos.longitude}"; } } super.dispose(); } final LocationSettings streamLocationSettings = LocationSettings( accuracy: LocationAccuracy.high, distanceFilter: 10, ); void onTrackingStart() async { // // notification handling for tracking in background notification // PermissionStatus permissionStatus = // await NotificationPermissions.getNotificationPermissionStatus(); // // if (permissionStatus != PermissionStatus.granted) { // await NotificationPermissions.requestNotificationPermissions(); // } positionStream = Geolocator.getPositionStream( locationSettings: AndroidSettings( accuracy: LocationAccuracy.high, distanceFilter: 0, foregroundNotificationConfig: mounted ? ForegroundNotificationConfig( notificationTitle: AppLocalizations.of(context)!.trackingRunningInBackground, notificationText: "", ) : null, ), ).listen((Position? position) { if (position != null) { // pathList.add(LatLng(position.latitude, position.longitude)); setState(() { pathList.add(LatLng(rand.nextInt(5) + 40, position.longitude)); }); } else { if (mounted) { SnackBarHelper.showSnackBarMessage( context, AppLocalizations.of(context)!.couldntDeterminePosition, ); } } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context)!.tracking), // leading: IconButton(onPressed: () {}, icon: Icon(Icons.arrow_back_rounded)), actions: [ if (positionStreamRunning) IconButton( onPressed: () { setState(() { positionStreamRunning = false; positionStream!.cancel(); }); }, icon: Icon(Icons.stop_rounded), ), IconButton( onPressed: () { if (positionStreamRunning) { positionStreamRunning = false; positionStream?.pause(); } else { positionStreamRunning = true; onTrackingStart(); } setState(() {}); }, icon: positionStreamRunning ? Icon(Icons.pause) : Icon(Icons.play_arrow), ), ], ), body: FlutterMap( mapController: MapController(), options: MapOptions( interactionOptions: const InteractionOptions( flags: InteractiveFlag.pinchZoom | InteractiveFlag.drag | InteractiveFlag.pinchMove, ), initialCenter: widget.startPosition, initialZoom: 16.0, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'com.example.app', ), if (pathList.isNotEmpty) PolylineLayer( polylines: [ Polyline(strokeWidth: 2.0, points: pathList, color: Colors.red), ], ), CircleLayer( circles: [ CircleMarker( color: Colors.blue, point: pathList.isEmpty ? widget.startPosition : pathList.last, radius: 5, useRadiusInMeter: true, ), ], ), ], ), ); } }