added notification for tracking function and button to reset map position to current location

time
This commit is contained in:
Nico
2025-05-17 17:43:03 +02:00
parent 895bcf1d5c
commit 94aebeafd0
10 changed files with 169 additions and 19 deletions

View File

@@ -11,6 +11,7 @@ android {
ndkVersion = flutter.ndkVersion ndkVersion = flutter.ndkVersion
compileOptions { compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_11 sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11
} }
@@ -42,3 +43,7 @@ android {
flutter { flutter {
source = "../.." source = "../.."
} }
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
}

View File

@@ -1,8 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <!-- <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" /> -->
<application <application
android:label="fforte" android:label="fforte"
android:name="${applicationName}" android:name="${applicationName}"
@@ -33,7 +33,14 @@
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
<!-- <service -->
<!-- android:name="com.dexterous.flutterlocalnotifications.ForegroundService" -->
<!-- android:exported="false" -->
<!-- android:stopWithTask="false" -->
<!-- android:foregroundServiceType="<location>"> -->
</application> </application>
<!-- Required to query activities that can process text, see: <!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and https://developer.android.com/training/package-visibility and

View File

@@ -4,6 +4,7 @@ import 'package:fforte/screens/addCam/add_cam_main.dart';
import 'package:fforte/screens/intro_screen.dart'; import 'package:fforte/screens/intro_screen.dart';
import 'package:fforte/screens/settings.dart'; import 'package:fforte/screens/settings.dart';
import 'package:fforte/screens/viewEntries/view_cams.dart'; import 'package:fforte/screens/viewEntries/view_cams.dart';
import 'package:fforte/services/notification_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
@@ -15,6 +16,12 @@ import 'l10n/l10n.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
// notifications
NotificationService().initNotification();
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true; bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true;
await prefs.setString('kTage1', "28"); await prefs.setString('kTage1', "28");

View File

