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 3f82c5cab167fd5bb9177008c721015f1d8c7d40..d04dc5137d1dc33c3eb31577ef33fade451f4594 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
@@ -82,11 +82,12 @@ class DownloadDiagnosisKeysTask @Inject constructor(
 
             if (wasLastDetectionPerformedRecently(now, exposureConfig, trackedExposureDetections)) {
                 // At most one detection every 6h
+                Timber.tag(TAG).i("task aborted, because detection was performed recently")
                 return object : Task.Result {}
             }
 
             if (hasRecentDetectionAndNoNewFiles(now, keySyncResult, trackedExposureDetections)) {
-                //  Last check was within 24h, and there are no new files.
+                Timber.tag(TAG).i("task aborted, last check was within 24h, and there are no new files")
                 return object : Task.Result {}
             }
 
@@ -104,13 +105,14 @@ class DownloadDiagnosisKeysTask @Inject constructor(
             val isSubmissionSuccessful = enfClient.provideDiagnosisKeys(availableKeyFiles)
             Timber.tag(TAG).d("Diagnosis Keys provided (success=%s)", isSubmissionSuccessful)
 
-            internalProgress.send(Progress.ApiSubmissionFinished)
-            throwIfCancelled()
-
+            // EXPOSUREAPP-3878 write timestamp immediately after submission,
+            // so that progress observers can rely on a clean app state
             if (isSubmissionSuccessful) {
                 saveTimestamp(currentDate, rollbackItems)
             }
 
+            internalProgress.send(Progress.ApiSubmissionFinished)
+
             return object : Task.Result {}
         } catch (error: Exception) {
             Timber.tag(TAG).e(error)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt
index ad63bbb134ffc3583c9fea34bc4c31e1ee2cb724..a15a2fa6969f165ac04109a4a55e3022a8bf878a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncTool.kt
@@ -11,7 +11,6 @@ import de.rki.coronawarnapp.diagnosiskeys.storage.CachedKeyInfo.Type
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
 import de.rki.coronawarnapp.storage.DeviceStorage
 import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDate
-import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalTime
 import de.rki.coronawarnapp.util.TimeStamper
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import kotlinx.coroutines.CoroutineScope
@@ -19,6 +18,7 @@ import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.async
 import kotlinx.coroutines.awaitAll
 import kotlinx.coroutines.withContext
+import org.joda.time.DateTimeZone
 import org.joda.time.Instant
 import org.joda.time.LocalDate
 import org.joda.time.LocalTime
@@ -117,10 +117,10 @@ class HourPackageSyncTool @Inject constructor(
 
     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
     internal fun expectNewHourPackages(cachedHours: List<CachedKey>, now: Instant): Boolean {
-        val previousHour = now.toLocalTime().minusHours(1)
-        val newestHour = cachedHours.map { it.info.toDateTime() }.maxOrNull()?.toLocalTime()
+        val today = now.toDateTime(DateTimeZone.UTC)
+        val newestHour = cachedHours.map { it.info.toDateTime() }.maxOrNull()
 
-        return previousHour.hourOfDay != newestHour?.hourOfDay
+        return today.minusHours(1).hourOfDay != newestHour?.hourOfDay || today.toLocalDate() != newestHour.toLocalDate()
     }
 
     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt
index 46499c31230bf37e06c79f5c124a5e02f9f61215..767788b052571ee50d306089dec02aba0a7513d6 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/diagnosiskeys/download/KeyPackageSyncSettings.kt
@@ -1,9 +1,11 @@
 package de.rki.coronawarnapp.diagnosiskeys.download
 
+import android.annotation.SuppressLint
 import android.content.Context
 import com.google.gson.Gson
 import de.rki.coronawarnapp.util.di.AppContext
 import de.rki.coronawarnapp.util.preferences.FlowPreference
+import de.rki.coronawarnapp.util.preferences.clearAndNotify
 import de.rki.coronawarnapp.util.serialization.BaseGson
 import org.joda.time.Instant
 import javax.inject.Inject
@@ -32,6 +34,11 @@ class KeyPackageSyncSettings @Inject constructor(
         writer = FlowPreference.gsonWriter(gson)
     )
 
+    @SuppressLint("ApplySharedPref")
+    fun clear() {
+        prefs.clearAndNotify()
+    }
+
     data class LastDownload(
         val startedAt: Instant,
         val finishedAt: Instant? = null,
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt
index 2c55673ffcd5040d3f55d3f9977cc7910c730769..909a66247fd7405a3239631942052de2892add21 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/DefaultExposureDetectionTracker.kt
@@ -161,6 +161,13 @@ class DefaultExposureDetectionTracker @Inject constructor(
         }
     }
 
+    override fun clear() {
+        Timber.i("clear()")
+        detectionStates.updateSafely {
+            emptyMap()
+        }
+    }
+
     companion object {
         private const val TAG = "DefaultExposureDetectionTracker"
         private const val MAX_ENTRY_SIZE = 5
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTracker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTracker.kt
index 1f0740acda63411295131ab734d60b5865a38ae5..0d6a6e86b50ea87bc3d58913e6773f339b9f410a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTracker.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/nearby/modules/detectiontracker/ExposureDetectionTracker.kt
@@ -8,4 +8,6 @@ interface ExposureDetectionTracker {
     fun trackNewExposureDetection(identifier: String)
 
     fun finishExposureDetection(identifier: String? = null, result: TrackedExposureDetection.Result)
+
+    fun clear()
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt
index f8a0ea1ba9b071b79fa8cee41c0785dd76600598..fd533993e2ecbee697a3ec5fc5c2215ce056b7c1 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt
@@ -383,46 +383,24 @@ object LocalData {
      * SERVER FETCH DATA
      ****************************************************/
 
-    /**
-     * Gets the last time the server fetched the diagnosis keys from the server as Date object
-     * from the EncryptedSharedPrefs
-     *
-     * @return timestamp as Date
-     */
-    // TODO should be changed to Long as well to align with other timestamps
-    fun lastTimeDiagnosisKeysFromServerFetch(): Date? {
-        val time = getSharedPreferenceInstance().getLong(
-            CoronaWarnApplication.getAppContext()
-                .getString(R.string.preference_timestamp_diagnosis_keys_fetch),
-            0L
-        )
-        if (time == 0L) return null
-
-        return Date(time)
+    private val dateMapperForFetchTime: (Long) -> Date? = {
+        if (it != 0L) Date(it) else null
     }
 
-    fun lastTimeDiagnosisKeysFromServerFetchFlow() =
+    private val lastTimeDiagnosisKeysFetchedFlowPref by lazy {
         getSharedPreferenceInstance()
-            .createFlowPreference<Long?>(CoronaWarnApplication.getAppContext()
-                .getString(R.string.preference_timestamp_diagnosis_keys_fetch), 0L).flow
-            .map { if (it != null && it != 0L) Date(it) else null }
-
-    /**
-     * Sets the last time the server fetched the diagnosis keys from the server as Date object
-     * from the EncryptedSharedPrefs
-     *
-     * @param value timestamp as Date
-     */
-    fun lastTimeDiagnosisKeysFromServerFetch(value: Date?) {
-        getSharedPreferenceInstance().edit(true) {
-            putLong(
-                CoronaWarnApplication.getAppContext()
-                    .getString(R.string.preference_timestamp_diagnosis_keys_fetch),
-                value?.time ?: 0L
-            )
-        }
+            .createFlowPreference<Long>(key = "preference_timestamp_diagnosis_keys_fetch", 0L)
     }
 
+    fun lastTimeDiagnosisKeysFromServerFetchFlow() = lastTimeDiagnosisKeysFetchedFlowPref.flow
+        .map { dateMapperForFetchTime(it) }
+
+    fun lastTimeDiagnosisKeysFromServerFetch() =
+        dateMapperForFetchTime(lastTimeDiagnosisKeysFetchedFlowPref.value)
+
+    fun lastTimeDiagnosisKeysFromServerFetch(value: Date?) =
+        lastTimeDiagnosisKeysFetchedFlowPref.update { value?.time ?: 0L }
+
     /**
      * Gets the last time of successful risk level calculation as long
      * from the EncryptedSharedPrefs
@@ -707,4 +685,8 @@ object LocalData {
                 putBoolean(PREFERENCE_INTEROPERABILITY_IS_USED_AT_LEAST_ONCE, value)
             }
         }
+
+    fun clear() {
+        lastTimeDiagnosisKeysFetchedFlowPref.update { 0L }
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
index 86690e22520a4689a14f591cf5e5edab61ef853a..fd1064bbfef209742a3e763e9ecd386543311e80 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt
@@ -22,8 +22,11 @@ package de.rki.coronawarnapp.util
 import android.annotation.SuppressLint
 import android.content.Context
 import de.rki.coronawarnapp.appconfig.AppConfigProvider
+import de.rki.coronawarnapp.diagnosiskeys.download.KeyPackageSyncSettings
 import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository
+import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker
 import de.rki.coronawarnapp.storage.AppDatabase
+import de.rki.coronawarnapp.storage.LocalData
 import de.rki.coronawarnapp.storage.RiskLevelRepository
 import de.rki.coronawarnapp.storage.SubmissionRepository
 import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository
@@ -43,7 +46,9 @@ class DataReset @Inject constructor(
     @AppContext private val context: Context,
     private val keyCacheRepository: KeyCacheRepository,
     private val appConfigProvider: AppConfigProvider,
-    private val interoperabilityRepository: InteroperabilityRepository
+    private val interoperabilityRepository: InteroperabilityRepository,
+    private val exposureDetectionTracker: ExposureDetectionTracker,
+    private val keyPackageSyncSettings: KeyPackageSyncSettings
 ) {
 
     private val mutex = Mutex()
@@ -56,6 +61,8 @@ class DataReset @Inject constructor(
         Timber.w("CWA LOCAL DATA DELETION INITIATED.")
         // Database Reset
         AppDatabase.reset(context)
+        // Because LocalData does not behave like a normal shared preference
+        LocalData.clear()
         // Shared Preferences Reset
         SecurityHelper.resetSharedPrefs()
         // Reset the current risk level stored in LiveData
@@ -65,6 +72,8 @@ class DataReset @Inject constructor(
         keyCacheRepository.clear()
         appConfigProvider.clear()
         interoperabilityRepository.clear()
+        exposureDetectionTracker.clear()
+        keyPackageSyncSettings.clear()
         Timber.w("CWA LOCAL DATA DELETION COMPLETED.")
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/FlowPreference.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/FlowPreference.kt
index c64cbedfde89f3c164c26e3eb1ea2204102d2bd3..2e97359373b6de42a333ade72b7b4542c5e42a73 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/FlowPreference.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/FlowPreference.kt
@@ -6,6 +6,7 @@ import com.google.gson.Gson
 import de.rki.coronawarnapp.util.serialization.fromJson
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
+import timber.log.Timber
 
 class FlowPreference<T> constructor(
     private val preferences: SharedPreferences,
@@ -17,6 +18,21 @@ class FlowPreference<T> constructor(
     private val flowInternal = MutableStateFlow(internalValue)
     val flow: Flow<T> = flowInternal
 
+    private val preferenceChangeListener =
+        SharedPreferences.OnSharedPreferenceChangeListener { changedPrefs, changedKey ->
+            if (changedKey != key) return@OnSharedPreferenceChangeListener
+
+            val newValue = reader(changedPrefs, changedKey)
+            val currentvalue = flowInternal.value
+            if (currentvalue != newValue && flowInternal.compareAndSet(currentvalue, newValue)) {
+                Timber.v("%s:%s changed to %s", changedPrefs, changedKey, newValue)
+            }
+        }
+
+    init {
+        preferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
+    }
+
     private var internalValue: T
         get() = reader(preferences, key)
         set(newValue) {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/SharedPreferenceExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/SharedPreferenceExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0469b3840d2b9417a4ad728314f57cfa871a63ec
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/preferences/SharedPreferenceExtensions.kt
@@ -0,0 +1,17 @@
+package de.rki.coronawarnapp.util.preferences
+
+import android.content.SharedPreferences
+import androidx.core.content.edit
+import timber.log.Timber
+
+fun SharedPreferences.clearAndNotify() {
+    val currentKeys = this.all.keys.toSet()
+    Timber.v("%s clearAndNotify(): %s", this, currentKeys)
+    edit {
+        currentKeys.forEach { remove(it) }
+    }
+    // Clear does not notify anyone using registerOnSharedPreferenceChangeListener
+    edit(commit = true) {
+        clear()
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt
index 370ab58fd4ce02e2358bc1dd9f66557020403546..c1c145e4965c2cd874b65a4c107f0976e59557dd 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/SecurityHelper.kt
@@ -27,6 +27,7 @@ import androidx.annotation.VisibleForTesting
 import de.rki.coronawarnapp.exception.CwaSecurityException
 import de.rki.coronawarnapp.util.di.AppInjector
 import de.rki.coronawarnapp.util.di.ApplicationComponent
+import de.rki.coronawarnapp.util.preferences.clearAndNotify
 import de.rki.coronawarnapp.util.security.SecurityConstants.CWA_APP_SQLITE_DB_PW
 import de.rki.coronawarnapp.util.security.SecurityConstants.DB_PASSWORD_MAX_LENGTH
 import de.rki.coronawarnapp.util.security.SecurityConstants.DB_PASSWORD_MIN_LENGTH
@@ -80,7 +81,7 @@ object SecurityHelper {
 
     @SuppressLint("ApplySharedPref")
     fun resetSharedPrefs() {
-        globalEncryptedSharedPreferencesInstance.edit().clear().commit()
+        globalEncryptedSharedPreferencesInstance.clearAndNotify()
     }
 
     private fun getStoredDbPassword(): ByteArray? =
diff --git a/Corona-Warn-App/src/main/res/values-bg/strings.xml b/Corona-Warn-App/src/main/res/values-bg/strings.xml
index 03b2b1f7a0f2b3c5313198d83369a2a978d274c4..469ac6b4b49c3c138f8703f8e2d5db12bedf9726 100644
--- a/Corona-Warn-App/src/main/res/values-bg/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-bg/strings.xml
@@ -20,8 +20,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml
index f8eaa6a2e06e2b1893ce39c6db4ba5b014fb3e53..0d7bf64ba7a61a27cdc2087dc10ef61deb287d8a 100644
--- a/Corona-Warn-App/src/main/res/values-de/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/strings.xml
@@ -21,8 +21,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/main/res/values-en/strings.xml b/Corona-Warn-App/src/main/res/values-en/strings.xml
index 6b9d4ca42f8c7a9b242d2e1f1862b7caa903e1df..a5e01cdeff99cac3ee50b5509b42354aebefa547 100644
--- a/Corona-Warn-App/src/main/res/values-en/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-en/strings.xml
@@ -20,8 +20,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/main/res/values-pl/strings.xml b/Corona-Warn-App/src/main/res/values-pl/strings.xml
index e6583c9af191c2f552c6c04953312988958f0e7f..eded35c4be1a262535dce655302b0fba532e50e5 100644
--- a/Corona-Warn-App/src/main/res/values-pl/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-pl/strings.xml
@@ -20,8 +20,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/main/res/values-ro/strings.xml b/Corona-Warn-App/src/main/res/values-ro/strings.xml
index 3bcca1384b7d4d00442d9525c768e0273cbdac85..0c5a9e4f4e0e8f0252b4a82e4df7ddcaa07dac65 100644
--- a/Corona-Warn-App/src/main/res/values-ro/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml
@@ -20,8 +20,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/main/res/values-tr/strings.xml b/Corona-Warn-App/src/main/res/values-tr/strings.xml
index 2af4f639b65779e8db88d69aec94612aa733ebb8..78dc5a455f852fb5ba62c532be47921025386790 100644
--- a/Corona-Warn-App/src/main/res/values-tr/strings.xml
+++ b/Corona-Warn-App/src/main/res/values-tr/strings.xml
@@ -20,8 +20,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index b76608adbad8e9fdfeec178b7849432f9c1ab914..5fe660c6b3eb46767911671628ad782883f3125f 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -21,8 +21,6 @@
     <!-- NOTR -->
     <string name="preference_tracing"><xliff:g id="preference">"preference_tracing"</xliff:g></string>
     <!-- NOTR -->
-    <string name="preference_timestamp_diagnosis_keys_fetch"><xliff:g id="preference">"preference_timestamp_diagnosis_keys_fetch"</xliff:g></string>
-    <!-- NOTR -->
     <string name="preference_timestamp_manual_diagnosis_keys_retrieval"><xliff:g id="preference">"preference_timestamp_manual_diagnosis_keys_retrieval"</xliff:g></string>
     <!-- NOTR -->
     <string name="preference_background_job_allowed"><xliff:g id="preference">"preference_background_job_enabled"</xliff:g></string>
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt
index 062d1bfb4c1fbf45e9fb29d274fbd97c0c7ee93a..f6dae8e55b255f6e8cb3d71bd3c8a7577cb88466 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/diagnosiskeys/download/HourPackageSyncToolTest.kt
@@ -204,6 +204,20 @@ class HourPackageSyncToolTest : CommonSyncToolTest() {
         instance.expectNewHourPackages(listOf(cachedKey1, cachedKey2), now) shouldBe true
     }
 
+    @Test
+    fun `EXPECT_NEW_HOUR_PACKAGES does not get confused by same hour on next day`() = runBlockingTest {
+        val cachedKey1 = mockk<CachedKey>().apply {
+            every { info } returns mockk<CachedKeyInfo>().apply {
+                every { toDateTime() } returns Instant.parse("2020-01-01T00:00:03.000Z").toDateTime(DateTimeZone.UTC)
+            }
+        }
+
+        val instance = createInstance()
+
+        val now = Instant.parse("2020-01-02T01:00:03.000Z")
+        instance.expectNewHourPackages(listOf(cachedKey1), now) shouldBe true
+    }
+
     @Test
     fun `if keys were revoked skip the EXPECT packages check`() = runBlockingTest {
         every { timeStamper.nowUTC } returns Instant.parse("2020-01-04T02:00:00.000Z")
diff --git a/Corona-Warn-App/src/test/java/testhelpers/preferences/MockFlowPreference.kt b/Corona-Warn-App/src/test/java/testhelpers/preferences/MockFlowPreference.kt
index 33d46578e1a956c645d549edc3f793d2fc9b27df..0b855e1b9938ed9d47650a26c85ba5bbe9ba4927 100644
--- a/Corona-Warn-App/src/test/java/testhelpers/preferences/MockFlowPreference.kt
+++ b/Corona-Warn-App/src/test/java/testhelpers/preferences/MockFlowPreference.kt
@@ -16,5 +16,6 @@ fun <T> mockFlowPreference(
         val updateCall = arg<(T) -> T>(0)
         flow.value = updateCall(flow.value)
     }
+
     return instance
 }
diff --git a/Corona-Warn-App/src/test/java/testhelpers/preferences/MockSharedPreferences.kt b/Corona-Warn-App/src/test/java/testhelpers/preferences/MockSharedPreferences.kt
index a6294b00f54bcdbc96ab6bd18195389fc1a79e51..c094e560e5401f80bbf7bedff36af3537cc8a67e 100644
--- a/Corona-Warn-App/src/test/java/testhelpers/preferences/MockSharedPreferences.kt
+++ b/Corona-Warn-App/src/test/java/testhelpers/preferences/MockSharedPreferences.kt
@@ -3,6 +3,7 @@ package testhelpers.preferences
 import android.content.SharedPreferences
 
 class MockSharedPreferences : SharedPreferences {
+    private val listeners = mutableListOf<SharedPreferences.OnSharedPreferenceChangeListener>()
     private val dataMap = mutableMapOf<String, Any>()
     val dataMapPeek: Map<String, Any>
         get() = dataMap.toMap()
@@ -36,12 +37,12 @@ class MockSharedPreferences : SharedPreferences {
         dataMap.putAll(newData)
     }
 
-    override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) {
-        throw NotImplementedError()
+    override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
+        listeners.add(listener)
     }
 
-    override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) {
-        throw NotImplementedError()
+    override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
+        listeners.remove(listener)
     }
 
     private fun createEditor(
diff --git a/gradle.properties b/gradle.properties
index 3802281e4f1879b6ddca5ff34f9f5b3376baaee3..2974345801f04919bc39c70e43305c810b323c9e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -20,4 +20,4 @@ org.gradle.dependency.verification.console=verbose
 VERSION_MAJOR=1
 VERSION_MINOR=8
 VERSION_PATCH=0
-VERSION_BUILD=7
+VERSION_BUILD=1