Kotlin+Jetpack Compose开发的App的应用更新升级功能实现

所属分类:Android | 发布于 2023-05-26 21:50:06

在开发了第一款app之后,才对app的更新升级有了认识,在iOS app中,通过App Store的应用更新机制,开发者不需要编写更新升级代码,但是在Android App中,确是需要开发者自己实现应用的更新升级功能。

道理很简单,iOS app的分发渠道目前只有App Store,但是Android的应用分发渠道确实五花八门,除了全球最大的Google Play之外,国内的各大手机厂商都有自己的应用商店,各个应用商店的升级策略不一样,同时,也还有通过浏览器直接下载Apk的方式进行安装的,所以Android App还是需要开发者自己开发应用更新升级功能。

通过这几天的研究,发现Android App要实现应用更新升级功能,需要实现下面三点:

  1. 设置界面增加版本检测功能
  2. App启动时检测版本更新
  3. 应用内更新(In-app update),这个是出海的app一般需要用的方式。

准备知识

1、在Mainfest.xml中有versionName和versionCode两个节点,versionName标志当前应用的版本号,如v1.2.0,是显示给用户看的,versionCode一般是不断增加的整数类型,是给开发者看的,应用商店也是通过versionCode来判断app的版本更新。

2、目前的开发实践中,一般把versionCode和versionName写在模块的build.gradle中,如

android {
    namespace 'net.test.testa'
    compileSdk 33

    defaultConfig {
        applicationId "net.test.testa"
        minSdk 26
        targetSdk 33
        versionCode 2
        versionName "1.1.0"
    }
}

3、当修改了build.gradle中的versionCode和versionName的值时,需要Sync Now,这样gradle就会重新构建项目,BuildConfig的值也会得到更新。

4、Kotlin获取versionCode和versionName

object AppUtil {
    fun getVersionCode(): Int {
        return BuildConfig.VERSION_CODE
    }

    fun getVersionName(): String {
        return BuildConfig.VERSION_NAME
    }
}

一、设置页面增加版本检测功能

1、原理

点击版本检测按钮后,发起请求获取当前最新的版本信息,然后将返回的versionCode和当前版本的versionCode做比较,如果返回的versionCode大于当前的versionCode,就说明有新的版本。

2、更新弹窗

@Composable
fun UpdateDialog(
    versionData: VersionData,
    onDismiss: ()->Unit,
    onConfirm: ()->Unit
) {
    Dialog(onDismissRequest = { /*TODO*/ }) {
        Card(
            shape = RoundedCornerShape(8.dp),
            colors = CardDefaults.cardColors(
                containerColor = Color.White
            ),
            modifier = Modifier
                .fillMaxWidth()
                .border(
                    2.dp,
                    color = MaterialTheme.colorScheme.primary,
                    shape = RoundedCornerShape(8.dp)
                )
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(15.dp),
                verticalArrangement = Arrangement.spacedBy(15.dp)
            ) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    verticalAlignment = Alignment.Bottom,
                    horizontalArrangement = Arrangement.Center
                ) {
                    Text(
                        text = "发现新版本",
                        style = MaterialTheme.typography.titleLarge,
                        textAlign = TextAlign.Center
                    )
                    Spacer(modifier = Modifier.width(5.dp))
                    Text(
                        text = "V${versionData.versionName}"
                    )
                }

                Text(
                    text = "更新内容",
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Bold
                )

                versionData.versionFeatures.forEach {
                    Text(text = it, style = MaterialTheme.typography.bodyMedium)
                }

                Column {
                    Row(
                        modifier = Modifier
                            .fillMaxWidth(),
                        horizontalArrangement = Arrangement.spacedBy(30.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ){
                        Button(
                            onClick = {
                                onDismiss()
                            },
                        ) {
                            Text(
                                text = "残忍拒绝",
                                style = MaterialTheme.typography.bodyMedium,
                                fontWeight = FontWeight.Bold,
                                textAlign = TextAlign.Center,
                            )
                        }
                        Button(
                            onClick = {
                                onConfirm()
                            },
                        ) {
                            Text(
                                text = "立即更新",
                                style = MaterialTheme.typography.bodyMedium,
                                fontWeight = FontWeight.Bold,
                                textAlign = TextAlign.Center,
                            )
                        }
                    }
                }
            }
        }
    }
}

简单解释一下,更新弹窗写成了单独的组件,文件为/ui/theme/component/UpdateDialog.kt,方便复用。

3、逻辑判断

点击按钮后,如果当前版本的versionCode和返回的versionCode相等,则使用toast或者snackbar弹出提示“你已经是最新版”,否则就弹出更新弹窗UpdateDialog()。

4、跳转到第三方网页进行更新

目前没有地方存储最新的apk安装包,所以就引导用户去酷安更新,这个时候就需要打开外部浏览器,跳转到酷安的应用页面进行下载安装。具体实现方式看上一篇文章:Jetpack Compose打开外部浏览器

5、应用内下载apk安装

目前还不会,暂时搁置。

二、应用启动时检测版本更新

目前也没有想到好的方式,暂时搁置。

三,应用内更新in-app updates

这种更新方式是针对Google Play商店应用的,由于目前这种方式在国内行不通,所以暂时没有研究。

文哥博客(https://wenge365.com)属于文野个人博客,欢迎浏览使用

联系方式:qq:52292959 邮箱:52292959@qq.com

备案号:粤ICP备18108585号 友情链接