diff --git a/Stores/build.gradle b/Stores/build.gradle index f63e0fd1..30934cf1 100644 --- a/Stores/build.gradle +++ b/Stores/build.gradle @@ -27,5 +27,11 @@ android { dependencies { implementation project(path: ':Core') - standardImplementation 'com.google.android.play:core:1.10.3' + def appReviewVersion = "2.0.1" + standardImplementation "com.google.android.play:review:$appReviewVersion" + standardImplementation "com.google.android.play:review-ktx:$appReviewVersion" + + def appUpdateVersion = "2.1.0" + standardImplementation "com.google.android.play:app-update:$appUpdateVersion" + standardImplementation "com.google.android.play:app-update-ktx:$appUpdateVersion" } diff --git a/Stores/src/fdroid/java/com.infomaniak.lib.stores/StoreUtils.kt b/Stores/src/fdroid/java/com.infomaniak.lib.stores/StoreUtils.kt index 87da9164..414cc2ba 100644 --- a/Stores/src/fdroid/java/com.infomaniak.lib.stores/StoreUtils.kt +++ b/Stores/src/fdroid/java/com.infomaniak.lib.stores/StoreUtils.kt @@ -17,6 +17,9 @@ */ package com.infomaniak.lib.stores +import android.content.Context +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.IntentSenderRequest import androidx.fragment.app.FragmentActivity import androidx.lifecycle.lifecycleScope import com.infomaniak.lib.core.fdroidTools.FdroidApiTools @@ -24,12 +27,41 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -fun FragmentActivity.checkUpdateIsAvailable(appId: String, versionCode: Int, onResult: (updateIsAvailable: Boolean) -> Unit) { - lifecycleScope.launch { - val lastVersionCode = FdroidApiTools().getLastRelease(appId) +object StoreUtils { - withContext(Dispatchers.Main) { onResult(versionCode < lastVersionCode) } + //region legacy App update + // TODO: Remove this when Ui for kDrive in app update will be made + fun FragmentActivity.checkUpdateIsAvailable(appId: String, versionCode: Int, onResult: (updateIsAvailable: Boolean) -> Unit) { + checkUpdateIsAvailable(appId = appId, versionCode = versionCode, inAppResultLauncher = null, onFDroidResult = onResult) + } + //endRegion + + //region In-App Update + fun initAppUpdateManager(context: Context, onInstall: () -> Unit) = Unit + + fun FragmentActivity.checkUpdateIsAvailable( + appId: String, + versionCode: Int, + inAppResultLauncher: ActivityResultLauncher?, + onFDroidResult: (updateIsAvailable: Boolean) -> Unit, + ) { + lifecycleScope.launch { + val lastVersionCode = FdroidApiTools().getLastRelease(appId) + + withContext(Dispatchers.Main) { onFDroidResult(versionCode < lastVersionCode) } + } } -} -fun FragmentActivity.launchInAppReview() = Unit + fun checkStalledUpdate() = Unit + + fun installDownloadedUpdate(onFailure: (Exception) -> Unit) = Unit + + fun unregisterAppUpdateListener() = Unit + + fun cancelUpdate() = Unit + //endregion + + //region In-App Review + fun FragmentActivity.launchInAppReview() = Unit + //endRegion +} diff --git a/Stores/src/standard/java/com.infomaniak.lib.stores/StoreUtils.kt b/Stores/src/standard/java/com.infomaniak.lib.stores/StoreUtils.kt index ca8a4fb9..42d6722f 100644 --- a/Stores/src/standard/java/com.infomaniak.lib.stores/StoreUtils.kt +++ b/Stores/src/standard/java/com.infomaniak.lib.stores/StoreUtils.kt @@ -17,26 +17,110 @@ */ package com.infomaniak.lib.stores +import android.content.Context +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.IntentSenderRequest import androidx.fragment.app.FragmentActivity +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 com.google.android.play.core.review.ReviewManagerFactory -fun FragmentActivity.checkUpdateIsAvailable(appId: String, versionCode: Int, onResult: (updateIsAvailable: Boolean) -> Unit) { - AppUpdateManagerFactory.create(this).appUpdateInfo.addOnSuccessListener { appUpdateInfo -> - val updateIsAvailable = appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && - appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE) +object StoreUtils { - onResult(updateIsAvailable) + private const val UPDATE_TYPE = AppUpdateType.FLEXIBLE + + private lateinit var appUpdateManager: AppUpdateManager + private lateinit var onInstallDownloaded: () -> Unit + + // Create a listener to track request state updates. + private val installStateUpdatedListener by lazy { + InstallStateUpdatedListener { state -> + when (state.installStatus()) { + InstallStatus.DOWNLOADED -> onInstallDownloaded() + InstallStatus.INSTALLED -> unregisterAppUpdateListener() + else -> Unit + } + } } -} -fun FragmentActivity.launchInAppReview() { - ReviewManagerFactory.create(this).apply { - val requestReviewFlow = requestReviewFlow() - requestReviewFlow.addOnCompleteListener { request -> - if (request.isSuccessful) launchReviewFlow(this@launchInAppReview, request.result) + //region legacy App update + // TODO: Remove this when Ui for kDrive in app update will be made + fun FragmentActivity.checkUpdateIsAvailable(appId: String, versionCode: Int, onResult: (updateIsAvailable: Boolean) -> Unit) { + AppUpdateManagerFactory.create(this).appUpdateInfo.addOnSuccessListener { appUpdateInfo -> + val updateIsAvailable = appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && + appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE) + + onResult(updateIsAvailable) + } + } + //endRegion + + //region In-App Update + fun initAppUpdateManager(context: Context, onInstall: () -> Unit) { + appUpdateManager = AppUpdateManagerFactory.create(context) + onInstallDownloaded = onInstall + } + + fun FragmentActivity.checkUpdateIsAvailable( + appId: String, + versionCode: Int, + inAppResultLauncher: ActivityResultLauncher, + onFDroidResult: (updateIsAvailable: Boolean) -> Unit, + ) { + appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo -> + if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE + && appUpdateInfo.isUpdateTypeAllowed(UPDATE_TYPE) + ) { + inAppResultLauncher?.let { startUpdateFlow(appUpdateInfo, it) } + } + } + } + + fun checkStalledUpdate() = with(appUpdateManager) { + registerListener(installStateUpdatedListener) + appUpdateInfo.addOnSuccessListener { appUpdateInfo -> + if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) { + // If the update is downloaded but not installed, notify the user to complete the update. + onInstallDownloaded.invoke() + } + } + } + + fun installDownloadedUpdate(onFailure: (Exception) -> Unit) { + appUpdateManager.completeUpdate().addOnFailureListener(onFailure) + } + + fun unregisterAppUpdateListener() { + appUpdateManager.unregisterListener(installStateUpdatedListener) + } + + private fun startUpdateFlow( + appUpdateInfo: AppUpdateInfo, + downloadUpdateResultLauncher: ActivityResultLauncher, + ) = with(appUpdateManager) { + registerListener(installStateUpdatedListener) + startUpdateFlowForResult( + appUpdateInfo, + downloadUpdateResultLauncher, + AppUpdateOptions.newBuilder(UPDATE_TYPE).build(), + ) + } + //endregion + + //region In-App Review + fun FragmentActivity.launchInAppReview() { + ReviewManagerFactory.create(this).apply { + val requestReviewFlow = requestReviewFlow() + requestReviewFlow.addOnCompleteListener { request -> + if (request.isSuccessful) launchReviewFlow(this@launchInAppReview, request.result) + } } } + //endregion } diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index e24afa86..3d236e63 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -31,6 +31,7 @@ Diese Datei wird von keiner installierten Anwendung unterstützt Fehler Ein Fehler ist aufgetreten + Fehler bei der Update-Installation Fehler Benutzer bereits vorhanden Keine Verbindung Öffnen mit @@ -43,4 +44,5 @@ Aktualisierung erforderlich Mit Blick auf ein optimales %s-Benutzererlebnis empfehlen wir Ihnen, Ihre Anwendung zu aktualisieren. Aktualisierung verfügbar! + Update bereit diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 02538d79..4b031aa5 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -32,6 +32,7 @@ No hay ninguna aplicación instalada compatible con este archivo Error Se ha producido un error + Error durante la instalación de la actualización Error, usuario ya registrado Sin conexión Error del servidor @@ -43,4 +44,5 @@ Es necesario actualizar Para disfrutar de una experiencia óptima de %s, te aconsejamos que actualices tu aplicación. ¡Actualización disponible! + Actualización lista diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index e8cb30a2..05e85f05 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -31,6 +31,7 @@ Aucune application installée ne prend en charge ce fichier Erreur Une erreur s’est produite + Erreur lors de l’installation de la mise à jour Erreur utilisateur déjà présent Pas de connexion Ouvrir avec @@ -43,4 +44,5 @@ Mise à jour requise Afin de profiter d’une expérience optimale de %s, nous vous conseillons de mettre à jour votre application. Mise à jour disponible ! + Mise à jour prête diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 27f9556a..c3e7ce72 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -31,6 +31,7 @@ Il file non è supportato da nessuna delle applicazioni installate Errore Si è verificato un errore + Errore durante l’installazione dell’aggiornamento Errore utente già esistente Nessuna connessione Apri con @@ -43,4 +44,5 @@ Aggiornamento necessario Per vivere la migliore esperienza con %s, ti consigliamo di aggiornare la tua applicazione. Aggiornamento disponibile! + Aggiornamento pronto diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 1eb4c8f6..b539a61a 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -33,6 +33,7 @@ This file is not supported by any installed application Error An error occurred + Error during update install Error, User already present No connection Open with @@ -45,4 +46,5 @@ Update required To get the best out of %s, we recommend you update your application. Update available! + Update ready