From 4565e4347906b17995854e1752557cf937659cbe Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Thu, 26 Feb 2026 20:26:43 -0700 Subject: [PATCH] attempt to stop crashes on Android 6 (but they didn't work) --- BUILDING.md | 1 + android/build.gradle | 3 +++ .../DailyNotificationFetcher.java | 2 +- .../DailyNotificationPlugin.kt | 6 ++--- .../DailyNotificationWorker.java | 2 +- .../dailynotification/FetchWorker.kt | 2 +- .../dailynotification/NotifyReceiver.kt | 25 +++++++++++-------- .../dailynotification/ReactivationManager.kt | 4 +-- test-apps/BUILD_PROCESS.md | 1 + .../android/app/build.gradle | 2 ++ 10 files changed, 29 insertions(+), 19 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index c99891e..43e79c3 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -94,6 +94,7 @@ The project includes an automated build script that handles both TypeScript and ```bash # Build all platforms +# Requires npm & gradle (with Java) ./scripts/build-native.sh # Build specific platform diff --git a/android/build.gradle b/android/build.gradle index ab7040b..014bd4d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -37,6 +37,7 @@ android { } compileOptions { + coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } @@ -116,6 +117,8 @@ dependencies { implementation "com.google.code.gson:gson:2.10.1" implementation "androidx.core:core:1.12.0" + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' + // Room annotation processor - use kapt for Kotlin, annotationProcessor for Java kapt "androidx.room:room-compiler:2.6.1" annotationProcessor "androidx.room:room-compiler:2.6.1" diff --git a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java index e5ce391..0276871 100644 --- a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java +++ b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java @@ -229,7 +229,7 @@ public class DailyNotificationFetcher { content.getTitle(), content.getBody(), content.getScheduledTime(), - java.time.ZoneId.systemDefault().getId() + java.util.TimeZone.getDefault().getID() ); entity.priority = mapPriority(content.getPriority()); try { diff --git a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt index f3e6ad4..8c92626 100644 --- a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt +++ b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt @@ -1162,12 +1162,12 @@ open class DailyNotificationPlugin : Plugin() { } else { call.reject("Daily notification scheduling failed") } - } catch (e: Exception) { + } catch (e: Throwable) { Log.e(TAG, "Failed to schedule daily notification", e) call.reject("Daily notification scheduling failed: ${e.message}") } } - } catch (e: Exception) { + } catch (e: Throwable) { Log.e(TAG, "Schedule daily notification error", e) call.reject("Daily notification error: ${e.message}") } @@ -2729,7 +2729,7 @@ object ScheduleHelper { } true - } catch (e: Exception) { + } catch (e: Throwable) { Log.e("ScheduleHelper", "Failed to schedule daily notification", e) false } diff --git a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationWorker.java b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationWorker.java index 7a39a2b..a8b1616 100644 --- a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationWorker.java +++ b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationWorker.java @@ -740,7 +740,7 @@ public class DailyNotificationWorker extends Worker { content.getTitle(), content.getBody(), content.getScheduledTime(), - java.time.ZoneId.systemDefault().getId() + java.util.TimeZone.getDefault().getID() ); entity.priority = mapPriorityToInt(content.getPriority()); try { diff --git a/android/src/main/java/com/timesafari/dailynotification/FetchWorker.kt b/android/src/main/java/com/timesafari/dailynotification/FetchWorker.kt index 79abb0a..78fc55c 100644 --- a/android/src/main/java/com/timesafari/dailynotification/FetchWorker.kt +++ b/android/src/main/java/com/timesafari/dailynotification/FetchWorker.kt @@ -211,7 +211,7 @@ class FetchWorker( title, body, notificationTime, - java.time.ZoneId.systemDefault().id + java.util.TimeZone.getDefault().id ) entity.priority = 0 // default priority entity.vibrationEnabled = true diff --git a/android/src/main/java/com/timesafari/dailynotification/NotifyReceiver.kt b/android/src/main/java/com/timesafari/dailynotification/NotifyReceiver.kt index 75cc883..40846c7 100644 --- a/android/src/main/java/com/timesafari/dailynotification/NotifyReceiver.kt +++ b/android/src/main/java/com/timesafari/dailynotification/NotifyReceiver.kt @@ -257,7 +257,7 @@ class NotifyReceiver : BroadcastReceiver() { config.title, config.body ?: (if (contentCache != null) String(contentCache.payload) else ""), triggerAtMillis, - java.time.ZoneId.systemDefault().id + java.util.TimeZone.getDefault().id ) entity.priority = when (config.priority) { "high", "max" -> 2 @@ -275,7 +275,7 @@ class NotifyReceiver : BroadcastReceiver() { roomStorage.saveNotificationContent(entity).get() Log.d(TAG, "Stored notification content in database: id=$notificationId (for recovery tracking)") } - } catch (e: Exception) { + } catch (e: Throwable) { Log.w(TAG, "Failed to store notification content in database, continuing with alarm scheduling", e) } @@ -400,14 +400,18 @@ class NotifyReceiver : BroadcastReceiver() { Log.i(TAG, "Exact alarm scheduled (setExact): triggerAt=$triggerAtMillis, requestCode=$requestCode") } - } catch (e: SecurityException) { + } catch (e: Throwable) { Log.w(TAG, "Cannot schedule exact alarm, falling back to inexact", e) - alarmManager.set( - AlarmManager.RTC_WAKEUP, - triggerAtMillis, - pendingIntent - ) - Log.i(TAG, "Inexact alarm scheduled (fallback): triggerAt=$triggerAtMillis, requestCode=$requestCode") + try { + alarmManager.set( + AlarmManager.RTC_WAKEUP, + triggerAtMillis, + pendingIntent + ) + Log.i(TAG, "Inexact alarm scheduled (fallback): triggerAt=$triggerAtMillis, requestCode=$requestCode") + } catch (fallbackError: Throwable) { + Log.e(TAG, "Fallback alarm scheduling also failed", fallbackError) + } } // Update database schedule with new nextRunAt so getNotificationStatus() returns correct value @@ -462,8 +466,7 @@ class NotifyReceiver : BroadcastReceiver() { Log.d(SCHEDULE_TAG, "Created new schedule in database: id=$stableScheduleId, nextRunAt=$triggerAtMillis") } } - } catch (e: Exception) { - // Log but don't fail - alarm is already scheduled, DB update is best-effort + } catch (e: Throwable) { Log.w(SCHEDULE_TAG, "Failed to update schedule in database: $stableScheduleId (alarm still scheduled)", e) } } diff --git a/android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt b/android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt index 395eb59..439fa39 100644 --- a/android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt +++ b/android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt @@ -273,7 +273,7 @@ class ReactivationManager(private val context: Context) { "Daily Notification", "Your daily update is ready", scheduledTime, - java.time.ZoneId.systemDefault().id + java.util.TimeZone.getDefault().id ) notification.deliveryStatus = "missed" notification.lastDeliveryAttempt = System.currentTimeMillis() @@ -1043,7 +1043,7 @@ class ReactivationManager(private val context: Context) { "Daily Notification", "Your daily update is ready", scheduledTime, - java.time.ZoneId.systemDefault().id + java.util.TimeZone.getDefault().id ) notification.deliveryStatus = "missed" notification.lastDeliveryAttempt = System.currentTimeMillis() diff --git a/test-apps/BUILD_PROCESS.md b/test-apps/BUILD_PROCESS.md index ea8c2ab..28525e3 100644 --- a/test-apps/BUILD_PROCESS.md +++ b/test-apps/BUILD_PROCESS.md @@ -65,6 +65,7 @@ emulator -avd AVD_NAME adb devices # Now install on the emulator +# ... which can take a looooooong time adb install -r ./app/build/outputs/apk/debug/app-debug.apk # Now start the app diff --git a/test-apps/daily-notification-test/android/app/build.gradle b/test-apps/daily-notification-test/android/app/build.gradle index a55631f..bbd1da3 100644 --- a/test-apps/daily-notification-test/android/app/build.gradle +++ b/test-apps/daily-notification-test/android/app/build.gradle @@ -17,6 +17,7 @@ android { } } compileOptions { + coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } @@ -62,6 +63,7 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-service:2.7.0' implementation 'com.google.code.gson:gson:2.10.1' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' testImplementation "junit:junit:$junitVersion" androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"