Skip to content

Commit

Permalink
Have DefaultDialog automatically launch Play Store for the user (#14)
Browse files Browse the repository at this point in the history
* PackageDetails interface additions (getVersion, isDevelopmentBuild, areTestUpdatesSupported)
  • Loading branch information
ssawchenko authored Oct 5, 2021
1 parent 82a5c79 commit 54c1a9a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ class App: Application() {
url = "https://myservice.com/api/version" // <-- Change this URL
)
)
// If you wish the VersionCheck to be automatically ran on the Application's OnStart
// lifecycle call, add the following line:
// Add the following line if you want the version check to be automatically
// run whenever the app is "Started"
ProcessLifecycleOwner.get().lifecycle.addObserver(versionChecker)
// If you wish to use the default alert dialog, add the following 2 lines:
val upgradeDialog = DefaultUpgradeDialog(versionChecker.displayStateFlow)
// Add the following lines if you want a default alert dialog to handle the displayStates
// and allow the user to jump out to the Play Store to get updates.
val upgradeDialog = DefaultUpgradeDialog(versionChecker.displayStateFlow, packageName)
registerActivityLifecycleCallbacks(upgradeDialog)
}
}
Expand Down
14 changes: 7 additions & 7 deletions app/src/main/java/com/steamclock/versioncheckkotlinsample/App.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package com.steamclock.versioncheckkotlinsample

import android.app.Application
import android.content.pm.PackageManager
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.ProcessLifecycleOwner
import com.steamclock.versioncheckkotlin.DefaultUpgradeDialog
import com.steamclock.versioncheckkotlin.VersionCheck
import com.steamclock.versioncheckkotlin.VersionCheckConfig
import com.steamclock.versioncheckkotlin.interfaces.DefaultPackageDetails
import com.steamclock.versioncheckkotlin.interfaces.DefaultUpgradeDialog
import com.steamclock.versioncheckkotlin.interfaces.URLFetcher
import com.steamclock.versioncheckkotlin.models.Version
import kotlinx.coroutines.*
import java.net.URL
import kotlin.random.Random

class App: Application() {

Expand All @@ -33,9 +28,14 @@ class App: Application() {
urlFetcher = MockURLFetcher
)
)
val upgradeDialog = DefaultUpgradeDialog(versionChecker.displayStateFlow)

// Add the following line if you want the version check to be automatically
// run whenever the app is "Started"
ProcessLifecycleOwner.get().lifecycle.addObserver(versionChecker)

// Add the following lines if you want a default alert dialog to handle the displayStates
// and allow the user to jump out to the Play Store to get updates.
val upgradeDialog = DefaultUpgradeDialog(versionChecker.displayStateFlow, packageName)
registerActivityLifecycleCallbacks(upgradeDialog)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package com.steamclock.versioncheckkotlin.interfaces
package com.steamclock.versioncheckkotlin

import android.app.Activity
import android.app.AlertDialog
import android.app.Application
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import com.steamclock.versioncheckkotlin.models.DisplayState
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import java.lang.Exception
import java.lang.ref.WeakReference

class DefaultUpgradeDialog(private val versionDisplayState: StateFlow<DisplayState>) : Application.ActivityLifecycleCallbacks {
class DefaultUpgradeDialog(
private val versionDisplayState: StateFlow<DisplayState>,
private val packageName: String
) : Application.ActivityLifecycleCallbacks {

private var dialog: AlertDialog? = null
private val coroutineScope = MainScope()
private var needToShowDialog = false
Expand All @@ -21,6 +28,7 @@ class DefaultUpgradeDialog(private val versionDisplayState: StateFlow<DisplaySta
init {
coroutineScope.launch {
versionDisplayState.collect { displayState ->
// If we have a current context, show the dialog immediately; else we need to wait.
when (val ctx = currentActivityContext?.get()) {
null -> needToShowDialog = true
else -> showForState(ctx, displayState)
Expand Down Expand Up @@ -95,13 +103,12 @@ class DefaultUpgradeDialog(private val versionDisplayState: StateFlow<DisplaySta

if (requiresUpdate) {
// Do not set click listener here, we do not want the button to dismiss the dialog.
setNeutralButton("Upgrade", null)
setPositiveButton("Update", null)
}

if (canDismiss) {
setPositiveButton("OK") { _, _ ->
setNegativeButton("Close") { _, _ ->
dialog = null
/* todo */
}
}
}
Expand All @@ -111,13 +118,25 @@ class DefaultUpgradeDialog(private val versionDisplayState: StateFlow<DisplaySta
// Tap dance a little to override the click listener so the dialog will not dismiss
dialog?.apply {
setOnShowListener {
getButton(AlertDialog.BUTTON_NEUTRAL)?.setOnClickListener {
// todo Proxy out to Play Store.
getButton(AlertDialog.BUTTON_POSITIVE)?.setOnClickListener {
launchPlayStorePage()
}
}
}
}

private fun launchPlayStorePage() {
try {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://play.google.com/store/apps/details?id=$packageName")
setPackage("com.android.vending")
}
currentActivityContext?.get()?.startActivity(intent)
} catch (e: Exception) {
// 2021-10-05 How to handle error
}
}

//-----------------------------------------------------------------
// Using ActivityLifecycleCallbacks to launch version checks and collect
// state flows.
Expand Down

0 comments on commit 54c1a9a

Please sign in to comment.