Как обрабатывать обновления внутри приложения. Гибкость при изменении конфигурации?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как обрабатывать обновления внутри приложения. Гибкость при изменении конфигурации?

Сообщение Anonymous »

Есть ли способ сохранить обратные вызовы InstallStateUpdatedListener после изменения конфигурации при использовании гибкого потока с обновлением в приложении? Я пробовал следующее, но обратный вызов для InstallStatus.DOWNLOADED всегда терялся после поворота экрана.
class MainActivity : BaseActivity(),
InstallStateUpdatedListener {

private var isAppUpdateOngoing = false

private lateinit var inAppUpdateDialog: AlertDialog

private lateinit var inAppUpdateResultLauncher: ActivityResultLauncher

private val appUpdateManager by inject()

private val userPreferences by inject()

override val viewModel by viewModel()

override fun bindingInflater(): (LayoutInflater) -> ActivityMainBinding =
ActivityMainBinding::inflate

override fun initViews(binding: ActivityMainBinding) {

// In case where Activity was recreated, reinitialize
inAppUpdateResultLauncher = activityForResultIntentSender { result, _ ->

when (result.resultCode) {
// In flexible flow, the user accepted the request to update.
// In immediate flow, the user accepted and the update succeeded (which, in practice, your app never should never receive because it already updated).
Activity.RESULT_OK -> isAppUpdateOngoing = true

// In flexible flow, the user denied the request to update.
// In immediate flow, the user denied or canceled the update.
Activity.RESULT_CANCELED -> unregisterInAppUpdateListener()

// In flexible flow, something failed during the request for user confirmation. For example, the user terminates the app before responding to the request.
// In immediate flow, the flow failed either during the user confirmation, the download, or the installation.
ActivityResult.RESULT_IN_APP_UPDATE_FAILED -> {
recordException("In-App Update Unknown Failure")
showToast(getString(R.string.unknown_error))
}
}

}

inAppUpdateDialog = materialDialog(
getString(R.string.update_success),
null,
getString(R.string.install_update),
{ dialog, _ ->
appUpdateManager.completeUpdate() // Install updates
dialog.dismiss()
},
null,
null,
false
).create()

}

}

override fun subscribeUI(savedInstanceState: Bundle?) {

// Try to recover the UI state during configuration change or system-initiated process death
isAppUpdateOngoing = savedInstanceState?.getBoolean(AppConfig.IS_APP_UPDATE_ONGOING, false) == true

}

override fun onSaveInstanceState(outState: Bundle) {
// Store the UI state that can survive even a System-initiated system-initiated process death
outState.putBoolean(AppConfig.IS_AD_FETCHED, isAdFetched)
outState.putBoolean(AppConfig.IS_APP_UPDATE_ONGOING, isAppUpdateOngoing)
super.onSaveInstanceState(outState)
}

override fun onStart() {
super.onStart()
if (isAppUpdateOngoing.not()) {
appUpdateManager.checkUpdates(inAppUpdateResultLauncher, this)
}
}

override fun onStop() {
super.onStop()
inAppUpdateDialog.dismiss()
}

override fun onDestroy() {
backPressedCallback.remove()
super.onDestroy()
}

override fun onStateUpdate(state: InstallState) {

when (state.installStatus()) {

InstallStatus.DOWNLOADED -> {

if (isDestroyed.not() && isFinishing.not()) {
inAppUpdateDialog.show()
}

}

InstallStatus.INSTALLED -> {
unregisterInAppUpdateListener()
}

InstallStatus.CANCELED, InstallStatus.FAILED, InstallStatus.UNKNOWN -> {
recordException("In-App Update Failed Status Code: ${state.installErrorCode()}")
unregisterInAppUpdateListener()
}

InstallStatus.DOWNLOADING,
InstallStatus.INSTALLING,
InstallStatus.PENDING -> {
/* no-op */
}

else -> {
recordException("In-App Update Unknown Status Code: ${state.installErrorCode()}")
unregisterInAppUpdateListener()
}

}

}

private fun unregisterInAppUpdateListener() {
appUpdateManager.unregisterListener(this)
}

}

AppUpdateManager расширение
fun AppUpdateManager.checkUpdates(
updateFlowResultLauncher: ActivityResultLauncher,
listener: InstallStateUpdatedListener
) {

val intentSenderForResultStarter =
IntentSenderForResultStarter { intent, _, fillInIntent, flagsMask, flagsValues, _, _ ->
val request = IntentSenderRequest.Builder(intent)
.setFillInIntent(fillInIntent)
.setFlags(flagsValues, flagsMask)
.build()

updateFlowResultLauncher.launch(request)
}

appUpdateInfo.addOnSuccessListener { appUpdateInfo ->

if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {

if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS || (appUpdateInfo.updatePriority >= 4 && appUpdateInfo.isImmediateUpdateAllowed)) {
startUpdateFlowForResult(
appUpdateInfo,
intentSenderForResultStarter,
AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE)
.setAllowAssetPackDeletion(true)
.build(),
DEFAULT_VALUE_INTEGER
)
} else if (appUpdateInfo.isFlexibleUpdateAllowed) {

// Callback to let user manually install the updates
registerListener(listener)

startUpdateFlowForResult(
appUpdateInfo,
intentSenderForResultStarter,
AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE)
.setAllowAssetPackDeletion(true)
.build(),
DEFAULT_VALUE_INTEGER
)

}

}

}

}

Я использую Koin для создания одноэлементного экземпляра AppUpdateManager
single {
AppUpdateManagerFactory.create(androidApplication())
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... ion-change
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»