diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle index 384bcddf02b314d29dac1879e23857db2d623eee..c4da9b2427af1bed9279c60ca405422493902501 100644 --- a/Corona-Warn-App/build.gradle +++ b/Corona-Warn-App/build.gradle @@ -237,7 +237,8 @@ dependencies { implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.work:work-runtime-ktx:2.3.4' - implementation 'android.arch.lifecycle:extensions:1.1.1' + implementation 'android.arch.lifecycle:extensions:2.2.0' + implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0' implementation 'androidx.annotation:annotation:1.1.0' // DAGGER @@ -247,6 +248,7 @@ dependencies { kapt 'com.google.dagger:dagger-compiler:2.28.1' kapt 'com.google.dagger:dagger-android-processor:2.28.1' + // QR implementation('com.journeyapps:zxing-android-embedded:4.1.0') { transitive = false } // noinspection GradleDependency - needed for SDK 23 compatibility, in combination with com.journeyapps:zxing-android-embedded:4.1.0 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 ec73b7aa81b7d70e37e0512d2da936a714f5453d..4b2300bc5c27b440054e145844cf415acfcb9370 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 @@ -16,6 +16,7 @@ import de.rki.coronawarnapp.risk.TimeVariables import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.timer.TimerHelper import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel @@ -44,15 +45,14 @@ class MainFragment : Fragment() { private val tracingViewModel: TracingViewModel by activityViewModels() private val settingsViewModel: SettingsViewModel by activityViewModels() private val submissionViewModel: SubmissionViewModel by activityViewModels() - private var _binding: FragmentMainBinding? = null - private val binding: FragmentMainBinding get() = _binding!! + private var binding: FragmentMainBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentMainBinding.inflate(inflater) + binding = FragmentMainBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.settingsViewModel = settingsViewModel binding.submissionViewModel = submissionViewModel @@ -60,11 +60,6 @@ class MainFragment : Fragment() { return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt index ae0e2409c30d6620ca870e1c804549f3c6addb9d..15b56532f1ddd85ff49a0bf773ccead970ec028b 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestForAPIFragment.kt @@ -52,6 +52,7 @@ import de.rki.coronawarnapp.storage.ExposureSummaryRepository import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.tracing.TracingIntervalRepository import de.rki.coronawarnapp.transaction.RiskLevelTransaction +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.KeyFileHelper import de.rki.coronawarnapp.util.di.AppInjector @@ -97,8 +98,7 @@ class TestForAPIFragment : Fragment(), InternalExposureNotificationPermissionHel private lateinit var qrPagerAdapter: RecyclerView.Adapter<QRPagerAdapter.QRViewHolder> // Data and View binding - private var _binding: FragmentTestForAPIBinding? = null - private val binding: FragmentTestForAPIBinding get() = _binding!! + private var binding: FragmentTestForAPIBinding by viewLifecycle() private var lastSetCountries: List<String>? = null @@ -109,7 +109,7 @@ class TestForAPIFragment : Fragment(), InternalExposureNotificationPermissionHel ): View? { // get the binding reference by inflating it with the current layout - _binding = FragmentTestForAPIBinding.inflate(inflater) + binding = FragmentTestForAPIBinding.inflate(inflater) // set the viewmmodel variable that will be used for data binding binding.tracingViewModel = tracingViewModel @@ -121,11 +121,6 @@ class TestForAPIFragment : Fragment(), InternalExposureNotificationPermissionHel return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt index f375c7b4707a9036a921d275d37c1a0feec9368c..268a583555dcfa109ed6f2248f20ca53b19e726e 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/test/TestRiskLevelCalculationFragment.kt @@ -32,6 +32,7 @@ import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.RiskLevelRepository import de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction import de.rki.coronawarnapp.transaction.RiskLevelTransaction +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel @@ -59,8 +60,7 @@ class TestRiskLevelCalculationFragment : Fragment() { private val tracingViewModel: TracingViewModel by activityViewModels() private val settingsViewModel: SettingsViewModel by activityViewModels() private val submissionViewModel: SubmissionViewModel by activityViewModels() - private var _binding: FragmentTestRiskLevelCalculationBinding? = null - private val binding: FragmentTestRiskLevelCalculationBinding get() = _binding!! + private var binding: FragmentTestRiskLevelCalculationBinding by viewLifecycle() // reference to the client from the Google framework with the given application context private val exposureNotificationClient by lazy { @@ -72,7 +72,7 @@ class TestRiskLevelCalculationFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentTestRiskLevelCalculationBinding.inflate(inflater) + binding = FragmentTestRiskLevelCalculationBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.settingsViewModel = settingsViewModel binding.submissionViewModel = submissionViewModel @@ -80,11 +80,6 @@ class TestRiskLevelCalculationFragment : Fragment() { return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainFragment.kt b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainFragment.kt index 7565b87826f75fa39bcfb224fdeeb84b26a705c5..add678b4840fa4a359551dc0edb97f8dea0ab5c0 100644 --- a/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainFragment.kt +++ b/Corona-Warn-App/src/deviceForTesters/java/de/rki/coronawarnapp/ui/main/MainFragment.kt @@ -16,6 +16,7 @@ import de.rki.coronawarnapp.risk.TimeVariables import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.timer.TimerHelper import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel @@ -44,15 +45,14 @@ class MainFragment : Fragment() { private val tracingViewModel: TracingViewModel by activityViewModels() private val settingsViewModel: SettingsViewModel by activityViewModels() private val submissionViewModel: SubmissionViewModel by activityViewModels() - private var _binding: FragmentMainBinding? = null - private val binding: FragmentMainBinding get() = _binding!! + private var binding: FragmentMainBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentMainBinding.inflate(inflater) + binding = FragmentMainBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.settingsViewModel = settingsViewModel binding.submissionViewModel = submissionViewModel @@ -60,11 +60,6 @@ class MainFragment : Fragment() { return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/assets/privacy_de.html b/Corona-Warn-App/src/main/assets/privacy_de.html index d1860a8991c5724d183d135d5248b625bb39b47f..d259720849b8dbd04ca0a9f6ebf0258853ed4d54 100644 --- a/Corona-Warn-App/src/main/assets/privacy_de.html +++ b/Corona-Warn-App/src/main/assets/privacy_de.html @@ -498,7 +498,7 @@ </p> <ul> <li> - Benachrichtigungen zu möglicher Begegnung mit COVID-19-Infizierten + COVID-19-Benachrichtigungen </li> </ul> <p> @@ -782,4 +782,4 @@ </p> <p> Stand: 12.06.2020 -</p> \ No newline at end of file +</p> diff --git a/Corona-Warn-App/src/main/assets/terms_de.html b/Corona-Warn-App/src/main/assets/terms_de.html index 8c0051547e248925cff81e64c3554d3e19fbe902..abecebc46f1160e3457dc5ffb11a929448541ab0 100644 --- a/Corona-Warn-App/src/main/assets/terms_de.html +++ b/Corona-Warn-App/src/main/assets/terms_de.html @@ -57,8 +57,7 @@ </p> <p> vertreten durch den Präsidenten. Für Fragen, Beschwerden und Ansprüche im - Zusammenhang mit diesen Nutzungsbedingungen können Sie das RKI telefonisch - unter +49 30 18754-5100 und per E-Mail unter CoronaWarnApp@rki.de + Zusammenhang mit diesen Nutzungsbedingungen können Sie das RKI per E-Mail unter CoronaWarnApp@rki.de erreichen. </p> <p> diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt index dec2043075ebf8241f0f91301c1905b0bc1ab6b2..bc347abb919fbbeff9ada2c2d768b3ef679334ff 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt @@ -27,30 +27,31 @@ import de.rki.coronawarnapp.exception.http.UnsupportedMediaTypeException import okhttp3.Interceptor import okhttp3.Response import java.net.UnknownHostException +import javax.net.ssl.HttpsURLConnection class HttpErrorParser : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { try { val response = chain.proceed(chain.request()) return when (val code = response.code) { - 200 -> response - 201 -> response - 202 -> response - 204 -> response - 400 -> throw BadRequestException() - 401 -> throw UnauthorizedException() - 403 -> throw ForbiddenException() - 404 -> throw NotFoundException() - 409 -> throw ConflictException() - 410 -> throw GoneException() - 415 -> throw UnsupportedMediaTypeException() + HttpsURLConnection.HTTP_OK -> response + HttpsURLConnection.HTTP_CREATED -> response + HttpsURLConnection.HTTP_ACCEPTED -> response + HttpsURLConnection.HTTP_NO_CONTENT -> response + HttpsURLConnection.HTTP_BAD_REQUEST -> throw BadRequestException() + HttpsURLConnection.HTTP_UNAUTHORIZED -> throw UnauthorizedException() + HttpsURLConnection.HTTP_FORBIDDEN -> throw ForbiddenException() + HttpsURLConnection.HTTP_NOT_FOUND -> throw NotFoundException() + HttpsURLConnection.HTTP_CONFLICT -> throw ConflictException() + HttpsURLConnection.HTTP_GONE -> throw GoneException() + HttpsURLConnection.HTTP_UNSUPPORTED_TYPE -> throw UnsupportedMediaTypeException() 429 -> throw TooManyRequestsException() - 500 -> throw InternalServerErrorException() - 501 -> throw NotImplementedException() - 502 -> throw BadGatewayException() - 503 -> throw ServiceUnavailableException() - 504 -> throw GatewayTimeoutException() - 505 -> throw HTTPVersionNotSupported() + HttpsURLConnection.HTTP_INTERNAL_ERROR -> throw InternalServerErrorException() + HttpsURLConnection.HTTP_NOT_IMPLEMENTED -> throw NotImplementedException() + HttpsURLConnection.HTTP_BAD_GATEWAY -> throw BadGatewayException() + HttpsURLConnection.HTTP_UNAVAILABLE -> throw ServiceUnavailableException() + HttpsURLConnection.HTTP_GATEWAY_TIMEOUT -> throw GatewayTimeoutException() + HttpsURLConnection.HTTP_VERSION -> throw HTTPVersionNotSupported() 511 -> throw NetworkAuthenticationRequiredException() 598 -> throw NetworkReadTimeoutException() 599 -> throw NetworkConnectTimeoutException() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt index c09cb0746f727e887d75b6e64156cf63e2d922ed..1fd3465f14562f241e5e9ecdd1c1707ce5d05c2f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt @@ -178,7 +178,7 @@ object NotificationHelper { */ fun sendNotification(content: String, visibility: Int) { if (!CoronaWarnApplication.isAppInForeground) { - sendNotification("", content, visibility) + sendNotification("", content, visibility, true) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt index 77e4492eda4d5205a02d4a92649258dd843d6fd0..ff77253438bce970b14a08837aadc11fcf1f5460 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt @@ -371,7 +371,7 @@ object RetrieveDiagnosisKeysTransaction : Transaction() { exportFiles: Collection<File>, exposureConfiguration: ExposureConfiguration? ) = executeState(API_SUBMISSION) { - if (googleAPIVersion.isAbove(GoogleAPIVersion.V16)) { + if (googleAPIVersion.isAtLeast(GoogleAPIVersion.V16)) { InternalExposureNotificationClient.asyncProvideDiagnosisKeys( exportFiles, exposureConfiguration, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/UIExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/UIExtensions.kt index ed1f696f784ab156db60f8c31b7db67cd5917bf2..ed36ea61f2a800d739395fcb5c751463386f02a2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/UIExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/UIExtensions.kt @@ -1,7 +1,15 @@ package de.rki.coronawarnapp.ui +import android.os.Handler +import android.os.Looper +import androidx.fragment.app.Fragment +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.Observer import androidx.navigation.NavController import androidx.navigation.NavDirections +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty /** * Extends NavController to prevent navigation error when the user clicks on two buttons at almost @@ -13,3 +21,47 @@ fun NavController.doNavigate(direction: NavDirections) { currentDestination?.getAction(direction.actionId) ?.let { navigate(direction) } } + +/** + * An extension to bind and unbind a value based on the view lifecycle of a Fragment. + * The binding will be unbound in onDestroyView. + * + * @throws IllegalStateException If the getter is invoked before the binding is set, + * or after onDestroyView an exception is thrown. + */ +fun <T> Fragment.viewLifecycle(): ReadWriteProperty<Fragment, T> { + return object : ReadWriteProperty<Fragment, T>, DefaultLifecycleObserver { + + private var binding: T? = null + + init { + this@viewLifecycle + .viewLifecycleOwnerLiveData + .observe(this@viewLifecycle, Observer { owner: LifecycleOwner? -> + owner?.lifecycle?.addObserver(this) + }) + } + + override fun onDestroy(owner: LifecycleOwner) { + val handler = Handler(Looper.getMainLooper()) + handler.post { + binding = null + } + } + + override fun getValue( + thisRef: Fragment, + property: KProperty<*> + ): T { + return this.binding ?: error("Called before onCreateView or after onDestroyView.") + } + + override fun setValue( + thisRef: Fragment, + property: KProperty<*>, + value: T + ) { + this.binding = value + } + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt index 5cc5be6d7aaf95183b23d4bed5b6dfbee387deb6..3b98d61d742bc64da47e392a3b429f306d01833c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationAboutFragment.kt @@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentInformationAboutBinding import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle /** * Basic Fragment which only displays static content. @@ -20,23 +21,17 @@ class InformationAboutFragment : Fragment() { private val TAG: String? = InformationAboutFragment::class.simpleName } - private var _binding: FragmentInformationAboutBinding? = null - private val binding: FragmentInformationAboutBinding get() = _binding!! + private var binding: FragmentInformationAboutBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationAboutBinding.inflate(inflater) + binding = FragmentInformationAboutBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationContactFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationContactFragment.kt index 6b351030c0f2712e25a9b14be40911e267cebcd8..5d42b024caaf792d54e0e7008c1f6295eda6db78 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationContactFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationContactFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentInformationContactBinding import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.util.ExternalActionHelper /** @@ -19,23 +20,17 @@ class InformationContactFragment : Fragment() { private val TAG: String? = InformationContactFragment::class.simpleName } - private var _binding: FragmentInformationContactBinding? = null - private val binding: FragmentInformationContactBinding get() = _binding!! + private var binding: FragmentInformationContactBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationContactBinding.inflate(inflater) + binding = FragmentInformationContactBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt index 9a6bd0b92f067cf0371595d1674c799776c4c921..418455b8bffdce3ed6fd8db125d7d022f5c9a866 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationFragment.kt @@ -12,6 +12,7 @@ import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentInformationBinding import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.util.ExternalActionHelper /** @@ -22,23 +23,17 @@ class InformationFragment : Fragment() { private val TAG: String? = InformationFragment::class.simpleName } - private var _binding: FragmentInformationBinding? = null - private val binding: FragmentInformationBinding get() = _binding!! + private var binding: FragmentInformationBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationBinding.inflate(inflater) + binding = FragmentInformationBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt index 6d102711f8e5440e30a7121c82553f17c8bcaebf..62a42f82fdbb112b6b31e517d25f0700c106dc91 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationLegalFragment.kt @@ -11,6 +11,7 @@ import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentInformationLegalBinding import de.rki.coronawarnapp.ui.main.MainActivity import de.rki.coronawarnapp.util.convertToHyperlink +import de.rki.coronawarnapp.ui.viewLifecycle /** * Basic Fragment which only displays static content. @@ -20,23 +21,17 @@ class InformationLegalFragment : Fragment() { private val TAG: String? = InformationLegalFragment::class.simpleName } - private var _binding: FragmentInformationLegalBinding? = null - private val binding: FragmentInformationLegalBinding get() = _binding!! + private var binding: FragmentInformationLegalBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationLegalBinding.inflate(inflater) + binding = FragmentInformationLegalBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() @@ -49,8 +44,6 @@ class InformationLegalFragment : Fragment() { private fun setUpContactFormLinks() { binding.informationLegalContactForm.informationLegalContactForm .convertToHyperlink(getString(R.string.information_legal_subtitle_contact_url)) - binding.informationLegalContactForm.informationLegalContactForm - .movementMethod = LinkMovementMethod.getInstance() binding.informationLegalContactForm.informationLegalContactFormNonEnDe .movementMethod = LinkMovementMethod.getInstance() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationPrivacyFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationPrivacyFragment.kt index c445f900f1539bfd1ef4e31ae4b9c10138a99311..2aede5973617d47d3e8c77d9e15537ba52efb2c0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationPrivacyFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationPrivacyFragment.kt @@ -8,6 +8,7 @@ import android.view.accessibility.AccessibilityEvent import androidx.fragment.app.Fragment import de.rki.coronawarnapp.databinding.FragmentInformationPrivacyBinding import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle /** * Basic Fragment which only displays static content. @@ -17,23 +18,17 @@ class InformationPrivacyFragment : Fragment() { private val TAG: String? = InformationPrivacyFragment::class.simpleName } - private var _binding: FragmentInformationPrivacyBinding? = null - private val binding: FragmentInformationPrivacyBinding get() = _binding!! + private var binding: FragmentInformationPrivacyBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationPrivacyBinding.inflate(inflater) + binding = FragmentInformationPrivacyBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTechnicalFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTechnicalFragment.kt index a4ee7576532e3928a945d24b1704b46eefab41e9..193fde9c2640c0ff26792d77830ae978b6deaec2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTechnicalFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTechnicalFragment.kt @@ -8,6 +8,7 @@ import android.view.accessibility.AccessibilityEvent import androidx.fragment.app.Fragment import de.rki.coronawarnapp.databinding.FragmentInformationTechnicalBinding import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle /** * Basic Fragment which only displays static content. @@ -17,23 +18,17 @@ class InformationTechnicalFragment : Fragment() { private val TAG: String? = InformationTechnicalFragment::class.simpleName } - private var _binding: FragmentInformationTechnicalBinding? = null - private val binding: FragmentInformationTechnicalBinding get() = _binding!! + private var binding: FragmentInformationTechnicalBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationTechnicalBinding.inflate(inflater) + binding = FragmentInformationTechnicalBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTermsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTermsFragment.kt index 98a4079e6a084554861912d4f0ad375ba5fc4531..592c36df7c4a5949313f1b06580507292df0c3e0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTermsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/information/InformationTermsFragment.kt @@ -8,6 +8,7 @@ import android.view.accessibility.AccessibilityEvent import androidx.fragment.app.Fragment import de.rki.coronawarnapp.databinding.FragmentInformationTermsBinding import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle /** * Basic Fragment which only displays static content. @@ -17,23 +18,17 @@ class InformationTermsFragment : Fragment() { private val TAG: String? = InformationTermsFragment::class.simpleName } - private var _binding: FragmentInformationTermsBinding? = null - private val binding: FragmentInformationTermsBinding get() = _binding!! + private var binding: FragmentInformationTermsBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentInformationTermsBinding.inflate(inflater) + binding = FragmentInformationTermsBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt index 67b6ebbe80b2cfc72150ad78ee1b68f853d17c61..aa437a80b60dcf6fa79874ef212652d6bb88a62d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainOverviewFragment.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent import androidx.fragment.app.Fragment import de.rki.coronawarnapp.databinding.FragmentMainOverviewBinding +import de.rki.coronawarnapp.ui.viewLifecycle /** * The fragment displays static informative content to the user @@ -21,23 +22,17 @@ class MainOverviewFragment : Fragment() { private val TAG: String? = MainOverviewFragment::class.simpleName } - private var _binding: FragmentMainOverviewBinding? = null - private val binding: FragmentMainOverviewBinding get() = _binding!! + private var binding: FragmentMainOverviewBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentMainOverviewBinding.inflate(inflater) + binding = FragmentMainOverviewBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt index 52c0e3df59de90639ce0c92aec3f62300e00934d..5dd447eaf6cf91b64866836419e60e930537efaf 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainShareFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentMainShareBinding +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.ExternalActionHelper @@ -24,25 +25,19 @@ class MainShareFragment : Fragment() { } private val tracingViewModel: TracingViewModel by activityViewModels() - private var _binding: FragmentMainShareBinding? = null - private val binding: FragmentMainShareBinding get() = _binding!! + private var binding: FragmentMainShareBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentMainShareBinding.inflate(inflater) + binding = FragmentMainShareBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt index 6b18c0845758f401814e0f8e64b40fd8801722d9..b1daa10c00314fb9dae088f67cdecc786cc43a9c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingFragment.kt @@ -12,6 +12,7 @@ import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentOnboardingBinding import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle /** * Onboarding starting point. @@ -21,23 +22,17 @@ class OnboardingFragment : Fragment() { private val TAG: String? = OnboardingFragment::class.simpleName } - private var _binding: FragmentOnboardingBinding? = null - private val binding: FragmentOnboardingBinding get() = _binding!! + private var binding: FragmentOnboardingBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentOnboardingBinding.inflate(inflater) + binding = FragmentOnboardingBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.onboardingButtonNext.setOnClickListener { 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 c6768a15f48d752bc6b7ce8ba8022a4eee645790..5813171099375402630300b5cf0dcccaf25069c7 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 @@ -9,6 +9,7 @@ import androidx.appcompat.app.AlertDialog import androidx.core.app.NotificationManagerCompat import androidx.fragment.app.Fragment import de.rki.coronawarnapp.databinding.FragmentOnboardingNotificationsBinding +import de.rki.coronawarnapp.ui.viewLifecycle /** * This fragment ask the user if he wants to get notifications and finishes the onboarding afterwards. @@ -21,23 +22,17 @@ class OnboardingNotificationsFragment : Fragment() { private val TAG: String? = OnboardingNotificationsFragment::class.simpleName } - private var _binding: FragmentOnboardingNotificationsBinding? = null - private val binding: FragmentOnboardingNotificationsBinding get() = _binding!! + private var binding: FragmentOnboardingNotificationsBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentOnboardingNotificationsBinding.inflate(inflater) + binding = FragmentOnboardingNotificationsBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingPrivacyFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingPrivacyFragment.kt index f15cbfbde6c084c29ee22e40add187f5ef94f49a..f81ec47d1e0a1524596815713ce7e24158371454 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingPrivacyFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingPrivacyFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.databinding.FragmentOnboardingPrivacyBinding import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle /** * This fragment informs the user regarding privacy. @@ -18,23 +19,17 @@ class OnboardingPrivacyFragment : Fragment() { private val TAG: String? = OnboardingPrivacyFragment::class.simpleName } - private var _binding: FragmentOnboardingPrivacyBinding? = null - private val binding: FragmentOnboardingPrivacyBinding get() = _binding!! + private var binding: FragmentOnboardingPrivacyBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentOnboardingPrivacyBinding.inflate(inflater) + binding = FragmentOnboardingPrivacyBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTestFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTestFragment.kt index 2923d9ea0f06dbc570783d41a99d0b24b6b9b5f6..aacc99a5e1d01e2bf193804ceccda1a63408c86a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTestFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTestFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.databinding.FragmentOnboardingTestBinding import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle /** * This fragment informs the user about test results. @@ -18,23 +19,17 @@ class OnboardingTestFragment : Fragment() { private val TAG: String? = OnboardingTestFragment::class.simpleName } - private var _binding: FragmentOnboardingTestBinding? = null - private val binding: FragmentOnboardingTestBinding get() = _binding!! + private var binding: FragmentOnboardingTestBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentOnboardingTestBinding.inflate(inflater) + binding = FragmentOnboardingTestBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTracingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTracingFragment.kt index 23f302095ecfca1dc2fc645a8751af08b5535140..1d8e08fdffc83e8b9261f289162ba632a0d57480 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTracingFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingTracingFragment.kt @@ -18,6 +18,7 @@ import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient import de.rki.coronawarnapp.nearby.InternalExposureNotificationPermissionHelper import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.util.DialogHelper import kotlinx.coroutines.launch @@ -35,8 +36,7 @@ class OnboardingTracingFragment : Fragment(), } private lateinit var internalExposureNotificationPermissionHelper: InternalExposureNotificationPermissionHelper - private var _binding: FragmentOnboardingTracingBinding? = null - private val binding: FragmentOnboardingTracingBinding get() = _binding!! + private var binding: FragmentOnboardingTracingBinding by viewLifecycle() override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { internalExposureNotificationPermissionHelper.onResolutionComplete( @@ -56,15 +56,10 @@ class OnboardingTracingFragment : Fragment(), container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentOnboardingTracingBinding.inflate(inflater) + binding = FragmentOnboardingTracingBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt index d816080e0948d03eebb3399b908dfaf873ba0529..db5bba738605699031475f19c236acc7ac115c1f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/riskdetails/RiskDetailsFragment.kt @@ -12,6 +12,7 @@ import de.rki.coronawarnapp.databinding.FragmentRiskDetailsBinding import de.rki.coronawarnapp.timer.TimerHelper import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel @@ -29,26 +30,20 @@ class RiskDetailsFragment : Fragment() { private val tracingViewModel: TracingViewModel by activityViewModels() private val settingsViewModel: SettingsViewModel by activityViewModels() - private var _binding: FragmentRiskDetailsBinding? = null - private val binding: FragmentRiskDetailsBinding get() = _binding!! + private var binding: FragmentRiskDetailsBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentRiskDetailsBinding.inflate(inflater) + binding = FragmentRiskDetailsBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.settingsViewModel = settingsViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListeners() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt index aa8218a169d1c324033939f8148106c7f0821aff..7385447600b0312a69f06c32da52abd4f19491c9 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt @@ -10,6 +10,7 @@ import androidx.fragment.app.activityViewModels import de.rki.coronawarnapp.databinding.FragmentSettingsBackgroundPriorityBinding import de.rki.coronawarnapp.ui.base.startActivitySafely import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel @@ -26,25 +27,19 @@ class SettingsBackgroundPriorityFragment : Fragment() { } private val settingsViewModel: SettingsViewModel by activityViewModels() - private var _binding: FragmentSettingsBackgroundPriorityBinding? = null - private val binding: FragmentSettingsBackgroundPriorityBinding get() = _binding!! + private var binding: FragmentSettingsBackgroundPriorityBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSettingsBackgroundPriorityBinding.inflate(inflater) + binding = FragmentSettingsBackgroundPriorityBinding.inflate(inflater) binding.settingsViewModel = settingsViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt index 33bc8f9b3217b510e45f33357252ad4a9695926b..1f6338e182d5c07b3c2c7b1012bd102aa2e47793 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt @@ -11,6 +11,7 @@ import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.databinding.FragmentSettingsBinding import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel @@ -28,26 +29,20 @@ class SettingsFragment : Fragment() { private val tracingViewModel: TracingViewModel by activityViewModels() private val settingsViewModel: SettingsViewModel by activityViewModels() - private var _binding: FragmentSettingsBinding? = null - private val binding: FragmentSettingsBinding get() = _binding!! + private var binding: FragmentSettingsBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSettingsBinding.inflate(inflater) + binding = FragmentSettingsBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.settingsViewModel = settingsViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsNotificationFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsNotificationFragment.kt index 3acd7e6d9fa92a9c2a6fea280d8dde90a617d46e..7cbbccbfe2ef4a63c71d85f85c3f1d6cf9c1888d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsNotificationFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsNotificationFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import de.rki.coronawarnapp.databinding.FragmentSettingsNotificationsBinding import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.ExternalActionHelper @@ -28,25 +29,19 @@ class SettingsNotificationFragment : Fragment() { } private val settingsViewModel: SettingsViewModel by activityViewModels() - private var _binding: FragmentSettingsNotificationsBinding? = null - private val binding: FragmentSettingsNotificationsBinding get() = _binding!! + private var binding: FragmentSettingsNotificationsBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSettingsNotificationsBinding.inflate(inflater) + binding = FragmentSettingsNotificationsBinding.inflate(inflater) binding.settingsViewModel = settingsViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt index 77b7043444bbbb633a7dd539eb5e0ff7bbd88cd8..bea672e29d7244f9a346c3f99a9af9a7ae3ba9a7 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt @@ -16,6 +16,7 @@ import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient import de.rki.coronawarnapp.ui.main.MainActivity import de.rki.coronawarnapp.ui.onboarding.OnboardingActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.util.DataRetentionHelper import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.worker.BackgroundWorkScheduler @@ -33,23 +34,17 @@ class SettingsResetFragment : Fragment() { private val TAG: String? = SettingsResetFragment::class.simpleName } - private var _binding: FragmentSettingsResetBinding? = null - private val binding: FragmentSettingsResetBinding get() = _binding!! + private var binding: FragmentSettingsResetBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSettingsResetBinding.inflate(inflater) + binding = FragmentSettingsResetBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.settingsResetButtonDelete.setOnClickListener { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt index afc6c1abf4581ecf6200b17b8d7fc3318662bbf1..702eebc1705fb16a1a272293323e4d3469e621e6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsTracingFragment.kt @@ -17,6 +17,7 @@ import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient import de.rki.coronawarnapp.nearby.InternalExposureNotificationPermissionHelper import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.DialogHelper @@ -43,8 +44,7 @@ class SettingsTracingFragment : Fragment(), private val tracingViewModel: TracingViewModel by activityViewModels() private val settingsViewModel: SettingsViewModel by activityViewModels() - private var _binding: FragmentSettingsTracingBinding? = null - private val binding: FragmentSettingsTracingBinding get() = _binding!! + private var binding: FragmentSettingsTracingBinding by viewLifecycle() private lateinit var internalExposureNotificationPermissionHelper: InternalExposureNotificationPermissionHelper @@ -53,18 +53,13 @@ class SettingsTracingFragment : Fragment(), container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSettingsTracingBinding.inflate(inflater) + binding = FragmentSettingsTracingBinding.inflate(inflater) binding.tracingViewModel = tracingViewModel binding.settingsViewModel = settingsViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionContactFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionContactFragment.kt index 979cdd886eccfa0b234dd38085ad1cba1bf031d6..222aedad14e4c730216b13ca3c194d96a61352fd 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionContactFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionContactFragment.kt @@ -11,6 +11,7 @@ import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionContactBinding import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.util.ExternalActionHelper /** @@ -18,8 +19,7 @@ import de.rki.coronawarnapp.util.ExternalActionHelper */ class SubmissionContactFragment : Fragment() { - private var _binding: FragmentSubmissionContactBinding? = null - private val binding: FragmentSubmissionContactBinding get() = _binding!! + private var binding: FragmentSubmissionContactBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, @@ -27,15 +27,10 @@ class SubmissionContactFragment : Fragment() { savedInstanceState: Bundle? ): View? { // get the binding reference by inflating it with the current layout - _binding = FragmentSubmissionContactBinding.inflate(inflater) + binding = FragmentSubmissionContactBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt index 6f2b0a288bd9bd2ed83f17c81cb7022175d4df54..1a82f3fb8de31c892773a64cc5f5102aaf225ba1 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt @@ -11,6 +11,7 @@ import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionDispatcherBinding import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.main.MainActivity +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.util.DialogHelper class SubmissionDispatcherFragment : Fragment() { @@ -19,24 +20,18 @@ class SubmissionDispatcherFragment : Fragment() { private val TAG: String? = SubmissionDispatcherFragment::class.simpleName } - private var _binding: FragmentSubmissionDispatcherBinding? = null - private val binding: FragmentSubmissionDispatcherBinding get() = _binding!! + private var binding: FragmentSubmissionDispatcherBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSubmissionDispatcherBinding.inflate(inflater) + binding = FragmentSubmissionDispatcherBinding.inflate(inflater) binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDoneFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDoneFragment.kt index 458d5734dfddafe2d479f9ff803e074816c0344f..b76808583a8c3aadf49ca3b1b17469aeb72c4198 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDoneFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDoneFragment.kt @@ -9,14 +9,14 @@ import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.databinding.FragmentSubmissionDoneBinding import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle /** * The [SubmissionDoneFragment] displays information to a user that submitted his exposure keys */ class SubmissionDoneFragment : Fragment() { - private var _binding: FragmentSubmissionDoneBinding? = null - private val binding: FragmentSubmissionDoneBinding get() = _binding!! + private var binding: FragmentSubmissionDoneBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, @@ -24,15 +24,9 @@ class SubmissionDoneFragment : Fragment() { savedInstanceState: Bundle? ): View? { // get the binding reference by inflating it with the current layout - _binding = FragmentSubmissionDoneBinding.inflate(inflater) + binding = FragmentSubmissionDoneBinding.inflate(inflater) return binding.root } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionIntroFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionIntroFragment.kt index 1cda7eb11315b74c9020004041e3df0d21128f79..e44e543222167e1fce9c3705e3d2a6d6de731684 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionIntroFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionIntroFragment.kt @@ -9,14 +9,14 @@ import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.databinding.FragmentSubmissionIntroBinding import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle /** * The [SubmissionIntroFragment] displays information about how the corona warning system works */ class SubmissionIntroFragment : Fragment() { - private var _binding: FragmentSubmissionIntroBinding? = null - private val binding: FragmentSubmissionIntroBinding get() = _binding!! + private var binding: FragmentSubmissionIntroBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, @@ -24,15 +24,10 @@ class SubmissionIntroFragment : Fragment() { savedInstanceState: Bundle? ): View? { // get the binding reference by inflating it with the current layout - _binding = FragmentSubmissionIntroBinding.inflate(inflater) + binding = FragmentSubmissionIntroBinding.inflate(inflater) return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionQRCodeScanFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionQRCodeScanFragment.kt index 016527412dc019416615575248c005c9335b5c47..1542ea6998e8cbc47a7511bb72fea6e97624db5c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionQRCodeScanFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionQRCodeScanFragment.kt @@ -23,6 +23,7 @@ import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.main.MainActivity import de.rki.coronawarnapp.ui.submission.ApiRequestState import de.rki.coronawarnapp.ui.submission.ScanStatus +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.util.CameraPermissionHelper import de.rki.coronawarnapp.util.DialogHelper @@ -39,8 +40,7 @@ class SubmissionQRCodeScanFragment : Fragment() { } private val viewModel: SubmissionViewModel by activityViewModels() - private var _binding: FragmentSubmissionQrCodeScanBinding? = null - private val binding: FragmentSubmissionQrCodeScanBinding get() = _binding!! + private var binding: FragmentSubmissionQrCodeScanBinding by viewLifecycle() private var showsPermissionDialog = false override fun onCreateView( @@ -48,7 +48,7 @@ class SubmissionQRCodeScanFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - _binding = FragmentSubmissionQrCodeScanBinding.inflate(inflater) + binding = FragmentSubmissionQrCodeScanBinding.inflate(inflater) binding.lifecycleOwner = this return binding.root } @@ -61,20 +61,16 @@ class SubmissionQRCodeScanFragment : Fragment() { binding.submissionQrCodeScanPreview.decodeSingle { decodeCallback(it) } } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - private fun buildErrorDialog(exception: CwaWebException): DialogHelper.DialogInstance { return when (exception) { is BadRequestException -> DialogHelper.DialogInstance( requireActivity(), - R.string.submission_error_dialog_web_test_paired_title, - R.string.submission_error_dialog_web_test_paired_body, - R.string.submission_error_dialog_web_test_paired_button_positive, - null, + R.string.submission_qr_code_scan_invalid_dialog_headline, + R.string.submission_qr_code_scan_invalid_dialog_body, + R.string.submission_qr_code_scan_invalid_dialog_button_positive, + R.string.submission_qr_code_scan_invalid_dialog_button_negative, true, + { startDecode() }, ::navigateToDispatchScreen ) is CwaServerError -> DialogHelper.DialogInstance( diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionResultPositiveOtherWarningFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionResultPositiveOtherWarningFragment.kt index 2e44b812629ba33dfddaf7299063faa86d1dfac7..f62c30af37cc2ce91520fa0f2064b0ce261e8a14 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionResultPositiveOtherWarningFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionResultPositiveOtherWarningFragment.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent +import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer @@ -20,6 +21,7 @@ import de.rki.coronawarnapp.exception.http.ForbiddenException import de.rki.coronawarnapp.nearby.InternalExposureNotificationPermissionHelper import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.submission.ApiRequestState +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.DialogHelper @@ -35,11 +37,18 @@ class SubmissionResultPositiveOtherWarningFragment : Fragment(), private val submissionViewModel: SubmissionViewModel by activityViewModels() private val tracingViewModel: TracingViewModel by activityViewModels() - private var _binding: FragmentSubmissionPositiveOtherWarningBinding? = null - private val binding: FragmentSubmissionPositiveOtherWarningBinding get() = _binding!! + private var binding: FragmentSubmissionPositiveOtherWarningBinding by viewLifecycle() private lateinit var internalExposureNotificationPermissionHelper: InternalExposureNotificationPermissionHelper + // Overrides default back behaviour + private val backCallback: OnBackPressedCallback = + object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + handleSubmissionCancellation() + } + } + override fun onResume() { super.onResume() binding.submissionPositiveOtherPrivacyContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) @@ -53,17 +62,13 @@ class SubmissionResultPositiveOtherWarningFragment : Fragment(), ): View? { internalExposureNotificationPermissionHelper = InternalExposureNotificationPermissionHelper(this, this) - _binding = FragmentSubmissionPositiveOtherWarningBinding.inflate(inflater) + binding = FragmentSubmissionPositiveOtherWarningBinding.inflate(inflater) + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backCallback) binding.submissionViewModel = submissionViewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - private fun buildErrorDialog(exception: Exception): DialogHelper.DialogInstance { return when (exception) { is BadRequestException -> DialogHelper.DialogInstance( @@ -140,10 +145,28 @@ class SubmissionResultPositiveOtherWarningFragment : Fragment(), initiateWarningOthers() } binding.submissionPositiveOtherWarningHeader.headerButtonBack.buttonIcon.setOnClickListener { - navigateToSubmissionResultFragment() + handleSubmissionCancellation() } } + /** + * Opens a Dialog that warns user + * when they're about to cancel the submission flow + * @see DialogHelper + * @see navigateToSubmissionResultFragment + */ + fun handleSubmissionCancellation() { + DialogHelper.showDialog(DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_confirm_cancellation_title, + R.string.submission_error_dialog_confirm_cancellation_body, + R.string.submission_error_dialog_confirm_cancellation_button_positive, + R.string.submission_error_dialog_confirm_cancellation_button_negative, + true, + ::navigateToSubmissionResultFragment + )) + } + private fun navigateToSubmissionResultFragment() = findNavController().doNavigate( SubmissionResultPositiveOtherWarningFragmentDirections diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTanFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTanFragment.kt index 73133eccd3bcb0314ec7087904c877bbfe59ca95..bd8b681d6ebde3b71fb9abcc8240582bae1d3522 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTanFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTanFragment.kt @@ -20,6 +20,7 @@ import de.rki.coronawarnapp.ui.main.MainActivity import de.rki.coronawarnapp.ui.submission.ApiRequestState import de.rki.coronawarnapp.ui.submission.TanConstants import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionTanViewModel +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.TanHelper @@ -33,8 +34,7 @@ class SubmissionTanFragment : Fragment() { private val viewModel: SubmissionTanViewModel by viewModels() private val submissionViewModel: SubmissionViewModel by activityViewModels() - private var _binding: FragmentSubmissionTanBinding? = null - private val binding: FragmentSubmissionTanBinding get() = _binding!! + private var binding: FragmentSubmissionTanBinding by viewLifecycle() override fun onCreateView( inflater: LayoutInflater, @@ -42,23 +42,18 @@ class SubmissionTanFragment : Fragment() { savedInstanceState: Bundle? ): View? { // get the binding reference by inflating it with the current layout - _binding = FragmentSubmissionTanBinding.inflate(inflater) + binding = FragmentSubmissionTanBinding.inflate(inflater) binding.viewmodel = viewModel binding.lifecycleOwner = this return binding.root } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - private fun buildErrorDialog(exception: CwaWebException): DialogHelper.DialogInstance { return when (exception) { is BadRequestException -> DialogHelper.DialogInstance( requireActivity(), - R.string.submission_error_dialog_web_test_paired_title, - R.string.submission_error_dialog_web_test_paired_body, + R.string.submission_error_dialog_web_test_paired_title_tan, + R.string.submission_error_dialog_web_test_paired_body_tan, R.string.submission_error_dialog_web_test_paired_button_positive, null, true, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTestResultFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTestResultFragment.kt index ee5820ae68c61f9c898cfc1543f411bd4965a986..3b316fa48ef13260e537ce7d58281891815976f4 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTestResultFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionTestResultFragment.kt @@ -17,6 +17,7 @@ import de.rki.coronawarnapp.exception.http.CwaClientError import de.rki.coronawarnapp.exception.http.CwaServerError import de.rki.coronawarnapp.exception.http.CwaWebException import de.rki.coronawarnapp.ui.doNavigate +import de.rki.coronawarnapp.ui.viewLifecycle import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel import de.rki.coronawarnapp.util.DeviceUIState @@ -34,8 +35,7 @@ class SubmissionTestResultFragment : Fragment() { private val submissionViewModel: SubmissionViewModel by activityViewModels() private val tracingViewModel: TracingViewModel by activityViewModels() - private var _binding: FragmentSubmissionTestResultBinding? = null - private val binding: FragmentSubmissionTestResultBinding get() = _binding!! + private var binding: FragmentSubmissionTestResultBinding by viewLifecycle() private var skipInitialTestResultRefresh = false @@ -55,7 +55,7 @@ class SubmissionTestResultFragment : Fragment() { savedInstanceState: Bundle? ): View? { // get the binding reference by inflating it with the current layout - _binding = FragmentSubmissionTestResultBinding.inflate(inflater) + binding = FragmentSubmissionTestResultBinding.inflate(inflater) binding.submissionViewModel = submissionViewModel binding.lifecycleOwner = this // registers callback when the os level back is pressed @@ -111,11 +111,6 @@ class SubmissionTestResultFragment : Fragment() { } } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/LocationTracingStatusCardBodyTextView.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/LocationTracingStatusCardBodyTextView.kt new file mode 100644 index 0000000000000000000000000000000000000000..cf71bbc226196247918ebbada091a5a8887791b4 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/LocationTracingStatusCardBodyTextView.kt @@ -0,0 +1,34 @@ +package de.rki.coronawarnapp.ui.view + +import android.content.Context +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatTextView +import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.util.setUrl + +class LocationTracingStatusCardBodyTextView : AppCompatTextView { + + constructor(context: Context?) : super(context) { + setUrl() + } + + constructor(context: Context?, attrs: AttributeSet) : super(context, attrs) { + setUrl() + } + + constructor( + context: Context?, + attrs: AttributeSet, + defStyleAttr: Int + ) : super(context, attrs, defStyleAttr) { + setUrl() + } + + private fun setUrl() { + setUrl( + R.string.settings_tracing_status_location_body, + "FAQ", + context.getString(R.string.settings_tracing_status_location_body_url) + ) + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleAPIVersion.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleAPIVersion.kt index 9b1998f66c493dd8abb62ad9e711dda791a93f8b..cb6f64f5b0f97c1efed5b1b4dc4a9dfc10dffd18 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleAPIVersion.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/GoogleAPIVersion.kt @@ -14,7 +14,7 @@ class GoogleAPIVersion @Inject constructor() { * * @return isAboveVersion, if connected to an old unsupported version, return false */ - suspend fun isAbove(compareVersion: Long): Boolean { + suspend fun isAtLeast(compareVersion: Long): Boolean { if (!compareVersion.isCorrectVersionLength) { throw IllegalArgumentException("given version has incorrect length") } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/Views.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/Views.kt index 39caae195a240ea6859b743a80e49a49a2db7f68..0b70bf717794ab09bbd35bc899e5e24cdd24b24f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/Views.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/Views.kt @@ -2,12 +2,55 @@ package de.rki.coronawarnapp.util import android.text.SpannableString import android.text.Spanned +import android.text.method.LinkMovementMethod import android.text.style.URLSpan import android.widget.TextView +import androidx.annotation.StringRes fun TextView.convertToHyperlink(url: String) { setText( SpannableString(text).apply { setSpan(URLSpan(url), 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) }, TextView.BufferType.SPANNABLE ) + movementMethod = LinkMovementMethod.getInstance() +} + +fun TextView.setUrlText(@StringRes textRes: Int, url: String) { + context.getString(textRes, url).also { + val indexOf = it.indexOf(url) + setText( + SpannableString(it).apply { + setSpan( + URLSpan(url), + indexOf, + indexOf + url.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + }, + TextView.BufferType.SPANNABLE + ) + movementMethod = LinkMovementMethod.getInstance() + } +} + +fun TextView.setUrl(@StringRes textRes: Int, label: String, url: String) { + context.getString(textRes).also { + val indexOf = it.indexOf(label) + if (indexOf > 0) { + setText( + SpannableString(it).apply { + setSpan( + URLSpan(url), + indexOf, + indexOf + label.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + }, + TextView.BufferType.SPANNABLE + ) + movementMethod = LinkMovementMethod.getInstance() + } else { + text = it + } + } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt index 2942c09bfbadaa8fa99e019895309cc7fb472e5a..4c06814bafe705811329c21953bd9f75e2361111 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt @@ -142,7 +142,7 @@ fun formatRiskContact(riskLevelScore: Int?, matchedKeysCount: Int?): String { } RiskLevelConstants.LOW_LEVEL_RISK -> { if (matchedKeysCount == 0) { - appContext.getString(R.string.risk_card_body_contact_low_risk) + appContext.getString(R.string.risk_card_body_contact) } else { resources.getQuantityString( R.plurals.risk_card_body_contact_value, diff --git a/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml b/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml index bb55bbd0058e304e1ef08b61d5b007f401921919..c4f43ce6256a4a4368b43266fe8a90d15ff807d1 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_settings_tracing.xml @@ -87,11 +87,10 @@ <include android:id="@+id/settings_tracing_status_location" - layout="@layout/include_tracing_status_card" + layout="@layout/include_tracing_status_card_location" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:visibility="@{FormatterSettingsHelper.formatTracingStatusVisibilityLocation(tracingViewModel.isTracingEnabled(), settingsViewModel.isBluetoothEnabled(), settingsViewModel.isLocationEnabled())}" - app:body="@{@string/settings_tracing_status_location_body}" app:buttonText="@{@string/settings_tracing_status_location_button}" app:headline="@{@string/settings_tracing_status_location_headline}" app:icon="@{@drawable/ic_location}" diff --git a/Corona-Warn-App/src/main/res/layout/include_tracing_status_card_location.xml b/Corona-Warn-App/src/main/res/layout/include_tracing_status_card_location.xml new file mode 100644 index 0000000000000000000000000000000000000000..e7a794e026aeaed7ea17e28fdf869cfa47aa181f --- /dev/null +++ b/Corona-Warn-App/src/main/res/layout/include_tracing_status_card_location.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="utf-8"?> +<layout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <data> + + <import type="de.rki.coronawarnapp.util.formatter.FormatterHelper" /> + + <import type="de.rki.coronawarnapp.util.formatter.FormatterAccessibilityHelper" /> + + <import type="android.view.View" /> + + <variable + name="tracingViewModel" + type="de.rki.coronawarnapp.ui.viewmodel.TracingViewModel" /> + + <variable + name="icon" + type="android.graphics.drawable.Drawable" /> + + <variable + name="headline" + type="String" /> + + <variable + name="buttonText" + type="String" /> + + + </data> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/tracing_status_card" + style="@style/cardTracing" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:focusable="true"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/tracing_status_card_header" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <TextView + android:id="@+id/tracing_status_card_header_headline" + style="@style/headline6" + android:accessibilityHeading="true" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/spacing_small" + android:text="@{headline}" + android:contentDescription="@{headline}" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/tracing_status_card_header_icon" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/tracing_status_card_header_icon" + android:layout_width="@dimen/icon_size_main_card_end" + android:layout_height="@dimen/icon_size_main_card_end" + android:importantForAccessibility="no" + android:focusable="false" + android:src="@{icon}" + android:visibility="@{FormatterHelper.formatVisibilityIcon(icon)}" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/tracing_status_card_header_headline" + app:layout_constraintTop_toTopOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> + + <de.rki.coronawarnapp.ui.view.LocationTracingStatusCardBodyTextView + android:id="@+id/tracing_status_card_body" + style="@style/subtitle" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_small" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tracing_status_card_header" /> + + <Button + android:id="@+id/tracing_status_card_button" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + android:text="@{buttonText}" + android:visibility="@{FormatterHelper.formatVisibilityText(buttonText)}" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tracing_status_card_body" /> + </androidx.constraintlayout.widget.ConstraintLayout> +</layout> \ No newline at end of file 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 a1f3ce9a16f8b45652729d3a8118a22d402669b6..0e77b972ba7c4a35b683dead150fcc14cab0443b 100644 --- a/Corona-Warn-App/src/main/res/values-bg/strings.xml +++ b/Corona-Warn-App/src/main/res/values-bg/strings.xml @@ -135,8 +135,6 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"До момента нÑма излагане на риÑк"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"До момента нÑма излагане на ниÑък риÑк"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> <item quantity="one">"%1$s излагане на ниÑък риÑк"</item> 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 0c3e1cdeee3678bc044bcc8857a104ffb9cd79c2..025aae05313214dc9e21d1be6f25c8ad75feb407 100644 --- a/Corona-Warn-App/src/main/res/values-de/strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/strings.xml @@ -135,16 +135,14 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"Bisher keine Risiko-Begegnungen"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"Bisher keine Begegnungen mit niedrigem Risiko"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> - <item quantity="one">"%1$s Risiko-Begegnung mit niedrigem Risiko"</item> - <item quantity="other">"%1$s Risiko-Begegnungen mit niedrigem Risiko"</item> + <item quantity="one">"%1$s Begegnung mit niedrigem Risiko"</item> + <item quantity="other">"%1$s Begegnungen mit niedrigem Risiko"</item> <item quantity="zero">"Bisher keine Begegnungen mit niedrigem Risiko"</item> - <item quantity="two">"%1$s Risiko-Begegnungen mit niedrigem Risiko"</item> - <item quantity="few">"%1$s Risiko-Begegnungen mit niedrigem Risiko"</item> - <item quantity="many">"%1$s Risiko-Begegnungen mit niedrigem Risiko"</item> + <item quantity="two">"%1$s Begegnungen mit niedrigem Risiko"</item> + <item quantity="few">"%1$s Begegnungen mit niedrigem Risiko"</item> + <item quantity="many">"%1$s Begegnungen mit niedrigem Risiko"</item> </plurals> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value_high_risk"> @@ -427,7 +425,7 @@ <!-- XHED: onboarding(tracing) - headline for consent information --> <string name="onboarding_tracing_headline_consent">"Einwilligungserklärung"</string> <!-- YTXT: onboarding(tracing) - body for consent information --> - <string name="onboarding_tracing_body_consent">"Um zu erfahren, ob Sie Kontakt mit einer infizierten Person hatten und für Sie ein Infektionsrisiko besteht, müssen Sie die Funktion Risiko-Ermittlung in der App aktivieren. Der Aktivierung der Risiko-Ermittlung und der damit im Zusammenhang stehenden Datenverarbeitung stimmen Sie mit Antippen des Buttons: Risiko-Ermittlung aktivieren zu."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Um die Risiko-Ermittlung nutzen zu können müssen Sie zudem auf Ihrem Smartphone die von Google bereitgestellte Kontaktaufzeichnungs-Funktion „Benachrichtigungen zu möglicher Begegnung mit COVID-19-Infizierten“ aktivieren und für die Corona-Warn-App freigeben."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Ihr Smartphone erzeugt und versendet bei aktivierter Kontaktaufzeichnung kontinuierlich Zufalls-IDs per Bluetooth, die von anderen Apple- und Android-Smartphones mit ebenfalls aktivierter Kontaktaufzeichnung in Ihrer Umgebung empfangen werden können. Umgekehrt empfängt Ihr Smartphone die Zufalls-IDs der anderen Smartphones. Die eigenen und die von anderen Smartphones empfangenen Zufalls-IDs werden im Kontaktprotokoll der Kontaktaufzeichnungs-Funktion aufgezeichnet und dort für 14 Tage gespeichert."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Zur Ermittlung Ihres Infektionsrisikos lädt die App mehrmals täglich oder auf Abfrage eine Liste mit den Zufalls-IDs aller Nutzer, die Ihre Infektion mit dem Corona-Virus in der App geteilt haben. Diese Liste wird dann mit den im Kontaktprotokoll der Kontaktaufzeichnungs-Funktion gespeicherten Zufalls-IDs verglichen. Wenn die App dabei feststellt, dass Sie möglicherweise Kontakt zu einem infizierten Nutzer gehabt haben, werden Sie von der App informiert, dass Sie mit einer infizierten Person in Kontakt waren und insoweit ein Infektionsrisiko besteht. In diesem Fall erhält die App außerdem Zugriff auf weitere im Kontaktprotokoll der Kontaktaufzeichnungs-Funktion Ihres Smartphones gespeicherte Daten (Datum und Dauer sowie Bluetooth-Signalstärke des Kontakts)."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Aus der Bluetooth-Signalstärke wird der räumliche Abstand abgeleitet (je stärker das Signal, desto geringer der Abstand). Diese Angaben werden von der App ausgewertet, um Ihr Gesundheitsrisiko durch eine Infektion mit dem Corona-Virus abzuschätzen und Ihnen Empfehlungen für die nächsten Schritte zu geben. Diese Auswertung wird ausschließlich lokal auf Ihrem Smartphone durchgeführt. Außer Ihnen erfährt niemand (auch nicht das RKI), ob Sie mit einer infizierten Person Kontakt hatten und welches Risiko für Sie ermittelt wird."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Zum Widerruf Ihrer Einwilligung in die Risiko-Ermittlung können Sie die Funktion über den Schieberegler innerhalb der App deaktivieren oder die App löschen. Wenn Sie die Risiko-Ermittlung wieder nutzen möchten, können Sie den Schieberegler erneut aktivieren oder die App erneut installieren. Wenn Sie die Risiko-Ermittlung deaktivieren, prüft die App nicht mehr, ob Sie Kontakt zu einem infizierten Nutzer gehabt haben. Um auch die Aussendung und den Empfang der Zufalls-IDs anzuhalten, müssen Sie das Kontaktprotokoll der Kontaktaufzeichnungs-Funktion in den Einstellungen Ihres Smartphones deaktivieren. Bitte beachten Sie, dass die im Kontaktprotokoll aufgezeichneten fremden und eigenen Zufalls-Kennungen nicht in der App gelöscht werden. Die im Kontaktprotokoll gespeicherten Daten können Sie nur in den Einstellungen Ihres Smartphones dauerhaft löschen."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Die Datenschutzhinweise der App (einschließlich Informationen zur Datenverarbeitung für die Risiko-Ermittlung) finden Sie unter dem Menüpunkt „Datenschutzinformation“."</string> + <string name="onboarding_tracing_body_consent">"Um zu erfahren, ob Sie Kontakt mit einer infizierten Person hatten und für Sie ein Infektionsrisiko besteht, müssen Sie die Funktion Risiko-Ermittlung in der App aktivieren. Der Aktivierung der Risiko-Ermittlung und der damit im Zusammenhang stehenden Datenverarbeitung stimmen Sie mit Antippen des Buttons: Risiko-Ermittlung aktivieren zu."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Um die Risiko-Ermittlung nutzen zu können müssen Sie zudem auf Ihrem Smartphone die von Google bereitgestellte Kontaktaufzeichnungs-Funktion „COVID-19-Benachrichtigungen“ aktivieren und für die Corona-Warn-App freigeben."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Ihr Smartphone erzeugt und versendet bei aktivierter Kontaktaufzeichnung kontinuierlich Zufalls-IDs per Bluetooth, die von anderen Apple- und Android-Smartphones mit ebenfalls aktivierter Kontaktaufzeichnung in Ihrer Umgebung empfangen werden können. Umgekehrt empfängt Ihr Smartphone die Zufalls-IDs der anderen Smartphones. Die eigenen und die von anderen Smartphones empfangenen Zufalls-IDs werden im Kontaktprotokoll der Kontaktaufzeichnungs-Funktion aufgezeichnet und dort für 14 Tage gespeichert."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Zur Ermittlung Ihres Infektionsrisikos lädt die App mehrmals täglich oder auf Abfrage eine Liste mit den Zufalls-IDs aller Nutzer, die Ihre Infektion mit dem Corona-Virus in der App geteilt haben. Diese Liste wird dann mit den im Kontaktprotokoll der Kontaktaufzeichnungs-Funktion gespeicherten Zufalls-IDs verglichen. Wenn die App dabei feststellt, dass Sie möglicherweise Kontakt zu einem infizierten Nutzer gehabt haben, werden Sie von der App informiert, dass Sie mit einer infizierten Person in Kontakt waren und insoweit ein Infektionsrisiko besteht. In diesem Fall erhält die App außerdem Zugriff auf weitere im Kontaktprotokoll der Kontaktaufzeichnungs-Funktion Ihres Smartphones gespeicherte Daten (Datum und Dauer sowie Bluetooth-Signalstärke des Kontakts)."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Aus der Bluetooth-Signalstärke wird der räumliche Abstand abgeleitet (je stärker das Signal, desto geringer der Abstand). Diese Angaben werden von der App ausgewertet, um Ihr Gesundheitsrisiko durch eine Infektion mit dem Corona-Virus abzuschätzen und Ihnen Empfehlungen für die nächsten Schritte zu geben. Diese Auswertung wird ausschließlich lokal auf Ihrem Smartphone durchgeführt. Außer Ihnen erfährt niemand (auch nicht das RKI), ob Sie mit einer infizierten Person Kontakt hatten und welches Risiko für Sie ermittelt wird."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Zum Widerruf Ihrer Einwilligung in die Risiko-Ermittlung können Sie die Funktion über den Schieberegler innerhalb der App deaktivieren oder die App löschen. Wenn Sie die Risiko-Ermittlung wieder nutzen möchten, können Sie den Schieberegler erneut aktivieren oder die App erneut installieren. Wenn Sie die Risiko-Ermittlung deaktivieren, prüft die App nicht mehr, ob Sie Kontakt zu einem infizierten Nutzer gehabt haben. Um auch die Aussendung und den Empfang der Zufalls-IDs anzuhalten, müssen Sie das Kontaktprotokoll der Kontaktaufzeichnungs-Funktion in den Einstellungen Ihres Smartphones deaktivieren. Bitte beachten Sie, dass die im Kontaktprotokoll aufgezeichneten fremden und eigenen Zufalls-Kennungen nicht in der App gelöscht werden. Die im Kontaktprotokoll gespeicherten Daten können Sie nur in den Einstellungen Ihres Smartphones dauerhaft löschen."<xliff:g id="line_break">"\n"</xliff:g><xliff:g id="line_break">"\n"</xliff:g>"Die Datenschutzhinweise der App (einschließlich Informationen zur Datenverarbeitung für die Risiko-Ermittlung) finden Sie unter dem Menüpunkt „Datenschutzinformation“."</string> <!-- XBUT: onboarding(tracing) - button enable tracing --> <string name="onboarding_tracing_button_next">"Risiko-Ermittlung aktivieren"</string> <!-- XTXT: onboarding(tracing) - dialog about tracing permission declined --> @@ -543,7 +541,9 @@ <!--XHED : settings(tracing) - headline on card about the current status and what to do --> <string name="settings_tracing_status_location_headline">"Standort-Verwendung erlauben"</string> <!-- XTXT: settings(tracing) - explains user what to do on card if location is disabled --> - <string name="settings_tracing_status_location_body">"Auf Ihren Standort wird nicht zugegriffen. Die Standort-Erlaubnis wird benötigt, da Google bzw. Android diese für die Verwendung von Bluetooth voraussetzt."</string> + <string name="settings_tracing_status_location_body">"Aktivieren Sie die Standort-Dienste. Für die Abstandsberechnung benötigt Bluetooth Low Energy aktivierte Standort-Dienste, greift dabei aber nicht auf Ihren Standort zu. Weitere Informationen finden Sie in der FAQ."</string> + <!-- XTXT: settings(tracing) - explains user what to do on card if location is disabled: URL --> + <string name="settings_tracing_status_location_body_url">https://www.coronawarn.app/de/faq/#android_location</string> <!-- XBUT: settings(tracing) - go to operating system settings button on card - location --> <string name="settings_tracing_status_location_button">"Geräte-Einstellungen öffnen"</string> <!--XHED : settings(tracing) - headline on card about the current status and what to do --> @@ -742,10 +742,14 @@ <!-- XBUT: Positive button for generic web request error --> <string name="submission_error_dialog_web_generic_error_button_positive">"Zurück"</string> - <!-- XHED: Dialog title for already paired test error --> + <!-- XHED: Dialog title for already paired test error: qr --> <string name="submission_error_dialog_web_test_paired_title">"QR-Code ist ungültig"</string> - <!-- XMSG: Dialog body for already paired test error --> + <!-- XMSG: Dialog body for already paired test error: qr --> <string name="submission_error_dialog_web_test_paired_body">"Der QR-Code ist ungültig oder wurde bereits auf einem Smartphone registriert. Ihr Testergebnis bekommen Sie vom Testcenter oder Labor, unabhängig von der Gültigkeit des QR-Codes. Wenn Ihr Test positiv ausfällt, bekommen Sie vom Gesundheitsamt eine Mitteilung."</string> + <!-- XHED: Dialog title for already paired test error: tan --> + <string name="submission_error_dialog_web_test_paired_title_tan">"TAN ist ungültig"</string> + <!-- XMSG: Dialog body for already paired test via tan - error: tan --> + <string name="submission_error_dialog_web_test_paired_body_tan">"Die TAN ist ungültig oder wurde bereits verwendet. Bitte rufen Sie die unter „TAN anfragen" angegebene Nummer an, um weitere Informationen zu erhalten."</string> <!-- XBUT: Positive button for already paired test error --> <string name="submission_error_dialog_web_test_paired_button_positive">"Zurück"</string> @@ -770,6 +774,15 @@ <!-- XBUT: Positive button for submission tan redeemed --> <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string> + <!-- XHED: Dialog title for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_title">"Wollen Sie wirklich abbrechen?"</string> + <!-- XMSG: Dialog body for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_body">"Ihre bisherigen Angaben werden nicht gespeichert."</string> + <!-- XBUT: Positive button for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_button_positive">"Ja"</string> + <!-- XBUT: Negative button for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_button_negative">"Nein"</string> + <!-- Permission Rationale Dialog --> <!-- XHED: Dialog headline QR Scan permission rationale --> <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Kamera-Zugriff benötigt"</string> @@ -1098,7 +1111,7 @@ <!-- XTXT: error dialog - detailed text if there is an error during external navigation / external action --> <string name="errors_external_action">"Diese Aktion ist aktuell leider nicht verfügbar. Bitte kontaktieren Sie die Hotline."</string> <!-- XTXT: error dialog - phone still needs Google Play Services or Google Mobile Services update --> - <string name="errors_google_update_needed">"Ihre Corona-Warn-App ist korrekt installiert. Leider fehlt dem Betriebssystem Ihres Smartphones der Dienst „Benachrichtigungen zu möglicher Begegnung mit COVID-19-Infizierten“ und Sie können die Corona-Warn-App nicht nutzen. Weitere Informationen finden Sie in unseren FAQ: https://www.coronawarn.app/de/faq/"</string> + <string name="errors_google_update_needed">"Ihre Corona-Warn-App ist korrekt installiert. Leider fehlt dem Betriebssystem Ihres Smartphones der Dienst „COVID-19-Benachrichtigungen“ und Sie können die Corona-Warn-App nicht nutzen. Weitere Informationen finden Sie in unseren FAQ: https://www.coronawarn.app/de/faq/"</string> <!-- XTXT: error dialog - either Google API Error (10) or reached request limit per day --> <string name="errors_google_api_error">"Ihre Corona-Warn-App läuft fehlerfrei. Leider können Sie Ihren Risikostatus im Moment nicht aktualisieren. Ihre Risiko-Ermittlung ist weiterhin aktiv und funktioniert. Weitere Informationen finden Sie in unseren FAQ: https://www.coronawarn.app/de/faq/"</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 c146b8aa881f4e272cb2224c908b57f9d6929c83..1cea318c8050ccf66aef881f190c159ee1ba8cca 100644 --- a/Corona-Warn-App/src/main/res/values-en/strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/strings.xml @@ -135,8 +135,6 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"No exposure up to now"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"No exposure with low risk so far"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> <item quantity="one">"%1$s exposure with low risk"</item> 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 b3e9f2891ffb33bb326dadbf7fe88cbf299aafb9..ee8a348dc7fbb995706322514d4fb96a18dacab1 100644 --- a/Corona-Warn-App/src/main/res/values-pl/strings.xml +++ b/Corona-Warn-App/src/main/res/values-pl/strings.xml @@ -135,8 +135,6 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"Brak narażenia do tej pory"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"Brak narażenia z niskim ryzykiem do tej pory"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> <item quantity="one">"%1$s narażenie z niskim ryzykiem"</item> 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 37fcbdc96308cee1b171109d92c1725113f59d13..a38d1fc6e6e39a509c0ffce0a13855905460cd66 100644 --- a/Corona-Warn-App/src/main/res/values-ro/strings.xml +++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml @@ -135,8 +135,6 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"Nicio expunere până acum"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"Nicio expunere cu risc redus până acum"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> <item quantity="one">"%1$s expunere cu risc redus"</item> 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 bd2d1c01f20e46fb45137978b73cd393bb0ec25e..0b5195ad18370c52bcfc538eebe18a445c0743c9 100644 --- a/Corona-Warn-App/src/main/res/values-tr/strings.xml +++ b/Corona-Warn-App/src/main/res/values-tr/strings.xml @@ -135,8 +135,6 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"Åžu ana dek hiçbir maruz kalma yok"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"Åžu ana dek hiçbir düşük riskli maruz kalma yok"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> <item quantity="one">"%1$s kez düşük riskli maruz kalma"</item> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index bbd25903b5a0341f6c5f372d9c9ba0624881675d..8ac46316b8176e0b3bbb9f6fc6d5c097cbc7bf9f 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -137,8 +137,6 @@ <!-- XTXT: risk card - no contact yet --> <string name="risk_card_body_contact">"No exposure up to now"</string> - <!-- XTXT: risk card - no exposures with low risk --> - <string name="risk_card_body_contact_low_risk">"No exposure with low risk so far"</string> <!-- XTXT: risk card - number of contacts for one or more --> <plurals name="risk_card_body_contact_value"> <item quantity="one">"%1$s exposure with low risk"</item> @@ -546,6 +544,8 @@ <string name="settings_tracing_status_location_headline">"Allow location access"</string> <!-- XTXT: settings(tracing) - explains user what to do on card if location is disabled --> <string name="settings_tracing_status_location_body">"Your location cannot be accessed. Google and/or Android requires access to your device\'s location to use Bluetooth."</string> + <!-- XTXT: settings(tracing) - explains user what to do on card if location is disabled: URL --> + <string name="settings_tracing_status_location_body_url"/> <!-- XBUT: settings(tracing) - go to operating system settings button on card - location --> <string name="settings_tracing_status_location_button">"Open Device Settings"</string> <!--XHED : settings(tracing) - headline on card about the current status and what to do --> @@ -748,6 +748,10 @@ <string name="submission_error_dialog_web_test_paired_title">"QR code is invalid"</string> <!-- XMSG: Dialog body for already paired test error --> <string name="submission_error_dialog_web_test_paired_body">"The QR code is invalid or has been registered on another smartphone already. You will receive your test result from the test center or laboratory regardless of the validity of the QR code. If you are diagnosed with COVID-19, you will be notified by the public health authority."</string> + <!-- XHED: Dialog title for already paired test error: tan --> + <string name="submission_error_dialog_web_test_paired_title_tan" /> + <!-- XMSG: Dialog body for already paired test via tan - error: tan --> + <string name="submission_error_dialog_web_test_paired_body_tan" /> <!-- XBUT: Positive button for already paired test error --> <string name="submission_error_dialog_web_test_paired_button_positive">"Back"</string> @@ -772,6 +776,15 @@ <!-- XBUT: Positive button for submission tan redeemed --> <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string> + <!-- XHED: Dialog title for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_title">"Wollen Sie wirklich abbrechen?"</string> + <!-- XMSG: Dialog body for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_body">"Ihre bisherigen Angaben werden nicht gespeichert."</string> + <!-- XBUT: Positive button for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_button_positive">"Ja"</string> + <!-- XBUT: Negative button for keys submission process cancellation --> + <string name="submission_error_dialog_confirm_cancellation_button_negative">"Nein"</string> + <!-- Permission Rationale Dialog --> <!-- XHED: Dialog headline QR Scan permission rationale --> <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Camera authorization required"</string> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleAPIVersionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleAPIVersionTest.kt index 7667cb60400afae27e682d58f46a28007c610242..581282e966e84ea61492fcbb3dd4ad20e198ab2b 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleAPIVersionTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/GoogleAPIVersionTest.kt @@ -38,7 +38,7 @@ internal class GoogleAPIVersionTest { coEvery { InternalExposureNotificationClient.getVersion() } returns 17000000L runBlockingTest { - classUnderTest.isAbove(GoogleAPIVersion.V16) shouldBe true + classUnderTest.isAtLeast(GoogleAPIVersion.V16) shouldBe true } } @@ -48,7 +48,7 @@ internal class GoogleAPIVersionTest { coEvery { InternalExposureNotificationClient.getVersion() } returns 15000000L runBlockingTest { - classUnderTest.isAbove(GoogleAPIVersion.V16) shouldBe false + classUnderTest.isAtLeast(GoogleAPIVersion.V16) shouldBe false } } @@ -56,7 +56,7 @@ internal class GoogleAPIVersionTest { fun `isAbove API v16 throws IllegalArgument for invalid version`() { assertThrows<IllegalArgumentException> { runBlockingTest { - classUnderTest.isAbove(1L) + classUnderTest.isAtLeast(1L) } coVerify { InternalExposureNotificationClient.getVersion() wasNot Called @@ -70,7 +70,7 @@ internal class GoogleAPIVersionTest { ApiException(Status(API_NOT_CONNECTED)) runBlockingTest { - classUnderTest.isAbove(GoogleAPIVersion.V16) shouldBe false + classUnderTest.isAtLeast(GoogleAPIVersion.V16) shouldBe false } } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt index 2eea80e2d9b6964bdc5b772732a4e36702805630..46786d0d90d29ee08a82c9e88dbeeb2a9663ecc3 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelperTest.kt @@ -95,7 +95,6 @@ class FormatterRiskHelperTest { private fun formatRiskContactBase(iRiskLevelScore: Int?, iMatchedKeysCount: Int?, sValue: String) { every { context.getString(R.string.risk_card_body_contact) } returns R.string.risk_card_body_contact.toString() - every { context.getString(R.string.risk_card_body_contact_low_risk) } returns R.string.risk_card_body_contact_low_risk.toString() val result = formatRiskContact(riskLevelScore = iRiskLevelScore, matchedKeysCount = iMatchedKeysCount) assertThat( @@ -105,7 +104,6 @@ class FormatterRiskHelperTest { private fun formatRiskContactLastBase(iRiskLevelScore: Int?, iDaysSinceLastExposure: Int?, sValue: String) { every { context.getString(R.string.risk_card_body_contact) } returns R.string.risk_card_body_contact.toString() - every { context.getString(R.string.risk_card_body_contact_low_risk) } returns R.string.risk_card_body_contact_low_risk.toString() val result = formatRiskContactLast(riskLevelScore = iRiskLevelScore, daysSinceLastExposure = iDaysSinceLastExposure) @@ -584,7 +582,7 @@ class FormatterRiskHelperTest { formatRiskContactBase( iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK, iMatchedKeysCount = 0, - sValue = context.getString(R.string.risk_card_body_contact_low_risk) + sValue = context.getString(R.string.risk_card_body_contact) ) formatRiskContactBase( iRiskLevelScore = RiskLevelConstants.LOW_LEVEL_RISK,