diff --git a/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatHorizontalWidget.kt b/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatHorizontalWidget.kt index e03b88c..8166b87 100644 --- a/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatHorizontalWidget.kt +++ b/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatHorizontalWidget.kt @@ -39,9 +39,15 @@ class SolatHorizontalWidget : AppWidgetProvider() { // There may be multiple widgets active, so update all of them for (appWidgetId in appWidgetIds) { Log.i(LOG_TAG, "onUpdate: SolatHorizontalWidget called") - updateAppWidget(context, appWidgetManager, appWidgetId, widgetData, R.layout.solat_horizontal_widget) + updateAppWidget( + context, + appWidgetManager, + appWidgetId, + widgetData, + R.layout.solat_horizontal_widget + ) } - + Log.i(LOG_TAG, "onUpdate: Scheduling for next widget update..") scheduleNextUpdate(context); } @@ -100,14 +106,22 @@ internal fun updateAppWidget( // if the data is outdated (the month & year doesn't match), show outdated layout if (!isDateValid("${parsed.get("month")}-${parsed.get("year")}")) { - Log.i(LOG_TAG, "updateAppWidget: Data ${parsed.get("month")}-${parsed.get("year")} is invalid"); + Log.i( + LOG_TAG, + "updateAppWidget: Data ${parsed.get("month")}-${parsed.get("year")} is invalid" + ); views.setViewVisibility(R.id.outdated_text, View.VISIBLE); views.setViewVisibility(R.id.prayer_layout, View.GONE); appWidgetManager.updateAppWidget(appWidgetId, views) return; } - Log.i(LOG_TAG, "updateAppWidget: Reading SP json ${parsed.get("zone")}, ${parsed.get("month")}-${parsed.get("year")} ") + Log.i( + LOG_TAG, + "updateAppWidget: Reading SP json ${parsed.get("zone")}, ${parsed.get("month")}-${ + parsed.get("year") + } " + ) // If the prayer layout is hidden previously, make sure we unhide it to show // the data. https://github.com/mptwaktusolat/app_waktu_solat_malaysia/issues/224 @@ -195,27 +209,31 @@ private fun scheduleNextUpdate(context: Context) { midnight.set(Calendar.MILLISECOND, 0) midnight.add(Calendar.DAY_OF_YEAR, 1) - // For API 19 and later, set may fire the intent a little later to save battery, - // setExact ensures the intent goes off exactly at midnight. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - alarmManager[AlarmManager.RTC_WAKEUP, midnight.getTimeInMillis()] = pendingIntent - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - if (alarmManager.canScheduleExactAlarms()) { - alarmManager.setExact( - AlarmManager.RTC_WAKEUP, - midnight.timeInMillis, - pendingIntent - ) - } else { - alarmManager.setExact( - AlarmManager.RTC_WAKEUP, - midnight.timeInMillis, - pendingIntent - ) - } + // On device running Android 14 without granting SCHEDULE_EXACT_ALARM permission may crashes + // if call the [scheduleNextUpdate] function below. See issue: https://github.com/mptwaktusolat/app_waktu_solat_malaysia/issues/228 + // So, if checks below to prevent to crashes from happen by not calling the function if above two conditions + // were met. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (!alarmManager.canScheduleExactAlarms()) { + // if permission was not granted, no worries, use normal set() method. But, it doesn't + // guarantee the timing to be run exact as the time we assigned to it + alarmManager.set(AlarmManager.RTC, midnight.timeInMillis, pendingIntent) + Log.d(LOG_TAG, "scheduleNextUpdate: Didn't have permission-Scheduled NOT exact alarm") + alarmManager.setExact( + AlarmManager.RTC, + midnight.timeInMillis, + pendingIntent + ); + return; } } + + // When version low than Android S, no need for permission hihi, just use setExact + // or when canScheduleExactAlarms() is true on Android S+ + // The [setExact] method was added in API Level 19. Since our minSdkVersion is not lower than 19, + // we are safe to call this function without if checks + alarmManager.setExact(AlarmManager.RTC, midnight.timeInMillis, pendingIntent) + Log.d(LOG_TAG, "scheduleNextUpdate: Scheduled exact alarm") } // Function to check the validity of the given month and year diff --git a/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatVerticalWidget.kt b/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatVerticalWidget.kt index b605f55..2b4726e 100644 --- a/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatVerticalWidget.kt +++ b/android/app/src/main/java/live/iqfareez/waktusolatmalaysia/SolatVerticalWidget.kt @@ -73,25 +73,29 @@ private fun scheduleNextUpdate(context: Context) { midnight.set(Calendar.MILLISECOND, 0) midnight.add(Calendar.DAY_OF_YEAR, 1) - // For API 19 and later, set may fire the intent a little later to save battery, - // setExact ensures the intent goes off exactly at midnight. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - alarmManager[AlarmManager.RTC_WAKEUP, midnight.getTimeInMillis()] = pendingIntent - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - if (alarmManager.canScheduleExactAlarms()) { - alarmManager.setExact( - AlarmManager.RTC_WAKEUP, - midnight.timeInMillis, - pendingIntent - ) - } else { - alarmManager.setExact( - AlarmManager.RTC_WAKEUP, - midnight.timeInMillis, - pendingIntent - ) - } + // On device running Android 14 without granting SCHEDULE_EXACT_ALARM permission may crashes + // if call the [scheduleNextUpdate] function below. See issue: https://github.com/mptwaktusolat/app_waktu_solat_malaysia/issues/228 + // So, if checks below to prevent to crashes from happen by not calling the function if above two conditions + // were met. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (!alarmManager.canScheduleExactAlarms()) { + // if permission was not granted, no worries, use normal set() method. But, it doesn't + // guarantee the timing to be run exact as the time we assigned to it + alarmManager.set(AlarmManager.RTC, midnight.timeInMillis, pendingIntent) + Log.d(LOG_TAG, "scheduleNextUpdate: Didn't have permission-Scheduled NOT exact alarm") + alarmManager.setExact( + AlarmManager.RTC, + midnight.timeInMillis, + pendingIntent + ); + return; } } + + // When version low than Android S, no need for permission hihi, just use setExact + // or when canScheduleExactAlarms() is true on Android S+ + // The [setExact] method was added in API Level 19. Since our minSdkVersion is not lower than 19, + // we are safe to call this function without if checks + alarmManager.setExact(AlarmManager.RTC, midnight.timeInMillis, pendingIntent) + Log.d(LOG_TAG, "scheduleNextUpdate: Scheduled exact alarm") } \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 3de1a90..1403bb1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -623,6 +623,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -643,26 +667,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -715,10 +739,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1084,6 +1108,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 320ce15..7719522 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: App waktu solat seluruh Malaysia publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 2.12.1+145 +version: 2.12.2+146 environment: sdk: ">=3.0.0 <4.0.0"