diff --git a/CHANGELOG.md b/CHANGELOG.md index 00c7c01..427acd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,7 +76,8 @@ Die Android-App zählt eigenständig weiter (mehrere APKs pro Release). Welche d ## [2.6] — 2026-09-12 -**Android:** 1.9 (versionCode 12) — Besitzer geteilter Playlists. +**Android:** 1.9 (versionCode 12) → 1.10 (versionCode 13). 1.9 brachte den Besitzer geteilter +Playlists und die Offline-Korrekturen, 1.10 den Zählfehler im Downloader. ### Fixed - **Zurück und Vorwärts gingen im installierten Fenster am PC gar nicht (Web)** — im Browser-Tab @@ -108,6 +109,17 @@ Die Android-App zählt eigenständig weiter (mehrere APKs pro Release). Welche d toter Zurück-Druck gleich zu Beginn. Vorwärts funktioniert unverändert (mitgetestet). ### Fixed +- **Halb geladene Gruppen meldeten sich als „Vollständig" (Android)** — der Worker startete seinen + Zähler bei `group.downloadedTracks` und zählte dieselben fertigen Titel beim Überspringen **gleich + noch einmal**: nach einem Fortsetzen mit 412 fertigen Titeln meldete die Gruppe 824. Überschreitet + der Wert `totalTracks`, gilt sie als vollständig — der Fortschrittsbalken verschwindet und der + Herunterladen-Knopf wird unantastbar, obwohl Titel fehlen. Der Fehler steckte schon länger drin, + fiel aber kaum auf, solange Fortsetzen nur von Hand passierte; mit der automatischen Wiederholung + hätte er bei jedem Lauf zugeschlagen. Der Zähler beginnt jetzt bei 0 und zählt jeden fertigen Titel + genau einmal. + - Nebenbei: beim Überspringen wurde der Fortschritt in die Datenbank geschrieben, obwohl er sich + nicht ändert — 1900 überflüssige Schreibzugriffe je Lauf. Geschrieben wird jetzt nur nach einem + tatsächlichen Versuch und einmal beim Abbruch. - **Große Offline-Downloads liefen nie zu Ende (Android)** — WorkManager räumt einem Hintergrund-Worker rund **10 Minuten** ein und stoppt ihn dann. Ein Vordergrunddienst ist keine Option, `FOREGROUND_SERVICE_TYPE_DATA_SYNC` bringt die App unter Android 15 zum Absturz. Der diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index eb0cbef..1185393 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -14,8 +14,8 @@ android { applicationId = "com.novasonic.app" minSdk = 26 targetSdk = 35 - versionCode = 12 - versionName = "1.9" + versionCode = 13 + versionName = "1.10" // Host der eigenen NovaSonic-Web-App — Ziel der geteilten Links. Einmal in // gradle.properties setzen (novasonicHost=music.example.com); ohne Angabe bleibt der // Platzhalter stehen und der App-Link greift schlicht nicht. diff --git a/android/app/src/main/kotlin/com/novasonic/app/offline/DownloadWorker.kt b/android/app/src/main/kotlin/com/novasonic/app/offline/DownloadWorker.kt index 687f2a7..fabe8ff 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/offline/DownloadWorker.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/offline/DownloadWorker.kt @@ -31,7 +31,8 @@ class DownloadWorker( override suspend fun doWork(): Result { val groupId = inputData.getString(EXTRA_GROUP_ID) ?: return Result.failure() - val group = offlineRepo.getGroup(groupId) ?: return Result.failure() + // Nur die Existenz zaehlt — der Fortschritt wird unten neu gezaehlt, nicht fortgeschrieben. + offlineRepo.getGroup(groupId) ?: return Result.failure() val songIds = offlineRepo.songIdsForGroup(groupId) if (songIds.isEmpty()) return Result.success() @@ -39,7 +40,12 @@ class DownloadWorker( if (!creds.isValid) return Result.failure() val subsonicClient = SubsonicClient(creds.serverUrl, creds.username, creds.password) - var done = group.downloadedTracks + // Bei 0 anfangen und JEDEN fertigen Titel zaehlen — auch die aus frueheren Laeufen, die + // gleich uebersprungen werden. Frueher stand hier group.downloadedTracks, und die Schleife + // zaehlte dieselben Titel gleich nochmal: nach einem Fortsetzen mit 412 fertigen Titeln + // meldete die Gruppe 824. Ueberschreitet der Wert totalTracks, gilt die Gruppe als + // "Vollstaendig" und der Herunterladen-Knopf wird unantastbar, obwohl Titel fehlen. + var done = 0 val dao = OfflineDatabase.get(applicationContext).offlineDao() return try { @@ -51,8 +57,9 @@ class DownloadWorker( // wir sauber aus und fordern den naechsten Lauf an; Fertiges wird uebersprungen. if (isStopped) { gestoppt = true; break } if (offlineRepo.getTrackState(songId) == DownloadState.DONE) { + // Kein Schreibvorgang beim Ueberspringen: der Fortschritt aendert sich dabei + // nicht, und bei 1900 Titeln waeren das 1900 unnoetige Schreibzugriffe je Lauf. done++ - dao.updateGroupProgress(groupId, done) continue } @@ -86,6 +93,8 @@ class DownloadWorker( dao.updateGroupProgress(groupId, done) } + // Beim Abbruch ist der letzte Stand sonst nicht gesichert. + if (gestoppt) dao.updateGroupProgress(groupId, done) val offen = dao.offeneTitel(groupId) when {