diff --git a/app/build.gradle b/app/build.gradle index 72bcd1c9..af35727c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -184,6 +184,7 @@ dependencies { implementation 'androidx.browser:browser:1.5.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.security:security-crypto:1.1.0-alpha06' + implementation "androidx.work:work-runtime-ktx:2.7.1" implementation 'com.github.ev-map:CustomBottomSheetBehavior:e48f73ea7b' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-moshi:2.9.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 85f1358c..fad863ac 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ - + @@ -287,6 +288,18 @@ android:name="autoStoreLocales" android:value="true" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt b/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt index 4398fb99..c4a1b1d5 100644 --- a/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt +++ b/app/src/main/java/net/vonforst/evmap/EvMapApplication.kt @@ -1,6 +1,9 @@ package net.vonforst.evmap import android.app.Application +import android.os.Build +import androidx.work.* +import net.vonforst.evmap.storage.CleanupCacheWorker import net.vonforst.evmap.storage.PreferenceDataSource import net.vonforst.evmap.ui.updateAppLocale import net.vonforst.evmap.ui.updateNightMode @@ -9,8 +12,9 @@ import org.acra.config.limiter import org.acra.config.mailSender import org.acra.data.StringFormat import org.acra.ktx.initAcra +import java.time.Duration -class EvMapApplication : Application() { +class EvMapApplication : Application(), Configuration.Provider { override fun onCreate() { super.onCreate() val prefs = PreferenceDataSource(this) @@ -48,5 +52,20 @@ class EvMapApplication : Application() { } } } + + val cleanupCacheRequest = PeriodicWorkRequestBuilder(Duration.ofDays(1)) + .setConstraints(Constraints.Builder().apply { + setRequiresBatteryNotLow(true) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + setRequiresDeviceIdle(true) + } + }.build()).build() + WorkManager.getInstance(this).enqueueUniquePeriodicWork( + "CleanupCacheWorker", ExistingPeriodicWorkPolicy.REPLACE, cleanupCacheRequest + ) + } + + override fun getWorkManagerConfiguration(): Configuration { + return Configuration.Builder().build() } } \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/api/ChargepointApi.kt b/app/src/main/java/net/vonforst/evmap/api/ChargepointApi.kt index aa3878fc..2bb06ce8 100644 --- a/app/src/main/java/net/vonforst/evmap/api/ChargepointApi.kt +++ b/app/src/main/java/net/vonforst/evmap/api/ChargepointApi.kt @@ -9,6 +9,7 @@ import net.vonforst.evmap.api.openchargemap.OpenChargeMapApiWrapper import net.vonforst.evmap.model.* import net.vonforst.evmap.viewmodel.Resource import java.time.Duration +import java.time.Instant interface ChargepointApi { /** diff --git a/app/src/main/java/net/vonforst/evmap/storage/ChargeLocationsDao.kt b/app/src/main/java/net/vonforst/evmap/storage/ChargeLocationsDao.kt index 4df12ff0..272cc5f8 100644 --- a/app/src/main/java/net/vonforst/evmap/storage/ChargeLocationsDao.kt +++ b/app/src/main/java/net/vonforst/evmap/storage/ChargeLocationsDao.kt @@ -50,6 +50,9 @@ abstract class ChargeLocationsDao { @Delete abstract suspend fun delete(vararg locations: ChargeLocation) + @Query("DELETE FROM chargelocation WHERE dataSource == :dataSource AND timeRetrieved <= :before AND NOT EXISTS (SELECT 1 FROM favorite WHERE favorite.chargerId = chargelocation.id)") + abstract suspend fun deleteOutdatedIfNotFavorite(dataSource: String, before: Long) + @Query("SELECT * FROM chargelocation WHERE dataSource == :dataSource AND id == :id AND isDetailed == 1 AND timeRetrieved > :after") abstract fun getChargeLocationById( id: Long, @@ -303,14 +306,6 @@ class ChargeLocationsRepository( return PreferCacheLiveData(dbResult, apiResult, cacheSoftLimit) } - /** - * Numeric date for database limit required limit on some APIs - */ - private fun afterDate(): Long { - val cacheLimit = this.api.value!!.cacheLimit - return Instant.now().minus(cacheLimit).toEpochMilli() - } - fun getFilters(sp: StringProvider) = MediatorLiveData>>().apply { addSource(referenceData) { refData: ReferenceData? -> refData?.let { value = api.value!!.getFilters(refData, sp) } diff --git a/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt b/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt new file mode 100644 index 00000000..6e1927dc --- /dev/null +++ b/app/src/main/java/net/vonforst/evmap/storage/CleanupCacheWorker.kt @@ -0,0 +1,27 @@ +package net.vonforst.evmap.storage + +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import net.vonforst.evmap.api.createApi +import java.time.Instant + +class CleanupCacheWorker(appContext: Context, workerParams: WorkerParameters) : + CoroutineWorker(appContext, workerParams) { + override suspend fun doWork(): Result { + val db = AppDatabase.getInstance(applicationContext) + + val chargeLocations = db.chargeLocationsDao() + val savedRegionDao = db.savedRegionDao() + val now = Instant.now() + + val dataSources = listOf("openchargemap", "goingelectric") + for (dataSource in dataSources) { + val api = createApi(dataSource, applicationContext) + val limit = now.minus(api.cacheLimit).toEpochMilli() + chargeLocations.deleteOutdatedIfNotFavorite(dataSource, limit) + savedRegionDao.deleteOutdated(dataSource, limit) + } + return Result.success() + } +} \ No newline at end of file