diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index b726e91e1..8a7234ee8 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -200,6 +200,8 @@ dependencies { implementation(platform(libs.firebase.bom)) implementation(libs.firebase.crashlytics.buildtools) implementation(libs.bundles.firebase) + implementation(libs.app.update) + implementation(libs.app.update.ktx) // android test androidTestImplementation(libs.bundles.android.test) androidTestRuntimeOnly(libs.junit5.android.test.runner) diff --git a/android/app/src/main/java/poke/rogue/helper/presentation/home/HomeActivity.kt b/android/app/src/main/java/poke/rogue/helper/presentation/home/HomeActivity.kt index 16f08b0c7..9c2c7151f 100644 --- a/android/app/src/main/java/poke/rogue/helper/presentation/home/HomeActivity.kt +++ b/android/app/src/main/java/poke/rogue/helper/presentation/home/HomeActivity.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar import poke.rogue.helper.R @@ -22,20 +23,47 @@ import poke.rogue.helper.presentation.util.context.stringOf import poke.rogue.helper.presentation.util.context.toast import poke.rogue.helper.presentation.util.logClickEvent import poke.rogue.helper.presentation.util.repeatOnStarted +import poke.rogue.helper.update.UpdateManager +import timber.log.Timber class HomeActivity : ToolbarActivity(R.layout.activity_home) { private val viewModel by viewModels() private val logger: AnalyticsLogger = analyticsLogger() + private lateinit var updateManager: UpdateManager override val toolbar: Toolbar get() = binding.toolbarHome override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + initUpdateManager() initViews() initObservers() } + override fun onDestroy() { + super.onDestroy() + updateManager.unregisterInstallStateUpdateListener() + } + + private fun initUpdateManager() { + updateManager = UpdateManager(applicationContext) + updateManager.registerInstallStateUpdateListener() + + val appUpdateLauncher = + registerForActivityResult( + ActivityResultContracts.StartIntentSenderForResult(), + ) { result -> + // logger도 달아야겠죠?? + if (result.resultCode == RESULT_OK) { + Timber.i("Update completed successfully") + } else { + Timber.e("Update failed, result code: ${result.resultCode}") + } + } + updateManager.checkForAppUpdates(appUpdateLauncher) + } + private fun initViews() = with(binding) { supportActionBar?.setDisplayShowTitleEnabled(false) diff --git a/android/app/src/main/java/poke/rogue/helper/update/UpdateManager.kt b/android/app/src/main/java/poke/rogue/helper/update/UpdateManager.kt new file mode 100644 index 000000000..cc0eca2ef --- /dev/null +++ b/android/app/src/main/java/poke/rogue/helper/update/UpdateManager.kt @@ -0,0 +1,62 @@ +package poke.rogue.helper.update + +import android.content.Context +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.IntentSenderRequest +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.InstallStateUpdatedListener +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 timber.log.Timber + +class UpdateManager( + private val context: Context, +) { + private val appUpdateManager: AppUpdateManager = AppUpdateManagerFactory.create(context) + private val updateType = AppUpdateType.FLEXIBLE + + private val installStateUpdateListener = + InstallStateUpdatedListener { state -> + when (state.installStatus()) { + InstallStatus.INSTALLING -> Timber.i("Update is downloading") + + InstallStatus.DOWNLOADED -> { + Timber.i("Update installed successfully") + appUpdateManager.completeUpdate() + } + + InstallStatus.CANCELED -> Timber.e("Update was cancelled") + } + } + + fun checkForAppUpdates(appUpdateLauncher: ActivityResultLauncher) { + appUpdateManager.appUpdateInfo.addOnSuccessListener { info -> + if (checkForAppUpdate(info)) { + val updateOptions = AppUpdateOptions.newBuilder(updateType).build() + appUpdateManager.startUpdateFlowForResult( + info, + appUpdateLauncher, + updateOptions, + ) + } + } + } + + private fun checkForAppUpdate(info: AppUpdateInfo): Boolean { + val isUpdateAvailable = info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE + val isUpdateAllowed = info.isUpdateTypeAllowed(updateType) + return isUpdateAvailable && isUpdateAllowed + } + + fun registerInstallStateUpdateListener() { + appUpdateManager.registerListener(installStateUpdateListener) + } + + fun unregisterInstallStateUpdateListener() { + appUpdateManager.unregisterListener(installStateUpdateListener) + } +} diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index 91fe7289d..dd647aec2 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -37,6 +37,7 @@ datastore = "1.0.0" google-services = "4.4.2" firebase = "33.1.2" firebase-crashlytics = "3.0.2" +app-update = "2.1.0" # Android-Test android-junit5-plugin = "1.10.0.0" @@ -89,6 +90,8 @@ firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "fir firebase-analytics = { module = "com.google.firebase:firebase-analytics-ktx" } firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx" } firebase-crashlytics-plugin = { module = "com.google.firebase:firebase-crashlytics-gradle", version.ref = "firebase-crashlytics" } +app-update = { module = "com.google.android.play:app-update", version.ref = "app-update" } +app-update-ktx = { module = "com.google.android.play:app-update-ktx", version.ref = "app-update" } # android test androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-junit" } android-test-fragment = { module = "androidx.fragment:fragment-testing", version.ref = "androidx-test-fragment" }