From ae11a85872c9d1661f30307f949411ae538b2179 Mon Sep 17 00:00:00 2001 From: Dustin Date: Sun, 2 Aug 2026 16:06:04 +0200 Subject: [PATCH] =?UTF-8?q?v2.41=20=E2=80=94=20Issue=20#3:=20Musik-Downloa?= =?UTF-8?q?d=20im=20Hintergrund=20(flutter=5Fbackground=5Fservice)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - flutter_background_service ^5.0.0 hinzugefügt - AndroidManifest: FOREGROUND_SERVICE_DATA_SYNC Permission - main.dart: Background Service mit configure() initialisiert - _onServiceStart(): Service-Callback für Foreground-Garantie - DownloadService._startBackgroundService(): Foreground Service vor Download - DownloadService._stopBackgroundService(): Stopp nach Batch/Single - Integration in _resetStatus, downloadBatch, downloadVonUrl --- android/app/src/main/AndroidManifest.xml | 1 + lib/main.dart | 24 +++++++++++++++ lib/services/download_service.dart | 37 +++++++++++++++++++++++- pubspec.lock | 32 ++++++++++++++++++++ pubspec.yaml | 1 + 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 473b9f8..7d8fb4e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + diff --git a/lib/main.dart b/lib/main.dart index 9ead63a..8074a05 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:audio_service/audio_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:flutter_background_service/flutter_background_service.dart'; import 'database/db_helper.dart'; import 'services/favoriten_service.dart'; import 'services/auth_service.dart'; @@ -47,6 +48,16 @@ void main() async { AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(downloadChannel); + // ── Background Service initialisieren (Issue #3) ── + await FlutterBackgroundService().configure( + iosConfiguration: IosConfiguration(), + androidConfiguration: AndroidConfiguration( + onStart: _onServiceStart, + autoStart: false, + isForegroundMode: true, + ), + ); + try { await DbHelper().db; await FavoritenService().init(); @@ -148,6 +159,19 @@ Future _starteAutoSyncFallsNoetig() async { } } +/// Background Service Callback – hält App im Vordergrund beim Download (Issue #3) +@pragma('vm:entry-point') +Future _onServiceStart(ServiceInstance service) async { + WidgetsFlutterBinding.ensureInitialized(); + // Service läuft als Foreground-Service und hält den Prozess am Leben. + // Der eigentliche Download läuft im Haupt-Isolate – der Service dient nur + // als WakeLock / Foreground-Garantie. + service.on('stopService').listen((_) { + service.stopSelf(); + }); + return true; +} + class MeloApp extends StatelessWidget { const MeloApp({super.key}); diff --git a/lib/services/download_service.dart b/lib/services/download_service.dart index 0b089c5..d6d6d9f 100644 --- a/lib/services/download_service.dart +++ b/lib/services/download_service.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:flutter_background_service/flutter_background_service.dart'; import '../models/song.dart'; import '../database/db_helper.dart'; import '../utils/audio_validator.dart'; @@ -66,13 +67,46 @@ class DownloadService extends ChangeNotifier { _aktuellerTitel = null; _fehler = null; _abbruchCompleter = Completer(); + _startBackgroundService(); notifyListeners(); } + /// Issue #3: Foreground Service starten – hält App im Hintergrund aktiv + void _startBackgroundService() { + try { + final svc = FlutterBackgroundService(); + svc.isRunning().then((running) { + if (!running) { + svc.startService(); + } + }); + debugPrint('🔵 Background Service gestartet'); + } catch (e) { + debugPrint('Background Service Start fehlgeschlagen: $e'); + } + } + + /// Issue #3: Foreground Service stoppen + void _stopBackgroundService() { + try { + final svc = FlutterBackgroundService(); + svc.isRunning().then((running) { + if (running) { + svc.invoke('stopService'); + } + }); + debugPrint('🔴 Background Service gestoppt'); + } catch (e) { + debugPrint('Background Service Stop fehlgeschlagen: $e'); + } + } + /// Song von YouTube herunterladen Future downloadVonUrl(String url) async { _resetStatus(); - return _downloadEinzeln(url); + final result = await _downloadEinzeln(url); + if (!_ladt) _stopBackgroundService(); + return result; } /// Mehrere URLs/Playlists nacheinander mit Cooldown @@ -147,6 +181,7 @@ class DownloadService extends ChangeNotifier { } notifyListeners(); _completeNotification(erfolgreich, urls.length, abgebrochen: sollAbbrechen); + _stopBackgroundService(); MeloLogger().zustand('download_batch_ende', { 'erfolgreich': erfolgreich, 'gesamt': urls.length, diff --git a/pubspec.lock b/pubspec.lock index 3225fda..f0ef27b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -150,6 +150,38 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_background_service: + dependency: "direct main" + description: + name: flutter_background_service + sha256: "70a1c185b1fa1a44f8f14ecd6c86f6e50366e3562f00b2fa5a54df39b3324d3d" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + flutter_background_service_android: + dependency: transitive + description: + name: flutter_background_service_android + sha256: ca0793d4cd19f1e194a130918401a3d0b1076c81236f7273458ae96987944a87 + url: "https://pub.dev" + source: hosted + version: "6.3.1" + flutter_background_service_ios: + dependency: transitive + description: + name: flutter_background_service_ios + sha256: "6037ffd45c4d019dab0975c7feb1d31012dd697e25edc05505a4a9b0c7dc9fba" + url: "https://pub.dev" + source: hosted + version: "5.0.3" + flutter_background_service_platform_interface: + dependency: transitive + description: + name: flutter_background_service_platform_interface + sha256: ca74aa95789a8304f4d3f57f07ba404faa86bed6e415f83e8edea6ad8b904a41 + url: "https://pub.dev" + source: hosted + version: "5.1.2" flutter_cache_manager: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b78e0c4..9295984 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: crypto: ^3.0.6 flutter_secure_storage: ^10.3.1 flutter_local_notifications: ^22.2.0 + flutter_background_service: ^5.1.0 dev_dependencies: flutter_test: