diff --git a/android/app/src/main/java/ai/offgridmobile/download/DownloadForegroundService.kt b/android/app/src/main/java/ai/offgridmobile/download/DownloadForegroundService.kt index 30508e618..e990f2cf9 100644 --- a/android/app/src/main/java/ai/offgridmobile/download/DownloadForegroundService.kt +++ b/android/app/src/main/java/ai/offgridmobile/download/DownloadForegroundService.kt @@ -95,10 +95,16 @@ class DownloadForegroundService : Service() { private fun startService(context: Context) { val intent = Intent(context, DownloadForegroundService::class.java) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(intent) - } else { - context.startService(intent) + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.startForegroundService(intent) + } else { + context.startService(intent) + } + } catch (e: IllegalStateException) { + // App is in the background on Android 12+ — notification skipped, + // but WorkManager continues the download unaffected. + android.util.Log.w("DownloadService", "Skipping foreground notification (background): ${e.message}") } } } @@ -112,10 +118,19 @@ class DownloadForegroundService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val notification = buildNotificationFromState() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC) - } else { - startForeground(NOTIFICATION_ID, notification) + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC) + } else { + startForeground(NOTIFICATION_ID, notification) + } + } catch (e: IllegalStateException) { + // startForeground() can throw on Android 15+ when the dataSync time budget + // is exhausted. Calling stopSelf() here prevents the service sitting in limbo, + // which would otherwise trigger ForegroundServiceDidNotStartInTimeException. + // WorkManager continues the download unaffected without the notification. + android.util.Log.w("DownloadService", "startForeground failed, stopping service: ${e.message}") + stopSelf() } return START_NOT_STICKY } diff --git a/ios/OffgridMobile.xcodeproj/project.pbxproj b/ios/OffgridMobile.xcodeproj/project.pbxproj index f7a712c4c..3d87997e5 100644 --- a/ios/OffgridMobile.xcodeproj/project.pbxproj +++ b/ios/OffgridMobile.xcodeproj/project.pbxproj @@ -315,14 +315,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-OffgridMobile/Pods-OffgridMobile-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-OffgridMobile/Pods-OffgridMobile-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OffgridMobile/Pods-OffgridMobile-frameworks.sh\"\n"; @@ -358,14 +354,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-OffgridMobile/Pods-OffgridMobile-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-OffgridMobile/Pods-OffgridMobile-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OffgridMobile/Pods-OffgridMobile-resources.sh\"\n"; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index a076829d0..3db88fc3a 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3238,11 +3238,11 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNZipArchive (7.0.2): + - RNZipArchive (7.1.0): - React-Core - - RNZipArchive/Core (= 7.0.2) + - RNZipArchive/Core (= 7.1.0) - SSZipArchive (~> 2.5.5) - - RNZipArchive/Core (7.0.2): + - RNZipArchive/Core (7.1.0): - React-Core - SSZipArchive (~> 2.5.5) - SocketRocket (0.7.1) @@ -3603,7 +3603,7 @@ SPEC CHECKSUMS: FBLazyVector: 309703e71d3f2f1ed7dc7889d58309c9d77a95a4 fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 - hermes-engine: 3f74bbb07573d284e764cee0131ae769e16c53b8 + hermes-engine: 8c6be38f94b3bf8b864981980e64e55f08e467ec llama-rn: 3ae5a64b3d08ff41f9e62b214ba5004e475b9561 lottie-ios: a881093fab623c467d3bce374367755c272bdd59 lottie-react-native: 691b8363e8c591fb78a78254ff2517258891456b @@ -3695,7 +3695,7 @@ SPEC CHECKSUMS: RNSVG: 595abfa0f9ac26d56afcaaedf4e37a00f54cab71 RNVectorIcons: 791f13226ec4a3fd13062eda9e892159f0981fae RNWorklets: 944dddd0eef13006b658e653abbb3ee8365c3809 - RNZipArchive: 4304f5100eab004eeb7349adc51997b3a28deb76 + RNZipArchive: f2806ba80e24cf1984d6a7cb361d8a07d734997d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 SSZipArchive: c69881e8ac5521f0e622291387add5f60f30f3c4 whisper-rn: 7566faf9b7d78e39ab9fc634cb90fdee81177793 diff --git a/package-lock.json b/package-lock.json index 11517dc29..17facdb48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "react-native-svg": "^15.15.3", "react-native-vector-icons": "^10.3.0", "react-native-worklets": "^0.7.3", - "react-native-zip-archive": "^7.0.2", + "react-native-zip-archive": "^7.1.0", "whisper.rn": "^0.5.5", "zustand": "^5.0.10" }, @@ -12595,9 +12595,9 @@ } }, "node_modules/react-native-zip-archive": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/react-native-zip-archive/-/react-native-zip-archive-7.0.2.tgz", - "integrity": "sha512-msCRJMcwH6NVZ2/zoC+1nvA0wlpYRnMxteQywS9nt4BzXn48tZpaVtE519QEZn0xe3ygvgsWx5cdPoE9Jx3bsg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-native-zip-archive/-/react-native-zip-archive-7.1.0.tgz", + "integrity": "sha512-d/UGiF4Y9Xlf3PUIDO6d9u8AFuv1Wl7n8GirYOobpVoPLFuQhhf+YsHEZJBbi6aSZcM6QcGxeoqcJi303OrWJA==", "license": "MIT", "peerDependencies": { "react": ">=16.8.6", @@ -14156,7 +14156,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 58f1de965..29ecf907f 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "react-native-svg": "^15.15.3", "react-native-vector-icons": "^10.3.0", "react-native-worklets": "^0.7.3", - "react-native-zip-archive": "^7.0.2", + "react-native-zip-archive": "^7.1.0", "whisper.rn": "^0.5.5", "zustand": "^5.0.10" },