@@ -3,6 +3,7 @@ import 'dart:math';
import 'package:fforte/l10n/app_localizations.dart'; import 'package:fforte/l10n/app_localizations.dart';
import 'package:fforte/screens/helper/snack_bar_helper.dart'; import 'package:fforte/screens/helper/snack_bar_helper.dart';
import 'package:fforte/services/notification_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
@@ -21,6 +22,7 @@ class _TrackingState extends State<Tracking> {
List<LatLng> pathList = []; List<LatLng> pathList = [];
StreamSubscription<Position>? positionStream; StreamSubscription<Position>? positionStream;
bool positionStreamRunning = false; bool positionStreamRunning = false;
MapController mapController = MapController();
Random rand = Random(); Random rand = Random();
@@ -73,26 +75,26 @@ class _TrackingState extends State<Tracking> {
); );
void onTrackingStart() async { void onTrackingStart() async {
// // notification handling for tracking in background notification // notification handling for tracking in background notification
// PermissionStatus permissionStatus = await NotificationService().initNotification();
// await NotificationPermissions.getNotificationPermissionStatus();
// if (mounted)
// if (permissionStatus != PermissionStatus.granted) { NotificationService().showNotification(
// await NotificationPermissions.requestNotificationPermissions(); title: AppLocalizations.of(context)!.trackingRunningInBackground,
// } );
positionStream = Geolocator.getPositionStream( positionStream = Geolocator.getPositionStream(
locationSettings: AndroidSettings( locationSettings: AndroidSettings(
accuracy: LocationAccuracy.high, accuracy: LocationAccuracy.high,
distanceFilter: 0, distanceFilter: 0,
foregroundNotificationConfig: // foregroundNotificationConfig:
mounted // mounted
? ForegroundNotificationConfig( // ? ForegroundNotificationConfig(
notificationTitle: // notificationTitle:
AppLocalizations.of(context)!.trackingRunningInBackground, // AppLocalizations.of(context)!.trackingRunningInBackground,
notificationText: "", // notificationText: "",
) // )
: null, // : null,
), ),
).listen((Position? position) { ).listen((Position? position) {
if (position != null) { if (position != null) {
@@ -124,6 +126,7 @@ class _TrackingState extends State<Tracking> {
setState(() { setState(() {
positionStreamRunning = false; positionStreamRunning = false;
positionStream!.cancel(); positionStream!.cancel();
NotificationService().deleteNotification();
}); });
}, },
icon: Icon(Icons.stop_rounded), icon: Icon(Icons.stop_rounded),
@@ -146,8 +149,14 @@ class _TrackingState extends State<Tracking> {
), ),
], ],
), ),
floatingActionButton: FloatingActionButton(
onPressed: () {
mapController.move(pathList.last, 16);
},
child: Icon(Icons.my_location),
),
body: FlutterMap( body: FlutterMap(
mapController: MapController(), mapController: mapController,
options: MapOptions( options: MapOptions(
interactionOptions: const InteractionOptions( interactionOptions: const InteractionOptions(
flags: flags:

View File

@@ -0,0 +1,45 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class NotificationService {
final notifiactionPlugin = FlutterLocalNotificationsPlugin();
bool _isInitialized = false;
bool get isInitialized => _isInitialized;
Future<void> initNotification() async {
if (_isInitialized) return;
await notifiactionPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()!.requestNotificationsPermission();
const initSettingsAndroid = AndroidInitializationSettings(
'@mipmap/ic_launcher',
);
const initSettings = InitializationSettings(android: initSettingsAndroid);
await notifiactionPlugin.initialize(initSettings);
_isInitialized = true;
}
NotificationDetails notificationDetails() {
return const NotificationDetails(
android: AndroidNotificationDetails(
"tracking0",
"tracking ongoing",
importance: Importance.low,
priority: Priority.low,
ongoing: true,
),
);
}
Future<void> showNotification({int id = 0, String? title}) async {
return notifiactionPlugin.show(id, title, "", notificationDetails());
}
Future<void> deleteNotification({id = 0}) async {
await notifiactionPlugin.cancel(id);
}
}

View File

@@ -6,6 +6,7 @@ import FlutterMacOS
import Foundation import Foundation
import file_picker import file_picker
import flutter_local_notifications
import geolocator_apple import geolocator_apple
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
@@ -13,6 +14,7 @@ import sqflite_darwin
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

View File

@@ -9,6 +9,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.11" version: "2.0.11"
args:
dependency: transitive
description:
name: args
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
url: "https://pub.dev"
source: hosted
version: "2.7.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@@ -73,6 +81,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
dbus:
dependency: transitive
description:
name: dbus
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
url: "https://pub.dev"
source: hosted
version: "0.7.11"
dio: dio:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -174,6 +190,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.0" version: "5.0.0"
flutter_local_notifications:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: ebc86e2ff6a9ca5bc1943e675fef02b5ddaa1a99b4ef980cac576fcfc65959aa
url: "https://pub.dev"
source: hosted
version: "19.2.0"
flutter_local_notifications_linux:
dependency: transitive
description:
name: flutter_local_notifications_linux
sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5
url: "https://pub.dev"
source: hosted
version: "6.0.0"
flutter_local_notifications_platform_interface:
dependency: transitive
description:
name: flutter_local_notifications_platform_interface
sha256: "2569b973fc9d1f63a37410a9f7c1c552081226c597190cb359ef5d5762d1631c"
url: "https://pub.dev"
source: hosted
version: "9.0.0"
flutter_local_notifications_windows:
dependency: transitive
description:
name: flutter_local_notifications_windows
sha256: f8fc0652a601f83419d623c85723a3e82ad81f92b33eaa9bcc21ea1b94773e6e
url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@@ -477,6 +525,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.3.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@@ -674,6 +730,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.4" version: "0.7.4"
timezone:
dependency: transitive
description:
name: timezone
sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1
url: "https://pub.dev"
source: hosted
version: "0.10.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -746,6 +810,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
sdks: sdks:
dart: ">=3.7.0 <4.0.0" dart: ">=3.7.0 <4.0.0"
flutter: ">=3.29.0" flutter: ">=3.29.0"

View File

@@ -33,6 +33,7 @@ dependencies:
dio: ^5.4.1 dio: ^5.4.1
geocoding: ^3.0.0 geocoding: ^3.0.0
flutter_slidable: ^4.0.0 flutter_slidable: ^4.0.0
flutter_local_notifications: ^19.2.0
dev_dependencies: dev_dependencies:
flutter_lints: ^5.0.0 flutter_lints: ^5.0.0

View File

@@ -83,3 +83,4 @@
12.mai 5h 30min 12.mai 5h 30min
13.mai 1h 50min 13.mai 1h 50min
15.mai 2h 30min 15.mai 2h 30min
17.mai 1h 30min

View File

@@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
flutter_local_notifications_windows
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)