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: