Skip to content

DirectAppUpdate An open-source in-app update library for Android that allows you to update your app via a private server, without relying on the Play Store. Ideal for apps distributed outside of app stores. Compatible with Jetpack Compose.

Notifications You must be signed in to change notification settings

Micoder-dev/DirectAppUpdate

Repository files navigation

DirectAppUpdate 📲

DirectAppUpdate is an open-source in-app update library using Jetpack Compose to update your Android app without relying on the Play Store or any other app store. Instead, updates are managed via a private server using a configurable JSON URL.

DirectAppUpdate Demo 1 DirectAppUpdate Demo 2

Getting Started 🚀

Library Setup

In your settings.gradle.ktx

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        mavenCentral()
        maven("https://jitpack.io")
    }
}

In your project build.gradle.ktx

dependencies {
    implementation("com.github.Micoder-dev:DirectAppUpdate:Tag")
}

JSON Config Setup

Create a configuration file for your app updates:

{
  "apkFileName": "new_release.apk",
  "appName": "My App",
  "downloadUrl": "https://example/new_release.apk",
  "immediateUpdate": false,
  "releaseNotes": "- Exciting Update\n - Bug Fixes",
  "versionCode": 2,
  "versionName": "2.0.0"
}

Implementation Methods 🔧

1st Way: Simple Implementation using Jetpack Compose

val configUrl = "https://example/micoder.json"
DirectAppUpdate(activity = this@MainActivity, configUrl = configUrl, appIcon = R.mipmap.ic_launcher)

The DirectAppUpdate is a composable function that can be used within your main activity's composable theme or any other composable function where you can check for update status.

2nd Way: Custom Implementation

@Composable
fun DirectAppUpdate(activity: Activity, configUrl: String, notificationViewModel: NotificationViewModel = hiltViewModel(), appIcon: Int) {

    val updateDialogState = remember { mutableStateOf(UpdateDialogState()) }

    val directAppUpdateManager = remember { DirectAppUpdateManager.Builder(activity) }

    LaunchedEffect(key1 = true) {
        directAppUpdateManager.fetchUpdateConfig(
            configUrl = configUrl,
            onSuccess = { builder ->
                builder.setDirectUpdateListener(object : DirectUpdateListener {
                    override fun onImmediateUpdateAvailable() {
                        updateDialogState.value = updateDialogState.value.copy(
                            visible = true,
                            updateType = UpdateType.Immediate,
                            status = "Immediate Update Available",
                            showUpdateButton = true
                        )
                    }

                    override fun onFlexibleUpdateAvailable() {
                        updateDialogState.value = updateDialogState.value.copy(
                            visible = true,
                            updateType = UpdateType.Flexible,
                            status = "Flexible Update Available",
                            showUpdateButton = true
                        )
                    }

                    override fun onAlreadyUpToDate() {
                        updateDialogState.value = updateDialogState.value.copy(
                            status = "Already up to date",
                            showUpdateButton = false
                        )
                    }

                    override fun onDownloadStart() {
                        updateDialogState.value = updateDialogState.value.copy(
                            status = "Download started",
                            showUpdateButton = false
                        )
                    }

                    override fun onProgress(progress: Float) {
                        notificationViewModel.showProgress(progress = progress.toInt(), icon = appIcon)
                        updateDialogState.value = updateDialogState.value.copy(
                            status = "Downloading: $progress%",
                            progress = progress
                        )
                    }

                    override fun onDownloadComplete() {
                        updateDialogState.value = updateDialogState.value.copy(
                            status = "Download complete",
                            showUpdateButton = false
                        )
                    }

                    override fun onDownloadFailed(error: String) {
                        updateDialogState.value = updateDialogState.value.copy(
                            status = "Download failed: $error",
                            showUpdateButton = false
                        )
                    }
                }).build().checkForUpdate()
            },
            onError = { error ->
                Toast.makeText(activity, error, Toast.LENGTH_SHORT).show()
            }
        )
    }

    UpdateDialog(
        dialogState = updateDialogState.value,
        onUpdateClick = { directAppUpdateManager.build().startUpdate() },
        onCancelClick = {
            if (updateDialogState.value.updateType == UpdateType.Flexible) {
                updateDialogState.value = updateDialogState.value.copy(visible = false)
            }
        }
    )

}

This method provides more customization options. Users can create custom dialogs or use DirectUpdateListener overrides as per their needs.

Contributions 🙌

We welcome contributions! Please fork the repository, create a new branch, and submit a pull request. For major changes, please open an issue first to discuss what you would like to change.

Don't forget to give this repo a ⭐ if you found it useful!

License 📄

This project is licensed under the MIT License. See the LICENSE file for details.

Happy Coding! 💻

About

DirectAppUpdate An open-source in-app update library for Android that allows you to update your app via a private server, without relying on the Play Store. Ideal for apps distributed outside of app stores. Compatible with Jetpack Compose.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages