Skip to content

Commit

Permalink
Use ktx version of Google Play update library
Browse files Browse the repository at this point in the history
  • Loading branch information
DRSchlaubi committed Sep 26, 2023
1 parent c26831e commit d46dfcf
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 67 deletions.
4 changes: 2 additions & 2 deletions app/android/src/main/java/UpdateActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ 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.UpdateAvailability
import com.google.android.play.core.ktx.requestAppUpdateInfo
import dev.schlaubi.tonbrett.app.ColorScheme
import kotlinx.coroutines.tasks.await

class UpdateActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -60,7 +60,7 @@ fun UpdateScreen(activity: Activity) {
if (updateInfo == null) {
LaunchedEffect(appUpdateManager) {
try {
updateInfo = appUpdateManager.appUpdateInfo.await()
updateInfo = appUpdateManager.requestAppUpdateInfo()
} catch (e: Throwable) {
Log.w("Tonbrett", "Could not load Update info", e)
renderFallbackUpdate = true
Expand Down
102 changes: 40 additions & 62 deletions app/android/src/main/java/UpdateAwareAppScope.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,66 +29,35 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import com.google.android.play.core.appupdate.AppUpdateInfo
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.ktx.AppUpdateResult
import com.google.android.play.core.ktx.bytesDownloaded
import com.google.android.play.core.ktx.installStatus
import com.google.android.play.core.ktx.requestCompleteUpdate
import com.google.android.play.core.ktx.requestUpdateFlow
import com.google.android.play.core.ktx.totalBytesToDownload
import dev.schlaubi.tonbrett.app.ColorScheme
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import java.text.NumberFormat

private sealed interface State {
data object Waiting : State
data object Pending : State
data class UpdateAvailable(val info: AppUpdateInfo) : State
data object UpdateDownloaded : State
data class UpdateDownloading(val percentage: Double) : State
}

@Composable
fun UpdateAwareAppScope(activity: Activity, content: @Composable () -> Unit) {
val context = LocalContext.current.applicationContext
val scope = rememberCoroutineScope()
val appUpdateManager =
remember(context) { AppUpdateManagerFactory.create(context.applicationContext) }
var progress by remember(appUpdateManager) { mutableStateOf<State>(State.Waiting) }

val progressListener = remember {
InstallStateUpdatedListener {
when (it.installStatus()) {
InstallStatus.PENDING -> progress = State.Pending
InstallStatus.DOWNLOADING -> {
progress =
State.UpdateDownloading(
it.bytesDownloaded().toDouble() / it.totalBytesToDownload().toDouble().coerceAtLeast(1.0)
)
}

InstallStatus.DOWNLOADED -> {
progress = State.UpdateDownloaded
}

InstallStatus.INSTALLED, InstallStatus.FAILED, InstallStatus.CANCELED -> {
progress = State.Waiting
}

else -> {}
}
}
}

LaunchedEffect(appUpdateManager) { appUpdateManager.registerListener(progressListener) }
var progress by remember(appUpdateManager) { mutableStateOf<AppUpdateResult?>(null) }

if (progress is State.Waiting) {
if (progress != null) {
LaunchedEffect(appUpdateManager) {
try {
val updateInfo = appUpdateManager.appUpdateInfo.await()
if (updateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
progress = State.UpdateAvailable(updateInfo)
appUpdateManager.requestUpdateFlow().collect {
if (it is AppUpdateResult.Available) {
it.startFlexibleUpdate(activity, 12548)
} else {
progress = it
}
}
} catch (e: Throwable) {
Log.w("Tonbrett", "Could not load Update info", e)
Expand Down Expand Up @@ -127,29 +96,38 @@ fun UpdateAwareAppScope(activity: Activity, content: @Composable () -> Unit) {
}

when (val currentProgress = progress) {
is State.Pending -> Info(stringResource(R.string.update_pending))
is State.UpdateAvailable -> Button(onClick = {
scope.launch {
appUpdateManager.startUpdateFlow(
currentProgress.info,
activity,
AppUpdateOptions.defaultOptions(AppUpdateType.FLEXIBLE)
).await()
is AppUpdateResult.InProgress -> {
val installState = currentProgress.installState
when (installState.installStatus) {
InstallStatus.CANCELED, InstallStatus.INSTALLED, InstallStatus.FAILED -> {
progress = AppUpdateResult.NotAvailable
}

InstallStatus.DOWNLOADING -> {
val ratio = installState.bytesDownloaded.toDouble() /
installState.totalBytesToDownload.toDouble()
.coerceAtLeast(1.0) // avoid division by zero
val percentage = NumberFormat.getPercentInstance().format(ratio)
Info(stringResource(R.string.update_downloading, percentage))
}

InstallStatus.PENDING -> {
Info(stringResource(R.string.update_pending))
}

else -> {} // ignore
}
}

is AppUpdateResult.Available -> Button(onClick = {
currentProgress.startFlexibleUpdate(activity, 12548)
}) {
Info(stringResource(R.string.update_available))
}

is State.UpdateDownloading -> Info(
stringResource(
R.string.update_downloading,
NumberFormat.getPercentInstance().format(currentProgress.percentage)
)
)

is State.UpdateDownloaded -> Button(onClick = {
is AppUpdateResult.Downloaded -> Button(onClick = {
scope.launch {
appUpdateManager.completeUpdate().await()
appUpdateManager.requestCompleteUpdate()
}
}) {
Icon(Icons.Default.OpenInNew, null)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {

allprojects {
group = "dev.schlaubi.tonbrett"
version = "1.14.18"
version = "1.14.19"

repositories {
mavenCentral()
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mikbot = "3.23.5"
ksp = "1.9.10-1.0.13"
kordex = "1.5.8-SNAPSHOT"
android = "8.1.1"
compose = "1.5.1"
compose = "1.5.2"
lyricist = "1.4.2"
google-play = "2.1.0"
coroutines = "1.7.3"
Expand Down Expand Up @@ -40,7 +40,7 @@ ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serializatio
mikbot-ktor = { group = "dev.schlaubi", name = "mikbot-ktor", version.ref = "mikbot" }
mikbot-music = { group = "dev.schlaubi", name = "mikbot-music-player", version = "3.1.8-SNAPSHOT" }

imageloader = { group = "io.github.qdsfdhvh", name = "image-loader", version = "1.6.5" }
imageloader = { group = "io.github.qdsfdhvh", name = "image-loader", version = "1.6.7" }

kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging", version = "3.0.5" }

Expand Down

0 comments on commit d46dfcf

Please sign in to comment.