From fbdda89219d8a4328ad049173986e63c409fa8a8 Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sun, 13 Jul 2025 22:54:07 +0200 Subject: [PATCH] automatically update OSM data --- .../net/vonforst/evmap/EvMapApplication.kt | 20 +++++++- .../evmap/storage/CleanupCacheWorker.kt | 2 +- .../evmap/storage/UpdateFullDownloadWorker.kt | 46 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/net/vonforst/evmap/storage/UpdateFullDownloadWorker.kt diff --git a/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt b/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt index 09927094..6a6b0010 100644 --- a/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt +++ b/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt @@ -6,10 +6,12 @@ import android.os.Build import androidx.work.Configuration import androidx.work.Constraints import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.NetworkType import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import net.vonforst.evmap.storage.CleanupCacheWorker import net.vonforst.evmap.storage.PreferenceDataSource +import net.vonforst.evmap.storage.UpdateFullDownloadWorker import net.vonforst.evmap.ui.updateAppLocale import net.vonforst.evmap.ui.updateNightMode import org.acra.config.dialog @@ -68,6 +70,7 @@ class EvMapApplication : Application(), Configuration.Provider { } } + val workManager = WorkManager.getInstance(this) val cleanupCacheRequest = PeriodicWorkRequestBuilder(Duration.ofDays(1)) .setConstraints(Constraints.Builder().apply { setRequiresBatteryNotLow(true) @@ -75,9 +78,24 @@ class EvMapApplication : Application(), Configuration.Provider { setRequiresDeviceIdle(true) } }.build()).build() - WorkManager.getInstance(this).enqueueUniquePeriodicWork( + workManager.enqueueUniquePeriodicWork( "CleanupCacheWorker", ExistingPeriodicWorkPolicy.UPDATE, cleanupCacheRequest ) + + val updateFullDownloadRequest = + PeriodicWorkRequestBuilder(Duration.ofDays(7)) + .setConstraints(Constraints.Builder().apply { + setRequiresBatteryNotLow(true) + setRequiredNetworkType(NetworkType.UNMETERED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + setRequiresDeviceIdle(true) + } + }.build()).build() + workManager.enqueueUniquePeriodicWork( + "UpdateOsmWorker", + ExistingPeriodicWorkPolicy.UPDATE, + updateFullDownloadRequest + ) } override val workManagerConfiguration = Configuration.Builder().build() diff --git a/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt b/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt index 6e1927dc..c8be5316 100644 --- a/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt +++ b/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt @@ -15,7 +15,7 @@ class CleanupCacheWorker(appContext: Context, workerParams: WorkerParameters) : val savedRegionDao = db.savedRegionDao() val now = Instant.now() - val dataSources = listOf("openchargemap", "goingelectric") + val dataSources = listOf("openchargemap", "openstreetmap", "goingelectric") for (dataSource in dataSources) { val api = createApi(dataSource, applicationContext) val limit = now.minus(api.cacheLimit).toEpochMilli() diff --git a/app/src/main/java/net/vonforst/evmap/storage/UpdateFullDownloadWorker.kt b/app/src/main/java/net/vonforst/evmap/storage/UpdateFullDownloadWorker.kt new file mode 100644 index 00000000..6395912c --- /dev/null +++ b/app/src/main/java/net/vonforst/evmap/storage/UpdateFullDownloadWorker.kt @@ -0,0 +1,46 @@ +package net.vonforst.evmap.storage + +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import net.vonforst.evmap.api.createApi +import net.vonforst.evmap.api.openstreetmap.OSMReferenceData +import net.vonforst.evmap.api.openstreetmap.OpenStreetMapApiWrapper + +class UpdateFullDownloadWorker(appContext: Context, workerParams: WorkerParameters) : + CoroutineWorker(appContext, workerParams) { + override suspend fun doWork(): Result { + val dataSource = PreferenceDataSource(applicationContext).dataSource + val db = AppDatabase.getInstance(applicationContext) + val chargeLocations = db.chargeLocationsDao() + val api = createApi(dataSource, applicationContext) + + if (!api.supportsFullDownload) return Result.success() + + var insertJob: Job? = null + val result = api.fullDownload() + result.chargers.chunked(1024).forEach { + insertJob?.join() + insertJob = withContext(Dispatchers.IO) { + launch { + chargeLocations.insert(*it.toTypedArray()) + } + } + } + + when (api) { + is OpenStreetMapApiWrapper -> { + val refData = result.referenceData + val repo = OSMReferenceDataRepository(db.osmReferenceDataDao()) + repo.updateReferenceData(refData as OSMReferenceData) + } + } + + // TODO: remove deleted chargers + return Result.success() + } +} \ No newline at end of file