From 22c9702aaf782c09b7539ba89e5c9bc597e78bd2 Mon Sep 17 00:00:00 2001 From: Kolya Opahle <k.opahle@sap.com> Date: Thu, 30 Jul 2020 17:59:38 +0200 Subject: [PATCH] Fix looping background restricition notification in onboarding (EXPOSUREAPP-1962) (#950) * added call to navigateToMain before opening the app settings * Moved checks for background job notification to main activity * refined background dialogs Co-authored-by: Philipp Woessner <philipp.woessner@sap.com> --- .../ui/main/MainFragment.kt | 32 ------- .../de/rki/coronawarnapp/storage/LocalData.kt | 50 ++++++----- .../rki/coronawarnapp/ui/main/MainActivity.kt | 76 +++++++++++++++++ .../OnboardingNotificationsFragment.kt | 84 +------------------ .../coronawarnapp/util/ConnectivityHelper.kt | 22 ++++- .../src/main/res/values-bg/strings.xml | 2 + .../src/main/res/values-de/strings.xml | 2 + .../src/main/res/values-en/strings.xml | 2 + .../src/main/res/values-pl/strings.xml | 2 + .../src/main/res/values-ro/strings.xml | 2 + .../src/main/res/values-tr/strings.xml | 2 + .../src/main/res/values/strings.xml | 4 +- 12 files changed, 133 insertions(+), 147 deletions(-) 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 f0707b0ae..ec73b7aa8 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 e952683d9..889ab5669 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 afb0a44be..21aab5b52 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 78b41cb72..c6768a15f 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 b111fec8a..da39aa39b 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 94a189e86..01d0307c6 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 3249261a3..803710aef 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 b9a428cc1..9a82b6a5e 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 12e66aa35..61cd21496 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 910694562..f67be6a34 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 de46267b6..9e009842d 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 cf22866d9..92c978486 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 -- GitLab