diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt
index 870c80617d260aafb04eedc58c461b86ae003372..608b952e46cd31a5c78f0ceca22c5bb1cbceb363 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/DownloadDiagnosisKeysTask.kt
@@ -15,13 +15,10 @@ import de.rki.coronawarnapp.task.TaskFactory
 import de.rki.coronawarnapp.task.TaskFactory.Config.CollisionBehavior
 import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.ui.toLazyString
-import de.rki.coronawarnapp.worker.BackgroundWorkHelper
 import kotlinx.coroutines.channels.ConflatedBroadcastChannel
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.asFlow
 import kotlinx.coroutines.flow.first
-import org.joda.time.DateTime
-import org.joda.time.DateTimeZone
 import org.joda.time.Duration
 import org.joda.time.Instant
 import timber.log.Timber
@@ -50,10 +47,6 @@ class DownloadDiagnosisKeysTask @Inject constructor(
             Timber.d("Running with arguments=%s", arguments)
             arguments as Arguments
 
-            if (arguments.withConstraints) {
-                if (!noKeysFetchedToday()) return object : Task.Result {}
-            }
-
             /**
              * Handles the case when the ENClient got disabled but the Task is still scheduled
              * in a background job. Also it acts as a failure catch in case the orchestration code did
@@ -191,25 +184,6 @@ class DownloadDiagnosisKeysTask @Inject constructor(
         }
     }
 
-    private fun noKeysFetchedToday(): Boolean {
-        val currentDate = DateTime(timeStamper.nowUTC, DateTimeZone.UTC)
-        val lastFetch = DateTime(
-            LocalData.lastTimeDiagnosisKeysFromServerFetch(),
-            DateTimeZone.UTC
-        )
-        return (LocalData.lastTimeDiagnosisKeysFromServerFetch() == null ||
-            currentDate.withTimeAtStartOfDay() != lastFetch.withTimeAtStartOfDay()).also {
-            if (it) {
-                Timber.tag(TAG)
-                    .d("No keys fetched today yet (last=%s, now=%s)", lastFetch, currentDate)
-                BackgroundWorkHelper.sendDebugNotification(
-                    "Start Task",
-                    "No keys fetched today yet \n${DateTime.now()}\nUTC: $currentDate"
-                )
-            }
-        }
-    }
-
     private fun rollback(rollbackItems: MutableList<RollbackItem>) {
         try {
             Timber.tag(TAG).d("Initiate Rollback")
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt
index 0658b10604134435f471c5ef6f351372f18bdcb0..e45cbc98f179654ac80834bbf44931a2cc1e1608 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/TracingRepository.kt
@@ -15,18 +15,20 @@ import de.rki.coronawarnapp.task.submitBlocking
 import de.rki.coronawarnapp.timer.TimerHelper
 import de.rki.coronawarnapp.tracing.TracingProgress
 import de.rki.coronawarnapp.util.ConnectivityHelper
+import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.coroutine.AppScope
 import de.rki.coronawarnapp.util.di.AppContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
-import org.joda.time.DateTime
-import org.joda.time.DateTimeZone
-import org.joda.time.Instant
+import org.joda.time.Duration
 import timber.log.Timber
 import java.util.Date
+import java.util.NoSuchElementException
 import javax.inject.Inject
 import javax.inject.Singleton
 
@@ -43,7 +45,8 @@ class TracingRepository @Inject constructor(
     @AppContext private val context: Context,
     @AppScope private val scope: CoroutineScope,
     private val taskController: TaskController,
-    enfClient: ENFClient
+    enfClient: ENFClient,
+    private val timeStamper: TimeStamper
 ) {
 
     private val internalLastTimeDiagnosisKeysFetched = MutableStateFlow<Date?>(null)
@@ -62,11 +65,9 @@ class TracingRepository @Inject constructor(
             LocalData.lastTimeDiagnosisKeysFromServerFetch()
     }
 
-    private val retrievingDiagnosisKeys = MutableStateFlow(false)
     private val internalIsRefreshing =
-        retrievingDiagnosisKeys.combine(taskController.tasks) { retrievingDiagnosisKeys, tasks ->
-            retrievingDiagnosisKeys || tasks.isRiskLevelTaskRunning()
-        }
+        taskController.tasks.map { it.isDownloadDiagnosisKeysTaskRunning() || it.isRiskLevelTaskRunning() }
+
     val tracingProgress: Flow<TracingProgress> = combine(
         internalIsRefreshing,
         enfClient.isPerformingExposureDetection()
@@ -81,6 +82,9 @@ class TracingRepository @Inject constructor(
     private fun List<TaskInfo>.isRiskLevelTaskRunning() = any {
         it.taskState.isActive && it.taskState.request.type == RiskLevelTask::class
     }
+    private fun List<TaskInfo>.isDownloadDiagnosisKeysTaskRunning() = any {
+        it.taskState.isActive && it.taskState.request.type == DownloadDiagnosisKeysTask::class
+    }
 
     /**
      * Refresh the diagnosis keys. For that isRefreshing is set to true which is displayed in the ui.
@@ -93,7 +97,6 @@ class TracingRepository @Inject constructor(
      */
     fun refreshDiagnosisKeys() {
         scope.launch {
-            retrievingDiagnosisKeys.value = true
             taskController.submitBlocking(
                 DefaultTaskRequest(
                     DownloadDiagnosisKeysTask::class,
@@ -102,7 +105,6 @@ class TracingRepository @Inject constructor(
             )
             taskController.submit(DefaultTaskRequest(RiskLevelTask::class))
             refreshLastTimeDiagnosisKeysFetchedDate()
-            retrievingDiagnosisKeys.value = false
             TimerHelper.startManualKeyRetrievalTimer()
         }
     }
@@ -126,19 +128,6 @@ class TracingRepository @Inject constructor(
      */
     // TODO temp place, this needs to go somewhere better
     fun refreshRiskLevel() {
-
-        // get the current date and the date the diagnosis keys were fetched the last time
-        val currentDate = DateTime(Instant.now(), DateTimeZone.UTC)
-        val lastFetch = DateTime(
-            LocalData.lastTimeDiagnosisKeysFromServerFetch(),
-            DateTimeZone.UTC
-        )
-
-        // check if the keys were not already retrieved today
-        val keysWereNotRetrievedToday =
-            LocalData.lastTimeDiagnosisKeysFromServerFetch() == null ||
-                currentDate.withTimeAtStartOfDay() != lastFetch.withTimeAtStartOfDay()
-
         // check if the network is enabled to make the server fetch
         val isNetworkEnabled = ConnectivityHelper.isNetworkEnabled(context)
 
@@ -146,32 +135,51 @@ class TracingRepository @Inject constructor(
         // model the keys are only fetched on button press of the user
         val isBackgroundJobEnabled = ConnectivityHelper.autoModeEnabled(context)
 
-        Timber.tag(TAG).v("Keys were not retrieved today $keysWereNotRetrievedToday")
+        val wasNotYetFetched = LocalData.lastTimeDiagnosisKeysFromServerFetch() == null
+
         Timber.tag(TAG).v("Network is enabled $isNetworkEnabled")
         Timber.tag(TAG).v("Background jobs are enabled $isBackgroundJobEnabled")
+        Timber.tag(TAG).v("Was not yet fetched from server $wasNotYetFetched")
 
-        if (keysWereNotRetrievedToday && isNetworkEnabled && isBackgroundJobEnabled) {
-            // TODO shouldn't access this directly
-            retrievingDiagnosisKeys.value = true
-
-            // start the fetching and submitting of the diagnosis keys
+        if (isNetworkEnabled && isBackgroundJobEnabled) {
             scope.launch {
-                taskController.submitBlocking(
-                    DefaultTaskRequest(
-                        DownloadDiagnosisKeysTask::class,
-                        DownloadDiagnosisKeysTask.Arguments()
+                if (wasNotYetFetched || downloadDiagnosisKeysTaskDidNotRunRecently()) {
+                    Timber.tag(TAG).v("Start the fetching and submitting of the diagnosis keys")
+
+                    taskController.submitBlocking(
+                        DefaultTaskRequest(
+                            DownloadDiagnosisKeysTask::class,
+                            DownloadDiagnosisKeysTask.Arguments()
+                        )
                     )
-                )
-                refreshLastTimeDiagnosisKeysFetchedDate()
-                TimerHelper.checkManualKeyRetrievalTimer()
+                    refreshLastTimeDiagnosisKeysFetchedDate()
+                    TimerHelper.checkManualKeyRetrievalTimer()
 
-                taskController.submit(DefaultTaskRequest(RiskLevelTask::class))
-                // TODO shouldn't access this directly
-                retrievingDiagnosisKeys.value = false
+                    taskController.submit(DefaultTaskRequest(RiskLevelTask::class))
+                }
             }
         }
     }
 
+    private suspend fun downloadDiagnosisKeysTaskDidNotRunRecently(): Boolean {
+        val currentDate = timeStamper.nowUTC
+        val taskLastFinishedAt = try {
+            taskController.tasks.first()
+                .filter { it.taskState.type == DownloadDiagnosisKeysTask::class }
+                .mapNotNull { it.taskState.finishedAt }
+                .sortedDescending()
+                .first()
+        } catch (e: NoSuchElementException) {
+            Timber.tag(TAG).v("download did not run recently - no task with a finishedAt date found")
+            return true
+        }
+
+        return currentDate.isAfter(taskLastFinishedAt.plus(Duration.standardHours(1))).also {
+            Timber.tag(TAG)
+                .v("download did not run recently: %s (last=%s, now=%s)", it, taskLastFinishedAt, currentDate)
+        }
+    }
+
     /**
      * Exposure summary
      * Refresh the following variables in TracingRepository