androidandroid-update-app

In-app update - infinite loop, even after restarting the app


I'm trying to implement in app update

But the issue that when I test it I get the infinite installing which never ends, I press back button, it returns back to main screen of the app and instantly displaying update screen again with infinite installing, restarting the app (including force stop), clearing the date + cache doesn't help - the update screen will popup again:

enter image description here

The code I use:

class InAppUpdateTestHelper(
    private val activity: Activity,
    lifecycleOwner: LifecycleOwner,
    private val startUpdateFlowForResult: ActivityResultLauncher<IntentSenderRequest>,
) {
    private val appUpdateManager by lazy { AppUpdateManagerFactory.create(activity) }

    init {
        try {
            val defaultLifecycleObserver = object : DefaultLifecycleObserver {
                override fun onResume(owner: LifecycleOwner) {
                    checkIfAppUpdateInProgress()
                }
            }
            lifecycleOwner.lifecycle.addObserver(defaultLifecycleObserver)
        } catch (e: Throwable) {
            e.printStackTrace()
        }
        forceUpdate()
    }

    private fun forceUpdate() {
        try {
            appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
                try {
                    val updateAvailable =
                        appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE

                    val isUpdateImmediateAllowed =
                        appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)

                    if (updateAvailable && isUpdateImmediateAllowed) {
                        appUpdateManager.startUpdateFlowForResult(
                            appUpdateInfo,
                            // an activity result launcher registered via registerForActivityResult
                            startUpdateFlowForResult,
                            AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE)
                                .build()
                        )
                    }
                } catch (e: Throwable) {
                    e.printStackTrace()
                }
            }.addOnFailureListener {
                Timber.e("appUpdateInfo addOnFailureListener ${it.message}")
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    private fun checkIfAppUpdateInProgress() {
        val startUpdateFlowForResult = startUpdateFlowForResult ?: return
        try {
            appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
                if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
                    try {
                        appUpdateManager.startUpdateFlowForResult(
                            appUpdateInfo,
                            // an activity result launcher registered via registerForActivityResult
                            startUpdateFlowForResult,
                            AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE)
                                .build()
                        )
                    } catch (e: Throwable) {
                        e.printStackTrace()
                    }
                }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }
}

the docs says that I should check if app is in update progress onResume, that's why I use DefaultLifecycleObserver. lifecycleOwner comes from activity:

private val startUpdateFlowForResult =
    registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
        // handle callback
        if (DEBUG) {
            val resultCode = result.resultCode
            Timber.d("startUpdateFlowForResult $resultCode")
        }
    }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    inAppUpdateTestHelper = InAppUpdateTestHelper(
        activity = this,
        lifecycleOwner = this,
        startUpdateFlowForResult = startUpdateFlowForResult,
    )
}

So what am I doing wrong here?

Update:

I was testing on Samsung S22 Android 14.

Then I tried Samsung S10 Android 12 and finally it worked fine.

I even tried to clear data + cache for Google Play on Samsung S22 Android 14 but still infinite installation...

Need to test Pixel Emulator on Android 14 then...


Solution

  • It was fixed somehow, mb a temporary issue, I don't remember exactly. But no code changes were needed. So it's on Google Play side anyway.

    Or at least it works fine if updating from release version instead of play link for internal testers