diff --git a/CHANGELOG.de.md b/CHANGELOG.de.md
index 2e157d1..c0e0723 100644
--- a/CHANGELOG.de.md
+++ b/CHANGELOG.de.md
@@ -8,19 +8,30 @@ Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
---
-## [1.7.1] - 2026-01-30
+## [1.7.1] - 2026-02-02
### đ Kritische Fehlerbehebungen
-- **App-Absturz auf Android 9 nach längerer Nutzung behoben** ([ref #15](https://github.com/inventory69/simple-notes-sync/issues/15))
- - RessourcenerschĂśpfung durch nicht geschlossene HTTP-Verbindungen behoben
- - App konnte nach ~30-45 Minuten Nutzung durch angesammelte Connection-Leaks abstĂźrzen
- - Danke an [@roughnecks] fĂźr den detaillierten Fehlerbericht!
+#### Android 9 App-Absturz Fix ([#15](https://github.com/inventory69/simple-notes-sync/issues/15))
-- **VPN-Kompatibilitäts-Regression behoben** ([ref #11](https://github.com/inventory69/simple-notes-sync/issues/11))
- - WiFi Socket-Binding erkennt jetzt korrekt Wireguard VPN-Interfaces (tun*, wg*, *-wg-*)
- - Traffic wird korrekt durch VPN-Tunnel geleitet statt direkt Ăźber WiFi
- - Behebt "Verbindungs-Timeout" beim Sync zu externen Servern Ăźber VPN
+**Problem:** App stĂźrzte auf Android 9 (API 28) ab wenn WorkManager Expedited Work fĂźr Hintergrund-Sync verwendet wurde.
+
+**Root Cause:** Wenn `setExpedited()` in WorkManager verwendet wird, muss die `CoroutineWorker` die Methode `getForegroundInfo()` implementieren um eine Foreground Service Notification zurĂźckzugeben. Auf Android 9-11 ruft WorkManager diese Methode auf, aber die Standard-Implementierung wirft `IllegalStateException: Not implemented`.
+
+**LĂśsung:** `getForegroundInfo()` in `SyncWorker` implementiert um eine korrekte `ForegroundInfo` mit Sync-Progress-Notification zurĂźckzugeben.
+
+**Details:**
+- `ForegroundInfo` mit Sync-Progress-Notification fĂźr Android 9-11 hinzugefĂźgt
+- Android 10+: Setzt `FOREGROUND_SERVICE_TYPE_DATA_SYNC` fĂźr korrekte Service-Typisierung
+- Foreground Service Permissions in AndroidManifest.xml hinzugefĂźgt
+- Notification zeigt Sync-Progress mit indeterminiertem Progress Bar
+- Danke an [@roughnecks](https://github.com/roughnecks) fĂźr das detaillierte Debugging!
+
+#### VPN-Kompatibilitäts-Fix ([#11](https://github.com/inventory69/simple-notes-sync/issues/11))
+
+- WiFi Socket-Binding erkennt jetzt korrekt Wireguard VPN-Interfaces (tun*, wg*, *-wg-*)
+- Traffic wird korrekt durch VPN-Tunnel geleitet statt direkt Ăźber WiFi
+- Behebt "Verbindungs-Timeout" beim Sync zu externen Servern Ăźber VPN
### đ§ Technische Ănderungen
@@ -28,10 +39,12 @@ Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Weniger unnĂśtige 401-Authentifizierungs-Challenges durch preemptive Auth-Header
- ProGuard-Regel hinzugefĂźgt um harmlose TextInclusionStrategy-Warnungen zu unterdrĂźcken
- VPN-Interface-Erkennung via `NetworkInterface.getNetworkInterfaces()` Pattern-Matching
+- Foreground Service Erkennung und Notification-System fĂźr Hintergrund-Sync-Tasks
### đ Lokalisierung
- Hardcodierte deutsche Fehlermeldungen behoben - jetzt String-Resources fĂźr korrekte Lokalisierung
+- Deutsche und englische Strings fĂźr Sync-Progress-Notifications hinzugefĂźgt
---
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a63608..759db93 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,19 +8,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
---
-## [1.7.1] - 2026-01-30
+## [1.7.1] - 2026-02-02
### đ Critical Bug Fixes
-- **Fixed app crash on Android 9 after extended use** ([ref #15](https://github.com/inventory69/simple-notes-sync/issues/15))
- - Fixed resource exhaustion caused by unclosed HTTP connections
- - App could crash after ~30-45 minutes of use due to accumulated connection leaks
- - Thanks to [@roughnecks] for the detailed bug report!
+#### Android 9 App Crash Fix ([#15](https://github.com/inventory69/simple-notes-sync/issues/15))
-- **Fixed VPN compatibility regression** ([ref #11](https://github.com/inventory69/simple-notes-sync/issues/11))
- - WiFi socket binding now correctly detects Wireguard VPN interfaces (tun*, wg*, *-wg-*)
- - Traffic routes through VPN tunnel instead of bypassing it directly to WiFi
- - Fixes "Connection timeout" when syncing to external servers via VPN
+**Problem:** App crashed on Android 9 (API 28) when using WorkManager Expedited Work for background sync.
+
+**Root Cause:** When `setExpedited()` is used in WorkManager, the `CoroutineWorker` must implement `getForegroundInfo()` to return a Foreground Service notification. On Android 9-11, WorkManager calls this method, but the default implementation throws `IllegalStateException: Not implemented`.
+
+**Solution:** Implemented `getForegroundInfo()` in `SyncWorker` to return a proper `ForegroundInfo` with sync progress notification.
+
+**Details:**
+- Added `ForegroundInfo` with sync progress notification for Android 9-11
+- Android 10+: Sets `FOREGROUND_SERVICE_TYPE_DATA_SYNC` for proper service typing
+- Added Foreground Service permissions to AndroidManifest.xml
+- Notification shows sync progress with indeterminate progress bar
+- Thanks to [@roughnecks](https://github.com/roughnecks) for the detailed debugging!
+
+#### VPN Compatibility Fix ([#11](https://github.com/inventory69/simple-notes-sync/issues/11))
+
+- WiFi socket binding now correctly detects Wireguard VPN interfaces (tun*, wg*, *-wg-*)
+- Traffic routes through VPN tunnel instead of bypassing it directly to WiFi
+- Fixes "Connection timeout" when syncing to external servers via VPN
### đ§ Technical Changes
@@ -28,10 +39,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Reduced unnecessary 401 authentication challenges with preemptive auth headers
- Added ProGuard rule to suppress harmless TextInclusionStrategy warnings on older Android versions
- VPN interface detection via `NetworkInterface.getNetworkInterfaces()` pattern matching
+- Foreground Service detection and notification system for background sync tasks
### đ Localization
- Fixed hardcoded German error messages - now uses string resources for proper localization
+- Added German and English strings for sync progress notifications
---
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index e6d274b..e315feb 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -20,8 +20,8 @@ android {
applicationId = "dev.dettmer.simplenotes"
minSdk = 24
targetSdk = 36
- versionCode = 18 // đ§ v1.7.1: Connection Leak Fix (Issue #15)
- versionName = "1.7.1" // đ§ v1.7.1: Connection Leak Fix
+ versionCode = 18 // đ§ v1.7.1: Android 9 getForegroundInfo Fix (Issue #15)
+ versionName = "1.7.1" // đ§ v1.7.1: Android 9 getForegroundInfo Fix
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index bc7094a..601b20a 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -12,6 +12,11 @@
+
+
+
+
+
diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncWorker.kt b/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncWorker.kt
index 692db55..43ee154 100644
--- a/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncWorker.kt
+++ b/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncWorker.kt
@@ -5,8 +5,11 @@ package dev.dettmer.simplenotes.sync
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
+import android.content.pm.ServiceInfo
+import android.os.Build
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.work.CoroutineWorker
+import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import dev.dettmer.simplenotes.BuildConfig
import dev.dettmer.simplenotes.utils.Constants
@@ -26,6 +29,35 @@ class SyncWorker(
const val ACTION_SYNC_COMPLETED = "dev.dettmer.simplenotes.SYNC_COMPLETED"
}
+ /**
+ * đ§ v1.7.2: Required for expedited work on Android 9-11
+ *
+ * WorkManager ruft diese Methode auf um die Foreground-Notification zu erstellen
+ * wenn der Worker als Expedited Work gestartet wird.
+ *
+ * Ab Android 12+ wird diese Methode NICHT aufgerufen (neue Expedited API).
+ * Auf Android 9-11 MUSS diese Methode implementiert sein!
+ *
+ * @see https://developer.android.com/develop/background-work/background-tasks/persistent/getting-started/define-work#foregroundinfo
+ */
+ override suspend fun getForegroundInfo(): ForegroundInfo {
+ val notification = NotificationHelper.createSyncProgressNotification(applicationContext)
+
+ // Android 10+ benĂśtigt foregroundServiceType
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ForegroundInfo(
+ NotificationHelper.SYNC_PROGRESS_NOTIFICATION_ID,
+ notification,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+ )
+ } else {
+ ForegroundInfo(
+ NotificationHelper.SYNC_PROGRESS_NOTIFICATION_ID,
+ notification
+ )
+ }
+ }
+
/**
* PrĂźft ob die App im Vordergrund ist.
* Wenn ja, brauchen wir keine Benachrichtigung - die UI zeigt die Ănderungen direkt.
diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt b/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt
index 62d2eda..e4909e5 100644
--- a/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt
+++ b/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt
@@ -19,6 +19,7 @@ object NotificationHelper {
private const val CHANNEL_ID = "notes_sync_channel"
private const val NOTIFICATION_ID = 1001
private const val SYNC_NOTIFICATION_ID = 2
+ const val SYNC_PROGRESS_NOTIFICATION_ID = 1003 // v1.7.2: For expedited work foreground notification
private const val AUTO_CANCEL_TIMEOUT_MS = 30_000L
/**
@@ -54,6 +55,26 @@ object NotificationHelper {
Logger.d(TAG, "đď¸ Cleared old sync notifications")
}
+ /**
+ * đ§ v1.7.2: Erstellt Notification fĂźr Sync-Progress (Expedited Work)
+ *
+ * Wird von SyncWorker.getForegroundInfo() aufgerufen auf Android 9-11.
+ * Muss eine gĂźltige, sichtbare Notification zurĂźckgeben.
+ *
+ * @return Notification (nicht anzeigen, nur erstellen)
+ */
+ fun createSyncProgressNotification(context: Context): android.app.Notification {
+ return NotificationCompat.Builder(context, CHANNEL_ID)
+ .setSmallIcon(android.R.drawable.stat_notify_sync)
+ .setContentTitle(context.getString(R.string.sync_in_progress))
+ .setContentText(context.getString(R.string.sync_in_progress_text))
+ .setPriority(NotificationCompat.PRIORITY_LOW)
+ .setOngoing(true)
+ .setProgress(0, 0, true) // Indeterminate progress
+ .setCategory(NotificationCompat.CATEGORY_PROGRESS)
+ .build()
+ }
+
/**
* Zeigt Erfolgs-Notification nach Sync
*/
diff --git a/android/app/src/main/res/values-de/strings.xml b/android/app/src/main/res/values-de/strings.xml
index eeff55f..f773ecd 100644
--- a/android/app/src/main/res/values-de/strings.xml
+++ b/android/app/src/main/res/values-de/strings.xml
@@ -438,6 +438,8 @@
Notizen Synchronisierung
Benachrichtigungen Ăźber Sync-Status
+ Synchronisierung läuft
+ Notizen werden synchronisiertâŚ
Sync erfolgreich
%d Notiz(en) synchronisiert
Sync fehlgeschlagen
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index cd9d711..e51bbf0 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -438,6 +438,8 @@
Notes Synchronization
Notifications about sync status
+ Syncing
+ Syncing notesâŚ
Sync successful
%d note(s) synchronized
Sync failed
diff --git a/fastlane/metadata/android/de-DE/changelogs/18.txt b/fastlane/metadata/android/de-DE/changelogs/18.txt
index 3896169..9336b4d 100644
--- a/fastlane/metadata/android/de-DE/changelogs/18.txt
+++ b/fastlane/metadata/android/de-DE/changelogs/18.txt
@@ -1,4 +1,6 @@
-⢠Behoben: App-Absturz auf Android 9 - Danke an @roughnecks
-⢠Behoben: Kernel-VPN-Kompatibilität (Wireguard)
-⢠Verbessert: Stabilität der Sync-Sessions
-⢠Technisch: Optimierte Verbindungsverwaltung
+⢠Behoben: App-Absturz auf Android 9 (Issue #15) - Danke an @roughnecks
+ - WorkManager Expedited Work Kompatibilität (getForegroundInfo)
+ - Kernel-VPN-Kompatibilität (Wireguard tun/wg Interfaces)
+⢠Verbessert: Stabilität und Verbindungsverwaltung
+⢠Technisch: Optimierter HTTP-Connection-Lebenszyklus
+
diff --git a/fastlane/metadata/android/en-US/changelogs/18.txt b/fastlane/metadata/android/en-US/changelogs/18.txt
index e0fabd8..aa74861 100644
--- a/fastlane/metadata/android/en-US/changelogs/18.txt
+++ b/fastlane/metadata/android/en-US/changelogs/18.txt
@@ -1,4 +1,5 @@
-⢠Fixed: App crash on Android 9 - Thanks to @roughnecks
-⢠Fixed: Kernel-VPN compatibility (Wireguard)
-⢠Improved: Stability at sync sessions
-⢠Technical: Optimized connection management
+⢠Fixed: App crash on Android 9 (Issue #15) - Thanks to @roughnecks
+ - WorkManager expedited work compatibility (getForegroundInfo)
+ - Kernel-VPN compatibility (Wireguard tun/wg interfaces)
+⢠Improved: Stability and connection management
+⢠Technical: Optimized HTTP connection lifecycle