美文网首页
Android 如何通过google play获取最新版本并更新

Android 如何通过google play获取最新版本并更新

作者: SmallWalnutBG | 来源:发表于2021-06-25 14:10 被阅读0次

    前言

    当遇到直接通过Google play上的版本名称来更新我们自己的App时,这时我们可以通过访问Google play上目标App的版本信息,通知自己的App,并跳转到Google play。下面来看具体实现。

    一、工具集成

    implementation 'org.jsoup:jsoup:1.10.2'
    

    ps:jsoup官网github源码文档这个工具主要是java代码,作为抓取HTML的工具,有很高的效率,如果有兴趣可以通过文档详细了解这个工具。我们可以通过他获得网页上想要的信息,正如现在我们需要“current version”信息。

    二、代码逻辑

                val document: Document = Jsoup.connect(
                    "https://play.google.com/store/apps/details?id=" + (if (!BuildConfig.DEBUG) BuildConfig.APPLICATION_ID else testPackageName) + "&hl=en"
                ).timeout(30000).userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6").referrer("http://www.google.com").get()
    

    其中connect里面为要访问的目标url,拼接的id为访问目标的app id,通常为包名。这里可以直接获取BuildConfig.APPLICATION_ID当前项目id,如果在测试的时候没有上架到google play,可以找个已上架的app,作为测试id。
    timeout为链接超时时间,userAgent为当前链接需要设置的代理信息。

    三、获取目标信息

      val element: Elements = document.getElementsContainingOwnText("Current Version")
                for (ele in element) {
                    Logg.d(tag, "ele:$ele")
                    if (ele.siblingElements() != null) {
                        Logg.d(tag, "ele.siblingElements:${ele.siblingElements()}")
                        val sibElemets: Elements = ele.siblingElements()
                        for (sibElemet in sibElemets) {
                            newVersion = sibElemet.text()
                        }
                    }
                }
    

    通过第二步的操作,成功了的话我们可以获得所有的HTML信息并放入document中。此时只需要输入我们需要元素key值,再轮巡取出目标text,这就是本次所要的version值。当然,你也可以根据需要分析document,在这些信息取出需要的信息。

    四、跳转Google play

           activity?.let { it ->
                val intentData = Intent(Intent.ACTION_VIEW).setData(
                    Uri.parse(
                        "market://details?id=" + if (!BuildConfig.DEBUG) it.packageName else testPackageName
                    )
                )
                if (it.packageManager?.let { intentData.resolveActivity(it) } != null) {
                    it.startActivity(intentData)
                } else {
                    intentData.data = Uri.parse(
                        "https://play.google.com/store/apps/details?id=" + if (!BuildConfig.DEBUG) it.packageName else testPackageName
                    )
                    it.startActivity(intentData)
                }
            }
    

    如果顺利的话,第三步我们已经拿到了关键的version name,此时只要根据自己的逻辑判断,跳转到Google play就可以了。当然,如果当前设备没有安装Google play,那就跳转浏览器。这里的id便是跳转目标app的包名packageName.

    五、代码全览

    工具类

    object VersionUpdateUtil {
        private val tag = "${this.javaClass.simpleName}=="
        private var newVersion: String? = null
    
        //test app package name
        private const val testPackageName = "com.embrace_2redbeans"
    
        private fun getVersionGooglePlay(): String? {
            try {
                val document: Document = Jsoup.connect(
                    "https://play.google.com/store/apps/details?id=" + (if (!BuildConfig.DEBUG) BuildConfig.APPLICATION_ID else testPackageName) + "&hl=en"
                ).timeout(30000).userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6").referrer("http://www.google.com").get()
                //            d(tag,"document:$document")
                val element: Elements = document.getElementsContainingOwnText("Current Version")
                for (ele in element) {
                    Logg.d(tag, "ele:$ele")
                    if (ele.siblingElements() != null) {
                        Logg.d(tag, "ele.siblingElements:${ele.siblingElements()}")
                        val sibElemets: Elements = ele.siblingElements()
                        for (sibElemet in sibElemets) {
                            newVersion = sibElemet.text()
                        }
                    }
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
            return newVersion
        }
    
    
        /**
         * first->currentVersionName
         * second->mLatestVersionName
         * third->is not equal
         */
        fun startCheckVersion(): Triple<String?, String?, Boolean> {
            return try {
                val mLatestVersionName = getVersionGooglePlay()
                val currentVersionName = BuildConfig.VERSION_NAME
                Logg.d(tag, "versionName:$mLatestVersionName")
                Logg.d(tag, "VERSION_CODE:$currentVersionName")
                Triple(currentVersionName, mLatestVersionName, mLatestVersionName != currentVersionName)
            } catch (e: Exception) {
                e.printStackTrace()
                Triple(null, null, false)
            }
        }
    
        @SuppressLint("QueryPermissionsNeeded")
        fun jumpToGooglePlay(activity: Activity?) {
            activity?.let { it ->
                val intentData = Intent(Intent.ACTION_VIEW).setData(
                    Uri.parse(
                        "market://details?id=" + if (!BuildConfig.DEBUG) it.packageName else testPackageName
                    )
                )
                if (it.packageManager?.let { intentData.resolveActivity(it) } != null) {
                    it.startActivity(intentData)
                } else {
                    intentData.data = Uri.parse(
                        "https://play.google.com/store/apps/details?id=" + if (!BuildConfig.DEBUG) it.packageName else testPackageName
                    )
                    it.startActivity(intentData)
                }
            }
        }
    }
    

    调用

     coroutineScope?.launch(context = ioDispatcherDispatchers.IO) {
                try {
                    onGetResponse(resultCallback, VersionUpdateUtil.startCheckVersion())
                } catch (e: Exception) {
                    e.printStackTrace()
                    onGetResponse(resultCallback, null)
                }
            }
            
     suspend fun <T> withNonCancellable(block: suspend CoroutineScope.() -> T): T {
            return withContext(NonCancellable, block)
        }
    
    suspend fun <T> withMain(block: suspend CoroutineScope.() -> T): T {
            return withContext(mainDispatcher, block)
        }
     suspend fun <Data> onGetResponse(callback: (Data?) -> Unit, httpData: Data?) {
            callback.let {
                withNonCancellable {
                    withMain {
                        it.invoke(httpData)
                    }
                }
            }
        }
    

    六、 尾声

    获取HTML数据时,耗时操作要放入协程里面。目前的这个更新方式也有小缺点:google play哪天改了current version,那我们的app就没法获取最新版本更新了。

    相关文章

      网友评论

          本文标题:Android 如何通过google play获取最新版本并更新

          本文链接:https://www.haomeiwen.com/subject/goqoyltx.html