From 40e72d50d1994f14b003449bd8ece89b43d10fcd Mon Sep 17 00:00:00 2001 From: Hee Tatt Ooi <hee.tatt.ooi@sap.com> Date: Wed, 10 Jun 2020 17:06:34 +0200 Subject: [PATCH] use direct link to google play store for update (#357) --- .../rki/coronawarnapp/ui/LauncherActivity.kt | 13 +- .../rki/coronawarnapp/update/UpdateChecker.kt | 124 +++++------------- 2 files changed, 34 insertions(+), 103 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/LauncherActivity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/LauncherActivity.kt index 45b78f063..2c4daee38 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/LauncherActivity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/LauncherActivity.kt @@ -1,7 +1,6 @@ package de.rki.coronawarnapp.ui import android.content.Intent -import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import de.rki.coronawarnapp.storage.LocalData @@ -17,21 +16,15 @@ class LauncherActivity : AppCompatActivity() { private lateinit var updateChecker: UpdateChecker - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - updateChecker = UpdateChecker(this) + override fun onResume() { + super.onResume() + updateChecker = UpdateChecker(this) lifecycleScope.launch { updateChecker.checkForUpdate() } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - - updateChecker.onActivityResult(requestCode, resultCode) - } - fun navigateToActivities() { if (LocalData.isOnboarded()) { startMainActivity() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/update/UpdateChecker.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/update/UpdateChecker.kt index 0e4c32b13..580cdb81c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/update/UpdateChecker.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/update/UpdateChecker.kt @@ -1,16 +1,9 @@ package de.rki.coronawarnapp.update -import android.app.Activity.RESULT_CANCELED -import android.app.Activity.RESULT_OK -import android.content.IntentSender.SendIntentException -import android.widget.Toast +import android.content.Intent +import android.net.Uri import androidx.appcompat.app.AlertDialog -import com.google.android.play.core.appupdate.AppUpdateInfo -import com.google.android.play.core.appupdate.AppUpdateManager -import com.google.android.play.core.appupdate.AppUpdateManagerFactory -import com.google.android.play.core.install.model.ActivityResult.RESULT_IN_APP_UPDATE_FAILED -import com.google.android.play.core.install.model.AppUpdateType -import com.google.android.play.core.install.model.UpdateAvailability +import androidx.core.content.ContextCompat.startActivity import de.rki.coronawarnapp.BuildConfig import de.rki.coronawarnapp.R import de.rki.coronawarnapp.exception.CwaSecurityException @@ -18,15 +11,14 @@ import de.rki.coronawarnapp.server.protocols.ApplicationConfigurationOuterClass import de.rki.coronawarnapp.service.applicationconfiguration.ApplicationConfigurationService import de.rki.coronawarnapp.ui.LauncherActivity import timber.log.Timber -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException -import kotlin.coroutines.suspendCoroutine class UpdateChecker(private val activity: LauncherActivity) { companion object { val TAG: String? = UpdateChecker::class.simpleName - private const val REQUEST_CODE = 100 + + const val STORE_PREFIX = "https://play.google.com/store/apps/details?id=" + const val COM_ANDROID_VENDING = "com.android.vending" } suspend fun checkForUpdate() { @@ -35,106 +27,62 @@ class UpdateChecker(private val activity: LauncherActivity) { val updateNeededFromServer: Boolean = try { checkIfUpdatesNeededFromServer() } catch (exception: CwaSecurityException) { - Timber.e("CwaSecurityException caught:$exception.localizedMessage") + Timber.e("CwaSecurityException caught:%s", exception.localizedMessage) true } catch (exception: Exception) { - Timber.e("Exception caught:$exception.localizedMessage") - false - } - - // get AppUpdateManager - val baseContext = activity.baseContext - val appUpdateManager = AppUpdateManagerFactory.create(baseContext) - - var appUpdateInfo: AppUpdateInfo? = null - - val updateAvailableFromGooglePlay = try { - appUpdateInfo = checkForGooglePlayUpdate(appUpdateManager) - - val availability = appUpdateInfo.updateAvailability() - val immediateUpdateAllowed = - appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) - - availability == UpdateAvailability.UPDATE_AVAILABLE && immediateUpdateAllowed - } catch (exception: Exception) { + Timber.e("Exception caught:%s", exception.localizedMessage) false } - if (updateNeededFromServer && updateAvailableFromGooglePlay && appUpdateInfo != null) { - Timber.i("show update dialog") - showUpdateAvailableDialog(appUpdateManager, appUpdateInfo) + if (updateNeededFromServer) { + showUpdateNeededDialog() } else { activity.navigateToActivities() } } - private fun showUpdateAvailableDialog( - appUpdateManager: AppUpdateManager, - appUpdateInfo: AppUpdateInfo - ) { + /** + * Show dialog there an update is needed and links to the play store + */ + private fun showUpdateNeededDialog() { AlertDialog.Builder(activity) .setTitle(activity.getString(R.string.update_dialog_title)) .setMessage(activity.getString(R.string.update_dialog_message)) + .setCancelable(false) .setPositiveButton(activity.getString(R.string.update_dialog_button)) { _, _ -> - startGooglePlayUpdateFlow(appUpdateManager, appUpdateInfo) - } - .create().show() - } - - private fun startGooglePlayUpdateFlow( - appUpdateManager: AppUpdateManager, - appUpdateInfo: AppUpdateInfo - ) { - try { - appUpdateManager.startUpdateFlowForResult( - appUpdateInfo, - AppUpdateType.IMMEDIATE, - activity, - REQUEST_CODE - ) - } catch (exception: SendIntentException) { - Timber.i(exception.toString()) - } - } - fun onActivityResult(requestCode: Int, resultCode: Int) { - if (REQUEST_CODE == requestCode) { - - // TODO react to these - when (resultCode) { - RESULT_OK -> { - Timber.i("startFlowResult RESULT_OK") - activity.navigateToActivities() - } - RESULT_CANCELED -> { - Timber.i("startFlowResult RESULT_CANCELED") - } - RESULT_IN_APP_UPDATE_FAILED -> { - Timber.i("startFlowResult RESULT_IN_APP_UPDATE_FAILED") - val toast = Toast.makeText(activity, "In app update failed", Toast.LENGTH_LONG) - toast.show() - activity.navigateToActivities() + val uriStringInPlayStore = STORE_PREFIX + BuildConfig.APPLICATION_ID + val intent = Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse( + uriStringInPlayStore + ) + setPackage(COM_ANDROID_VENDING) } + startActivity(activity, intent, null) } - } + .create().show() } private suspend fun checkIfUpdatesNeededFromServer(): Boolean { - val applicationConfigurationFromServer = ApplicationConfigurationService.asyncRetrieveApplicationConfiguration() val minVersionFromServer = applicationConfigurationFromServer.appVersion.android.min val minVersionFromServerString = constructSemanticVersionString(minVersionFromServer) - Timber.i("minVersionStringFromServer:${constructSemanticVersionString(minVersionFromServer)}") - Timber.i("Current app version:${BuildConfig.VERSION_NAME}") + + Timber.e( + "minVersionStringFromServer:%s", constructSemanticVersionString( + minVersionFromServer + ) + ) + Timber.e("Current app version:%s", BuildConfig.VERSION_NAME) val needsImmediateUpdate = VersionComparator.isVersionOlder( BuildConfig.VERSION_NAME, minVersionFromServerString ) - Timber.i("needs update:$needsImmediateUpdate") + Timber.e("needs update:$needsImmediateUpdate") return true } @@ -145,14 +93,4 @@ class UpdateChecker(private val activity: LauncherActivity) { semanticVersion.minor.toString() + "." + semanticVersion.patch.toString() } - - private suspend fun checkForGooglePlayUpdate(appUpdateManager: AppUpdateManager) = - suspendCoroutine<AppUpdateInfo> { cont -> - val appUpdateInfoTask = appUpdateManager.appUpdateInfo - appUpdateInfoTask.addOnSuccessListener { - cont.resume(it) - }.addOnFailureListener { - cont.resumeWithException(it) - } - } } -- GitLab