Update AndroidManifest to include foreground service permissions and implement tracking service in excursion screens. Refactor tracking logic to utilize TrackingService for better state management and streamline position updates.
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
import 'package:fforte/screens/addCam/services/geolocator_service.dart';
|
||||
import 'package:fforte/screens/helper/add_entries_dialog_helper.dart';
|
||||
import 'package:fforte/screens/helper/snack_bar_helper.dart';
|
||||
import 'package:fforte/services/notification_service.dart';
|
||||
import 'package:fforte/services/tracking_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_map_location_marker/flutter_map_location_marker.dart';
|
||||
@@ -22,20 +21,14 @@ class Tracking extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _TrackingState extends State<Tracking> {
|
||||
List<LatLng> pathList = [];
|
||||
StreamSubscription<Position>? positionStream;
|
||||
final TrackingService _trackingService = TrackingService();
|
||||
LocationMarkerPosition? locationMarkerPosition;
|
||||
bool positionStreamRunning = false;
|
||||
MapController mapController = MapController();
|
||||
|
||||
Random rand = Random();
|
||||
StreamSubscription? _positionSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// debugging (i guess)
|
||||
// pathList.add(
|
||||
// LatLng(widget.startPosition.latitude, widget.startPosition.longitude),
|
||||
// );
|
||||
super.initState();
|
||||
|
||||
if (widget.weg.text.isNotEmpty) {
|
||||
for (var element in widget.weg.text.split(";")) {
|
||||
@@ -47,7 +40,7 @@ class _TrackingState extends State<Tracking> {
|
||||
// ignore because the double is short enough then
|
||||
}
|
||||
|
||||
pathList.add(
|
||||
_trackingService.pathList.add(
|
||||
LatLng(double.parse(posSplit.first), double.parse(posSplit[1])),
|
||||
);
|
||||
}
|
||||
@@ -59,7 +52,15 @@ class _TrackingState extends State<Tracking> {
|
||||
accuracy: widget.startPosition.accuracy,
|
||||
);
|
||||
|
||||
super.initState();
|
||||
_positionSubscription = _trackingService.positionStream$.listen((position) {
|
||||
setState(() {
|
||||
locationMarkerPosition = LocationMarkerPosition(
|
||||
latitude: position.latitude,
|
||||
longitude: position.longitude,
|
||||
accuracy: position.accuracy,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
GeolocatorService.alwaysPositionEnabled().then((value) {
|
||||
if (!value && mounted) {
|
||||
@@ -71,101 +72,30 @@ class _TrackingState extends State<Tracking> {
|
||||
|
||||
@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}";
|
||||
}
|
||||
}
|
||||
NotificationService().deleteNotification();
|
||||
|
||||
_positionSubscription?.cancel();
|
||||
widget.weg.text = _trackingService.getPathAsString();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
final LocationSettings streamLocationSettings = LocationSettings(
|
||||
accuracy: LocationAccuracy.high,
|
||||
distanceFilter: 10,
|
||||
);
|
||||
|
||||
void onTrackingStart() async {
|
||||
// notification handling for tracking in background notification
|
||||
await NotificationService().initNotification();
|
||||
|
||||
if (mounted) {
|
||||
NotificationService().showNotification(
|
||||
title: AppLocalizations.of(context)!.trackingRunningInBackground,
|
||||
);
|
||||
}
|
||||
|
||||
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) {
|
||||
setState(() {
|
||||
pathList.add(LatLng(position.latitude, position.longitude));
|
||||
// Random value for debugging
|
||||
// pathList.add(LatLng(rand.nextInt(5) + 40, position.longitude));
|
||||
|
||||
locationMarkerPosition = LocationMarkerPosition(
|
||||
latitude: position.latitude,
|
||||
longitude: position.longitude,
|
||||
accuracy: position.accuracy,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
if (mounted) {
|
||||
SnackBarHelper.showSnackBarMessage(
|
||||
context,
|
||||
AppLocalizations.of(context)!.couldntDeterminePosition,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
positionStream!.onError((e) {
|
||||
NotificationService().deleteNotification();
|
||||
NotificationService().showNotification(title: "ERROR: $e");
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.tracking),
|
||||
leading: IconButton(onPressed: () {
|
||||
Navigator.pop(context);
|
||||
}, icon: Icon(Icons.arrow_back_rounded)),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: Icon(Icons.arrow_back_rounded)
|
||||
),
|
||||
actions: [
|
||||
if (!positionStreamRunning)
|
||||
if (!_trackingService.isTracking)
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
bool delete =
|
||||
await AddEntriesDialogHelper.deleteCompleteRouteDialog(
|
||||
context,
|
||||
);
|
||||
|
||||
bool delete = await AddEntriesDialogHelper.deleteCompleteRouteDialog(context);
|
||||
if (delete) {
|
||||
setState(() {
|
||||
pathList = [];
|
||||
_trackingService.clearPath();
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -174,32 +104,32 @@ class _TrackingState extends State<Tracking> {
|
||||
color: Theme.of(context).colorScheme.errorContainer,
|
||||
),
|
||||
),
|
||||
if (positionStreamRunning)
|
||||
if (_trackingService.isTracking)
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
positionStreamRunning = false;
|
||||
positionStream!.cancel();
|
||||
NotificationService().deleteNotification();
|
||||
_trackingService.stopTracking();
|
||||
});
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.trackingStop),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (positionStreamRunning) {
|
||||
positionStreamRunning = false;
|
||||
positionStream?.pause();
|
||||
} else {
|
||||
positionStreamRunning = true;
|
||||
onTrackingStart();
|
||||
}
|
||||
setState(() {});
|
||||
setState(() {
|
||||
if (_trackingService.isTracking) {
|
||||
_trackingService.pauseTracking();
|
||||
} else {
|
||||
if (_trackingService.positionStream == null) {
|
||||
_trackingService.startTracking(context);
|
||||
} else {
|
||||
_trackingService.resumeTracking();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
child:
|
||||
positionStreamRunning
|
||||
? Text(AppLocalizations.of(context)!.trackingPause)
|
||||
: Text(AppLocalizations.of(context)!.trackingStart)
|
||||
child: _trackingService.isTracking
|
||||
? Text(AppLocalizations.of(context)!.trackingPause)
|
||||
: Text(AppLocalizations.of(context)!.trackingStart),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -219,8 +149,7 @@ class _TrackingState extends State<Tracking> {
|
||||
mapController: mapController,
|
||||
options: MapOptions(
|
||||
interactionOptions: const InteractionOptions(
|
||||
flags:
|
||||
InteractiveFlag.pinchZoom |
|
||||
flags: InteractiveFlag.pinchZoom |
|
||||
InteractiveFlag.drag |
|
||||
InteractiveFlag.pinchMove,
|
||||
),
|
||||
@@ -235,22 +164,16 @@ class _TrackingState extends State<Tracking> {
|
||||
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
userAgentPackageName: 'de.lupus.apps',
|
||||
),
|
||||
if (pathList.isNotEmpty)
|
||||
if (_trackingService.pathList.isNotEmpty)
|
||||
PolylineLayer(
|
||||
polylines: [
|
||||
Polyline(strokeWidth: 2.0, points: pathList, color: Colors.red),
|
||||
Polyline(
|
||||
strokeWidth: 2.0,
|
||||
points: _trackingService.pathList,
|
||||
color: Colors.red
|
||||
),
|
||||
],
|
||||
),
|
||||
// CircleLayer(
|
||||
// circles: [
|
||||
// CircleMarker(
|
||||
// color: Colors.blue,
|
||||
// point: pathList.isEmpty ? widget.startPosition : pathList.last,
|
||||
// radius: 5,
|
||||
// useRadiusInMeter: true,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
CurrentLocationLayer(),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user