Migrate to separate app-update and review artifacts from play:core (#2336)

This commit is contained in:
Rafał Borcz 2023-10-27 14:09:42 +02:00 committed by GitHub
parent 25ac171298
commit 1dbaa8bfdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 85 deletions

View File

@ -253,10 +253,10 @@ dependencies {
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.firebase:firebase-config-ktx'
playImplementation 'com.google.android.play:core:1.10.3'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
playImplementation 'com.google.android.gms:play-services-ads:22.4.0'
playImplementation "com.google.android.play:integrity:1.2.0"
playImplementation 'com.google.android.play:app-update-ktx:2.1.0'
playImplementation 'com.google.android.play:review-ktx:2.0.1'
hmsImplementation 'com.huawei.hms:hianalytics:6.12.0.300'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.9.1.301'

View File

@ -0,0 +1,13 @@
package io.github.wulkanowy.utils
import android.view.View
import javax.inject.Inject
class InAppUpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates() {}
fun onResume() {}
}

View File

@ -1,17 +0,0 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View File

@ -0,0 +1,13 @@
package io.github.wulkanowy.utils
import android.view.View
import javax.inject.Inject
class InAppUpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates() {}
fun onResume() {}
}

View File

@ -1,17 +0,0 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View File

@ -23,7 +23,7 @@ import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.notifications.NotificationsFragment
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.UpdateHelper
import io.github.wulkanowy.utils.InAppUpdateHelper
import javax.inject.Inject
@AndroidEntryPoint
@ -33,7 +33,7 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
override lateinit var presenter: LoginPresenter
@Inject
lateinit var updateHelper: UpdateHelper
lateinit var inAppUpdateHelper: InAppUpdateHelper
@Inject
lateinit var appInfo: AppInfo
@ -47,10 +47,10 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
setContentView(ActivityLoginBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.loginToolbar)
messageContainer = binding.loginContainer
updateHelper.messageContainer = binding.loginContainer
inAppUpdateHelper.messageContainer = binding.loginContainer
presenter.onAttachView(this)
updateHelper.checkAndInstallUpdates(this)
inAppUpdateHelper.checkAndInstallUpdates()
if (savedInstanceState == null) {
openFragment(LoginFormFragment.newInstance(), clearBackStack = true)
@ -117,14 +117,6 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
override fun onResume() {
super.onResume()
updateHelper.onResume(this)
}
//https://developer.android.com/guide/playcore/in-app-updates#status_callback
@Deprecated("Deprecated in Java")
@Suppress("DEPRECATION")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
updateHelper.onActivityResult(requestCode, resultCode)
inAppUpdateHelper.onResume()
}
}

View File

