diff --git a/app/build.gradle b/app/build.gradle index 2189643..f6a13d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -141,6 +141,9 @@ dependencies { implementation 'com.google.zxing:core:3.4.1' implementation 'com.journeyapps:zxing-android-embedded:4.3.0' implementation "com.google.android.material:material:1.9.0" + implementation "com.google.android.play:core:1.10.3" + implementation "com.google.android.play:app-update-ktx:2.1.0" + implementation "com.google.android.play:app-update:2.1.0" deps.implementation.each { name, dep -> implementation dep } diff --git a/app/src/main/java/com/jnj/vaccinetracker/playstore/AppActivity.kt b/app/src/main/java/com/jnj/vaccinetracker/playstore/AppActivity.kt new file mode 100644 index 0000000..b4cc43a --- /dev/null +++ b/app/src/main/java/com/jnj/vaccinetracker/playstore/AppActivity.kt @@ -0,0 +1,34 @@ +package com.jnj.vaccinetracker.playstore + +import com.google.android.play.core.appupdate.AppUpdateManager +import com.google.android.play.core.appupdate.AppUpdateManagerFactory +import com.jnj.vaccinetracker.R + +class HomeActivity : AppCompatActivity() { + + private lateinit var appUpdateManager: AppUpdateManager + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + appUpdateManager = AppUpdateManagerFactory.create(this) + checkForAppUpdates(appUpdateManager) + } + + override fun onResume() { + super.onResume() + setupAppUpdateListeners(appUpdateManager) + } + + override fun onDestroy() { + super.onDestroy() + unregisterAppUpdateListeners(appUpdateManager) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if(requestCode == APP_UPDATE_REQUEST_CODE && resultCode != RESULT_OK){ + toastError(getString(R.string.str_app_update_fail)) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/jnj/vaccinetracker/playstore/PlayStoreAppUpdateUtil.kt b/app/src/main/java/com/jnj/vaccinetracker/playstore/PlayStoreAppUpdateUtil.kt new file mode 100644 index 0000000..db71301 --- /dev/null +++ b/app/src/main/java/com/jnj/vaccinetracker/playstore/PlayStoreAppUpdateUtil.kt @@ -0,0 +1,118 @@ +package com.jnj.vaccinetracker.playstore + +import android.app.Activity +import com.google.android.material.snackbar.Snackbar +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.appupdate.AppUpdateOptions +import com.google.android.play.core.install.model.AppUpdateType +import com.google.android.play.core.install.model.InstallStatus +import com.google.android.play.core.install.model.UpdateAvailability +import com.google.android.play.core.listener.InstallStateUpdatedListener +import com.google.android.play.core.tasks.Task +import javax.inject.Inject + +class PlayStoreAppUpdateUtil @Inject constructor() { + + companion object { + const val APP_UPDATE_REQUEST_CODE = 100 + } + + private lateinit var appUpdateManager: AppUpdateManager + + private fun getUpdateType(): Int { + return AppUpdateType.FLEXIBLE + } + + fun checkForAppUpdates(activity: Activity) { + appUpdateManager = AppUpdateManagerFactory.create(activity) + val appUpdateInfoTask: Task = appUpdateManager.appUpdateInfo + + appUpdateInfoTask.addOnSuccessListener { info -> + val isUpdateAvailable = info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE + val isUpdateAllowed = when (getUpdateType()) { + AppUpdateType.FLEXIBLE -> info.isFlexibleUpdateAllowed + AppUpdateType.IMMEDIATE -> info.isImmediateUpdateAllowed + else -> false + } + + if (isUpdateAvailable && isUpdateAllowed) { + activity.requestAppUpdate(appUpdateManager, info, getUpdateType()) + } + } + } + + fun setupAppUpdateListeners(activity: Activity) { + val updateType = getUpdateType() + + when (updateType) { + AppUpdateType.FLEXIBLE -> activity.setupFlexibleUpdateSuccessListener(appUpdateManager) + AppUpdateType.IMMEDIATE -> activity.setupImmediateUpdateSuccessListener(appUpdateManager) + } + + if (updateType == AppUpdateType.FLEXIBLE) { + appUpdateManager.registerListener(activity.getInstallStateUpdateListener(appUpdateManager)) + } + } + + fun unregisterAppUpdateListeners(activity: Activity) { + if (getUpdateType() == AppUpdateType.FLEXIBLE) { + appUpdateManager.unregisterListener(activity.getInstallStateUpdateListener(appUpdateManager)) + } + } +} + +// Extensions for Activity +private fun Activity.requestAppUpdate( + appUpdateManager: AppUpdateManager, + appUpdateInfo: AppUpdateInfo, + updateType: Int +) { + try { + appUpdateManager.startUpdateFlowForResult( + appUpdateInfo, + this, + AppUpdateOptions.newBuilder(updateType).build(), + PlayStoreAppUpdateUtil.APP_UPDATE_REQUEST_CODE + ) + } catch (e: Exception) { + e.printStackTrace() + } +} + +private fun Activity.setupImmediateUpdateSuccessListener(appUpdateManager: AppUpdateManager) { + appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo -> + if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) { + requestAppUpdate(appUpdateManager, appUpdateInfo, AppUpdateType.IMMEDIATE) + } + } +} + +private fun Activity.setupFlexibleUpdateSuccessListener(appUpdateManager: AppUpdateManager) { + appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo -> + if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) { + showInstallSnackBar(appUpdateManager) + } + } +} + +private fun Activity.getInstallStateUpdateListener(appUpdateManager: AppUpdateManager) = + InstallStateUpdatedListener { + if (it.installStatus() == InstallStatus.DOWNLOADED) { + this.showInstallSnackBar(appUpdateManager) + } + } + +private fun Activity.showInstallSnackBar(appUpdateManager: AppUpdateManager) { + Snackbar.make( + findViewById(android.R.id.content), + getString(R.string.str_download_complete), + Snackbar.LENGTH_INDEFINITE + ).apply { + setAction(getString(R.string.str_restart)) { + appUpdateManager.completeUpdate() + } + show() + } +}