diff --git a/android/.gitignore b/android/.gitignore
index 67e07b8fea40e2050dce30710b53f2278836ecb9..e00b1df3a76b3ff2daf48f412bff7175fffbcecd 100644
--- a/android/.gitignore
+++ b/android/.gitignore
@@ -1,2 +1,3 @@
/build
/release
+version.properties
diff --git a/android/build.gradle.kts b/android/build.gradle.kts
index 30ac2080564beeab4eebb027eee61d39ebd00227..4e4f76b07336bff08125eeea689f79cfd65c1a39 100644
--- a/android/build.gradle.kts
+++ b/android/build.gradle.kts
@@ -1,5 +1,8 @@
@file:Suppress("UnstableApiUsage", "DSL_SCOPE_VIOLATION", "KaptUsageInsteadOfKsp")
+import java.io.FileInputStream
+import java.util.Properties
+
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
@@ -12,12 +15,71 @@ android {
namespace = "foundation.e.blissweather"
compileSdk = 33
+ val versionPropsFile = file("version.properties")
+ val versionProps = Properties()
+
+ if (!versionPropsFile.exists()) {
+ versionProps["VERSION_CHANGE"] = "0"
+ versionProps["VERSION_MAJOR"] = "1"
+ versionProps["VERSION_MINOR"] = "0"
+ versionProps["VERSION_PATCH"] = "0"
+ versionProps["VERSION_CODE"] = "1"
+ versionProps.store(versionPropsFile.writer(), null)
+ }
+
+ fun getVersionCode(): Int {
+ if (versionPropsFile.canRead()) {
+ versionProps.load(FileInputStream(versionPropsFile))
+ var versionChange = Integer.valueOf(versionProps["VERSION_CHANGE"].toString()) + 1
+ var versionMinor = Integer.valueOf(versionProps["VERSION_MINOR"].toString())
+ var versionMajor = Integer.valueOf(versionProps["VERSION_MAJOR"].toString())
+ var versionPatch = Integer.valueOf(versionProps["VERSION_PATCH"].toString())
+ // Up version on each 100 cycles of builds
+ if (versionChange >= 100) {
+ versionPatch += 1
+ versionChange = 0
+ }
+ if (versionPatch == 9) {
+ versionMinor = versionPatch + 1
+ versionPatch = 0
+ }
+ if (versionMinor == 9) {
+ versionMajor += 1
+ versionMinor = 0
+ }
+ val versionCode = Integer.valueOf(versionProps["VERSION_CODE"].toString())
+
+ versionProps["VERSION_CHANGE"] = versionChange.toString()
+ versionProps["VERSION_PATCH"] = versionPatch.toString()
+ versionProps["VERSION_MINOR"] = versionMinor.toString()
+ versionProps["VERSION_MAJOR"] = versionMajor.toString()
+ versionProps["VERSION_CODE"] = (Integer.valueOf(versionCode) + 1).toString()
+ versionProps.store(versionPropsFile.writer(), null)
+
+ return versionCode
+ }
+ return 1
+ }
+
+ fun getVersionName(): String {
+ if (versionPropsFile.canRead()) {
+ versionProps.load(FileInputStream(versionPropsFile))
+
+ val versionMajor = versionProps["VERSION_MAJOR"]
+ val versionMinor = versionProps["VERSION_MINOR"]
+ val versionPatch = versionProps["VERSION_PATCH"]
+
+ return "${versionMajor}.${versionMinor}.${versionPatch}"
+ }
+ return "1.0"
+ }
+
defaultConfig {
applicationId = "foundation.e.blissweather"
minSdk = 25
targetSdk = 33
- versionCode = 1
- versionName = "1.0"
+ versionCode = getVersionCode()
+ versionName = getVersionName()
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 259c191fe6514139fd0f07cf697413dfa00aad36..ebf2e63d2db39d7cba55fe57d5dd9d435eab385b 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
+
(refreshInterval, TimeUnit.MINUTES)
+ // Don't use this periodic worker, it doesn't work on idle.
+ PeriodicWorkRequestBuilder(30, TimeUnit.DAYS)
.setConstraints(constraints)
.build()
)
+
+ // Use AlarmManager for repeated job
+ AlarmUtils.cancelRepeatingUpdatesCheck(context)
+ AlarmUtils.scheduleRepeatingUpdatesCheck(context, refreshInterval)
} else {
workMgr
.beginWith(
@@ -74,6 +80,9 @@ class WeatherAppWidgetProvider : AppWidgetProvider() {
.build()
)
.enqueue()
+
+ // Cancel any repeating alarm
+ AlarmUtils.cancelRepeatingUpdatesCheck(context)
}
}
@@ -83,7 +92,7 @@ class WeatherAppWidgetProvider : AppWidgetProvider() {
}
override fun onReceive(context: Context, intent: Intent?) {
- Log.d(TAG, "onReceive: $intent}")
+ Log.d(TAG, "onReceive: $intent")
super.onReceive(context, intent)
when (intent?.action) {
ACTION_WEATHER_REFRESH,
diff --git a/android/src/main/kotlin/foundation/e/blissweather/worker/AlarmUtils.kt b/android/src/main/kotlin/foundation/e/blissweather/worker/AlarmUtils.kt
new file mode 100644
index 0000000000000000000000000000000000000000..352a87df1f6b0b23a014b7a849affbbc55da868f
--- /dev/null
+++ b/android/src/main/kotlin/foundation/e/blissweather/worker/AlarmUtils.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 MURENA SAS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package foundation.e.blissweather.worker
+
+import android.annotation.SuppressLint
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.util.Log
+import foundation.e.blissweather.widget.WeatherAppWidgetProvider
+import java.util.Date
+
+object AlarmUtils {
+ private const val TAG = "AlarmUtils"
+
+ @SuppressLint("ScheduleExactAlarm")
+ fun scheduleRepeatingUpdatesCheck(context: Context, refreshInterval: Long) {
+ val updateCheckIntent: PendingIntent = getRepeatingUpdatesCheckIntent(context)
+ val alarmMgr = context.getSystemService(AlarmManager::class.java)
+ val nextCheck: Long = System.currentTimeMillis() + (refreshInterval * 60 * 1000)
+ alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextCheck, updateCheckIntent)
+ Log.d(TAG, "Setting automatic updates check: ${Date(nextCheck)}")
+ }
+
+ private fun getRepeatingUpdatesCheckIntent(context: Context): PendingIntent {
+ val intent = Intent(context, WeatherAppWidgetProvider::class.java)
+ intent.setAction(WeatherAppWidgetProvider.ACTION_WEATHER_REFRESH)
+ return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+ }
+
+ fun cancelRepeatingUpdatesCheck(context: Context) {
+ val alarmMgr = context.getSystemService(AlarmManager::class.java)
+ alarmMgr.cancel(getRepeatingUpdatesCheckIntent(context))
+ }
+}