@ -45,7 +45,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
lateinit var analytics: AnalyticsHelper
@Inject
lateinit var updateHelper: UpdateHelper
lateinit var inAppUpdateHelper: InAppUpdateHelper
@Inject
lateinit var inAppReviewHelper: InAppReviewHelper
@ -100,7 +100,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
this.savedInstanceState = savedInstanceState
messageContainer = binding.mainMessageContainer
messageAnchor = binding.mainMessageContainer
updateHelper.messageContainer = binding.mainFragmentContainer
inAppUpdateHelper.messageContainer = binding.mainFragmentContainer
onBackCallback = onBackPressedDispatcher.addCallback(this, enabled = false) {
presenter.onBackPressed()
}
@ -109,19 +109,12 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
?.takeIf { savedInstanceState == null }
presenter.onAttachView(this, destination)
updateHelper.checkAndInstallUpdates(this)
inAppUpdateHelper.checkAndInstallUpdates()
}
override fun onResume() {
super.onResume()
updateHelper.onResume(this)
}
//https://developer.android.com/guide/playcore/in-app-updates#status_callback
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
updateHelper.onActivityResult(requestCode, resultCode)
inAppUpdateHelper.onResume()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {

View File

@ -3,12 +3,15 @@ package io.github.wulkanowy.utils
import android.app.Activity
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.IntentSender
import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import com.google.android.play.core.appupdate.AppUpdateInfo
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.appupdate.AppUpdateOptions
import com.google.android.play.core.install.InstallStateUpdatedListener
import com.google.android.play.core.install.model.AppUpdateType.FLEXIBLE
import com.google.android.play.core.install.model.AppUpdateType.IMMEDIATE
@ -20,15 +23,16 @@ import com.google.android.play.core.ktx.isFlexibleUpdateAllowed
import com.google.android.play.core.ktx.isImmediateUpdateAllowed
import com.google.android.play.core.ktx.updatePriority
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ActivityScoped
import io.github.wulkanowy.R
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class UpdateHelper @Inject constructor(
@ActivityScoped
class InAppUpdateHelper @Inject constructor(
@ApplicationContext private val context: Context,
private val analyticsHelper: AnalyticsHelper,
activity: Activity
) {
lateinit var messageContainer: View
@ -39,6 +43,7 @@ class UpdateHelper @Inject constructor(
when (state.installStatus()) {
PENDING -> Toast.makeText(context, R.string.update_download_started, Toast.LENGTH_SHORT)
.show()
DOWNLOADED -> popupSnackBarForCompleteUpdate()
else -> Timber.d("Update state: ${state.installStatus()}")
}
@ -70,35 +75,46 @@ class UpdateHelper @Inject constructor(
return updateAvailability() == UPDATE_AVAILABLE && isFlexibleUpdateAllowed && isUpdatePriorityAllowUpdate
}
fun checkAndInstallUpdates(activity: Activity) {
private val activityResultLauncher = (activity as AppCompatActivity).registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
::onActivityResult
)
fun checkAndInstallUpdates() {
Timber.d("Checking for updates...")
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
when {
appUpdateInfo.isImmediateUpdateAvailable -> {
startUpdate(activity, appUpdateInfo, IMMEDIATE)
startUpdate(appUpdateInfo, IMMEDIATE)
}
appUpdateInfo.isFlexibleUpdateAvailable -> {
appUpdateManager.registerListener(flexibleUpdateListener)
startUpdate(activity, appUpdateInfo, FLEXIBLE)
startUpdate(appUpdateInfo, FLEXIBLE)
}
else -> Timber.d("No update available")
}
}
}
private fun startUpdate(activity: Activity, appUpdateInfo: AppUpdateInfo, updateType: Int) {
private fun startUpdate(appUpdateInfo: AppUpdateInfo, updateType: Int) {
Timber.d("Start update ($updateType): $appUpdateInfo")
try {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo, updateType, activity, IN_APP_UPDATE_REQUEST_CODE
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.defaultOptions(updateType)
)
} catch (e: IntentSender.SendIntentException) {
Timber.i("Update failed! Duplicated PendingIntent")
} catch (e: Exception) {
Timber.e(e, "Update failed!")
}
}
fun onActivityResult(requestCode: Int, resultCode: Int) {
if (requestCode == IN_APP_UPDATE_REQUEST_CODE) {
private fun onActivityResult(activityResult: ActivityResult) {
val resultCode = activityResult.resultCode
if (resultCode != RESULT_OK) {
Timber.i("Update failed! Result code: $resultCode")
Toast.makeText(context, R.string.update_failed, Toast.LENGTH_LONG).show()
@ -106,9 +122,8 @@ class UpdateHelper @Inject constructor(
analyticsHelper.logEvent("inapp_update", "code" to resultCode)
}
}
fun onResume(activity: Activity) {
fun onResume() {
appUpdateManager.appUpdateInfo.addOnSuccessListener { info ->
Timber.d("InAppUpdate.onResume() listener: $info")
@ -116,7 +131,6 @@ class UpdateHelper @Inject constructor(
DOWNLOADED == info.installStatus() -> popupSnackBarForCompleteUpdate()
DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS == info.updateAvailability() -> {
startUpdate(
activity = activity,
appUpdateInfo = info,
updateType = if (info.isImmediateUpdateAvailable) IMMEDIATE else FLEXIBLE
)
@ -139,9 +153,4 @@ class UpdateHelper @Inject constructor(
show()
}
}
private companion object {
private const val IN_APP_UPDATE_REQUEST_CODE = 1721
}
}