Skip to content
Snippets Groups Projects
Unverified Commit 40e72d50 authored by Hee Tatt Ooi's avatar Hee Tatt Ooi Committed by GitHub
Browse files

use direct link to google play store for update (#357)

parent 1cd7e534
No related branches found
No related tags found
No related merge requests found
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()
......
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)
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment