diff --git a/Corona-Warn-App/src/device/java/de.rki.coronawarnapp/ui/main/MainFragment.kt b/Corona-Warn-App/src/device/java/de.rki.coronawarnapp/ui/main/MainFragment.kt index f0707b0aebe71c41ca1687844b1f4fd9be37e245..ec73b7aa81b7d70e37e0512d2da936a714f5453d 100644 --- a/Corona-Warn-App/src/device/java/de.rki.coronawarnapp/ui/main/MainFragment.kt +++ b/Corona-Warn-App/src/device/java/de.rki.coronawarnapp/ui/main/MainFragment.kt @@ -21,7 +21,6 @@ import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.ExternalActionHelper -import de.rki.coronawarnapp.util.PowerManagementHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -72,7 +71,6 @@ class MainFragment : Fragment() { setContentDescription() showOneTimeTracingExplanationDialog() - showEnergyOptimizedExplanationDialog() } override fun onResume() { @@ -220,34 +218,4 @@ class MainFragment : Fragment() { } } } - - private fun showEnergyOptimizedExplanationDialog() { - - // check if the dialog explaining the effects of energy saver mode were already shown and if energy saver is enabled - if (!LocalData.energyOptimizedExplanationDialogWasShown() && !PowerManagementHelper.isIgnoringBatteryOptimizations(requireActivity())) { - lifecycleScope.launch { - - withContext(Dispatchers.Main) { - - val dialog = DialogHelper.DialogInstance( - requireActivity(), - R.string.onboarding_energy_optimized_dialog_headline, - R.string.onboarding_energy_optimized_dialog_body, - R.string.onboarding_energy_optimized_dialog_button_positive, - R.string.onboarding_energy_optimized_dialog_button_negative, - false, - { - // go to battery optimization - ExternalActionHelper.toBatteryOptimizationSettings(requireContext()) - LocalData.energyOptimizedExplanationDialogWasShown(true) - }, - { - // keep battery optimization enabled - LocalData.energyOptimizedExplanationDialogWasShown(true) - }) - DialogHelper.showDialog(dialog) - } - } - } - } } 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 e952683d958dce1eae1b786e5462bb75bec79593..889ab566942df188a9780255f3301afafc45daa3 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 @@ -73,6 +73,30 @@ object LocalData { .getString(R.string.preference_onboarding_completed_timestamp), value ) } + + /** + * Gets the boolean if the user has received the background warning + * from the EncryptedSharedPrefs + * + * @return boolean if background warning was shown + */ + fun isBackgroundCheckDone(): Boolean = getSharedPreferenceInstance().getBoolean( + CoronaWarnApplication.getAppContext().getString(R.string.preference_background_check_done), + false + ) + + /** + * Sets the boolean if the user has received the background warning + * from the EncryptedSharedPrefs + * + * @param value boolean if background warning was shown + */ + fun isBackgroundCheckDone(value: Boolean) = getSharedPreferenceInstance().edit(true) { + putBoolean( + CoronaWarnApplication.getAppContext() + .getString(R.string.preference_background_check_done), value + ) + } /**************************************************** * TRACING DATA ****************************************************/ @@ -328,32 +352,6 @@ object LocalData { ) } - /** - * Gets the boolean if the user has seen the energy saving explanation dialog - * from the EncryptedSharedPrefs - * - * @return boolean if user has seen the energy saving explanation dialog - */ - fun energyOptimizedExplanationDialogWasShown(): Boolean = getSharedPreferenceInstance().getBoolean( - CoronaWarnApplication.getAppContext() - .getString(R.string.preference_energy_optimized_explanation_shown), - false - ) - - /** - * Sets the boolean if the user has seen the energy saving explanation dialog - * from the EncryptedSharedPrefs - * - * @param value boolean if onboarding in relation to energy saving was completed - */ - fun energyOptimizedExplanationDialogWasShown(value: Boolean) = - getSharedPreferenceInstance().edit(true) { - putBoolean( - CoronaWarnApplication.getAppContext() - .getString(R.string.preference_energy_optimized_explanation_shown), value - ) - } - /**************************************************** * SERVER FETCH DATA ****************************************************/ diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt index afb0a44be48cac15f526bdfff3843400c2252eb4..21aab5b528003702507158f378fe33df0b2bb59b 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainActivity.kt @@ -2,14 +2,20 @@ package de.rki.coronawarnapp.ui.main import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle +import android.provider.Settings import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.lifecycle.ViewModelProviders import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.util.ConnectivityHelper +import de.rki.coronawarnapp.util.DialogHelper +import de.rki.coronawarnapp.util.ExternalActionHelper +import de.rki.coronawarnapp.util.PowerManagementHelper import de.rki.coronawarnapp.worker.BackgroundWorkScheduler /** @@ -89,6 +95,76 @@ class MainActivity : AppCompatActivity() { ConnectivityHelper.registerLocationStatusCallback(this, callbackLocation) settingsViewModel.updateBackgroundJobEnabled(ConnectivityHelper.isBackgroundJobEnabled(this)) scheduleWork() + checkShouldDisplayBackgroundWarning() + } + + private fun showEnergyOptimizedEnabledForBackground() { + val dialog = DialogHelper.DialogInstance( + this, + R.string.onboarding_energy_optimized_dialog_headline, + R.string.onboarding_energy_optimized_dialog_body, + R.string.onboarding_energy_optimized_dialog_button_positive, + R.string.onboarding_energy_optimized_dialog_button_negative, + false, { + // go to battery optimization + ExternalActionHelper.disableBatteryOptimizations(this) + }, { + // keep battery optimization enabled + showManualCheckingRequiredDialog() + }) + DialogHelper.showDialog(dialog) + } + + private fun checkForEnergyOptimizedEnabled() { + if (!PowerManagementHelper.isIgnoringBatteryOptimizations(this)) { + showEnergyOptimizedEnabledForBackground() + } + } + + private fun showManualCheckingRequiredDialog() { + val dialog = DialogHelper.DialogInstance( + this, + R.string.onboarding_manual_required_dialog_headline, + R.string.onboarding_manual_required_dialog_body, + R.string.onboarding_manual_required_dialog_button, + null, + false + ) + DialogHelper.showDialog(dialog) + } + + private fun showBackgroundJobDisabledNotification() { + val dialog = DialogHelper.DialogInstance( + this, + R.string.onboarding_background_fetch_dialog_headline, + R.string.onboarding_background_fetch_dialog_body, + R.string.onboarding_background_fetch_dialog_button_positive, + R.string.onboarding_background_fetch_dialog_button_negative, + false, { + val intent = Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.fromParts("package", packageName, null) + ) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(intent) + // show battery optimization system dialog after background processing dialog + checkForEnergyOptimizedEnabled() + }, { + // declined, show additional dialog explaining manual risk calculation + showManualCheckingRequiredDialog() + }) + DialogHelper.showDialog(dialog) + } + + private fun checkShouldDisplayBackgroundWarning() { + if (!LocalData.isBackgroundCheckDone()) { + LocalData.isBackgroundCheckDone(true) + if (ConnectivityHelper.isBackgroundRestricted(this)) { + showBackgroundJobDisabledNotification() + } else { + checkForEnergyOptimizedEnabled() + } + } } /** diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingNotificationsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingNotificationsFragment.kt index 78b41cb7262fc03d4538e919ec7ec4070cf34a3c..c6768a15f48d752bc6b7ce8ba8022a4eee645790 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingNotificationsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingNotificationsFragment.kt @@ -1,9 +1,6 @@ package de.rki.coronawarnapp.ui.onboarding -import android.content.Intent -import android.net.Uri import android.os.Bundle -import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -11,13 +8,7 @@ import android.view.accessibility.AccessibilityEvent import androidx.appcompat.app.AlertDialog import androidx.core.app.NotificationManagerCompat import androidx.fragment.app.Fragment -import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentOnboardingNotificationsBinding -import de.rki.coronawarnapp.storage.LocalData -import de.rki.coronawarnapp.util.ConnectivityHelper -import de.rki.coronawarnapp.util.DialogHelper -import de.rki.coronawarnapp.util.ExternalActionHelper -import de.rki.coronawarnapp.util.PowerManagementHelper /** * This fragment ask the user if he wants to get notifications and finishes the onboarding afterwards. @@ -59,86 +50,13 @@ class OnboardingNotificationsFragment : Fragment() { private fun setButtonOnClickListener() { binding.onboardingButtonNext.setOnClickListener { - checkForBackgroundJobDisabled() + navigateToMain() } binding.onboardingButtonBack.buttonIcon.setOnClickListener { (activity as OnboardingActivity).goBack() } } - private fun checkForBackgroundJobDisabled() { - if (!ConnectivityHelper.isBackgroundJobEnabled(requireActivity())) { - showBackgroundJobDisabledNotification() - } else { - checkForEnergyOptimizedEnabled() - } - } - - private fun checkForEnergyOptimizedEnabled() { - if (!PowerManagementHelper.isIgnoringBatteryOptimizations(requireActivity())) { - showEnergyOptimizedEnabledForBackground() - } else { - navigateToMain() - } - } - - private fun showBackgroundJobDisabledNotification() { - val dialog = DialogHelper.DialogInstance( - requireActivity(), - R.string.onboarding_background_fetch_dialog_headline, - R.string.onboarding_background_fetch_dialog_body, - R.string.onboarding_background_fetch_dialog_button_positive, - R.string.onboarding_background_fetch_dialog_button_negative, - false, { - val intent = Intent( - ACTION_APPLICATION_DETAILS_SETTINGS, - Uri.fromParts("package", requireContext().packageName, null) - ) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) - // show battery optimization system dialog after background processing dialog - checkForEnergyOptimizedEnabled() - }, { - // declined, show additional dialog explaining manual risk calculation - showManualCheckingRequiredDialog() - }) - DialogHelper.showDialog(dialog) - } - - private fun showEnergyOptimizedEnabledForBackground() { - val dialog = DialogHelper.DialogInstance( - requireActivity(), - R.string.onboarding_energy_optimized_dialog_headline, - R.string.onboarding_energy_optimized_dialog_body, - R.string.onboarding_energy_optimized_dialog_button_positive, - R.string.onboarding_energy_optimized_dialog_button_negative, - false, { - // go to battery optimization - ExternalActionHelper.toBatteryOptimizationSettings(requireContext()) - LocalData.energyOptimizedExplanationDialogWasShown(true) - navigateToMain() - }, { - // keep battery optimization enabled - LocalData.energyOptimizedExplanationDialogWasShown(true) - showManualCheckingRequiredDialog() - }) - DialogHelper.showDialog(dialog) - } - - private fun showManualCheckingRequiredDialog() { - val dialog = DialogHelper.DialogInstance( - requireActivity(), - R.string.onboarding_manual_required_dialog_headline, - R.string.onboarding_manual_required_dialog_body, - R.string.onboarding_manual_required_dialog_button, - null, - false, { - navigateToMain() - } - ) - DialogHelper.showDialog(dialog) - } - private fun navigateToMain() { (requireActivity() as OnboardingActivity).completeOnboarding() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt index b111fec8a66b7a7f10267425a8a4a52aef88d454..da39aa39b7b2bbeb14b7f6edbb2611ea58d57bf5 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ConnectivityHelper.kt @@ -191,14 +191,28 @@ object ConnectivityHelper { * @param context the context * * @return Boolean + */ + fun isBackgroundRestricted(context: Context): Boolean { + val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + activityManager.isBackgroundRestricted + } else false + } + + /** + * Background jobs are enabled only if the battery optimization is enabled and + * the background activity is not restricted + * + * @param context the context + * + * @return Boolean * * @see isBackgroundRestricted */ fun isBackgroundJobEnabled(context: Context): Boolean { - val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - !activityManager.isBackgroundRestricted && PowerManagementHelper.isIgnoringBatteryOptimizations(context) - } else true + return !isBackgroundRestricted(context) && PowerManagementHelper.isIgnoringBatteryOptimizations( + context + ) } /** 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 94a189e86136a8a866b8f1044ea25d392cf30190..01d0307c693eff7bc5b1d315d7ae957cfe2a36fc 100644 --- a/Corona-Warn-App/src/main/res/values-bg/strings.xml +++ b/Corona-Warn-App/src/main/res/values-bg/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</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 3249261a39e3ff8c4261024b136190ceea04e34e..803710aef0e9151e1c7d9cc9c14442d4bd1e5a7e 100644 --- a/Corona-Warn-App/src/main/res/values-de/strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</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 b9a428cc12108e66d62a3ffeeca7738e374fd5c0..9a82b6a5e7643e3a5b5b23dca2f763c407fff96c 100644 --- a/Corona-Warn-App/src/main/res/values-en/strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</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 12e66aa35ebbe50642c3a4313542fd0a4db3ed12..61cd21496e253b03dad321f07cb4d4c3df63f5c8 100644 --- a/Corona-Warn-App/src/main/res/values-pl/strings.xml +++ b/Corona-Warn-App/src/main/res/values-pl/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</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 91069456291e3af2e0ed756eec4118d09f1c87c2..f67be6a3433030970df1b2fc5d6297019ad9b015 100644 --- a/Corona-Warn-App/src/main/res/values-ro/strings.xml +++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</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 de46267b6bfc33e615e743a9a5c24442a50c3f13..9e009842d6e07d43dd7090fcdf9439aa8fc2e3b0 100644 --- a/Corona-Warn-App/src/main/res/values-tr/strings.xml +++ b/Corona-Warn-App/src/main/res/values-tr/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</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 cf22866d907dbb877e6d3f9ac88b7dc33fba0f96..92c97848677b6e78fb5a934d6c133f17f97dd5ef 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -12,6 +12,8 @@ <!-- NOTR --> <string name="preference_onboarding_completed_timestamp"><xliff:g id="preference">"preference_onboarding_completed_timestamp"</xliff:g></string> <!-- NOTR --> + <string name="preference_background_check_done"><xliff:g id="preference">"preference_background_check_done"</xliff:g></string> + <!-- NOTR --> <string name="preference_reset_app"><xliff:g id="preference">"preference_reset_app"</xliff:g></string> <!-- NOTR --> <string name="preference_only_wifi"><xliff:g id="preference">"preference_only_wifi"</xliff:g></string> @@ -73,8 +75,6 @@ <string name="preference_risk_days_explanation_shown"><xliff:g id="preference">"preference_risk_days_explanation_shown"</xliff:g></string> <!-- NOTR --> <string name="preference_background_notification"><xliff:g id="preference">"preference_background_notification"</xliff:g></string> - <!-- NOTR --> - <string name="preference_energy_optimized_explanation_shown"><xliff:g id="preference">"preference_energy_optimized_explanation_shown"</xliff:g></string> <!-- #################################### Generics