返回

如何在不借助 Play 商店的情况下使用 Kotlin 通过 GitHub 自动更新 APK?

Android

使用 Kotlin 在不借助 Play 商店的情况下通过 GitHub 自动更新 APK

问题

应用程序更新是保持其稳定性和功能性至关重要的环节。传统上,更新是通过 Play 商店分发的,但对于希望掌控更新流程或分发私有 APK 的开发者来说,这并不是一个理想的解决方案。本文介绍了一种替代方法,使用 Kotlin 通过 GitHub 自动更新 APK,无需依赖 Play 商店。

解决方案

为了在没有 Play 商店的情况下实现 APK 自动更新,我们利用 GitHub 的 API 和 Kotlin 的强大功能,创建一个自定义更新机制。该机制涉及以下步骤:

  • 获取 GitHub 访问令牌
  • 使用 GitHub API 获取最新分支和 APK 下载 URL
  • 下载并安装 APK

代码实现

class Updater {

    private val token = "YOUR_GITHUB_TOKEN"
    private val repo = "YOUR_REPO_NAME"

    fun checkForUpdate() {
        val client = OkHttpClient()
        val request = Request.Builder()
            .url("https://api.github.com/repos/$repo/branches")
            .header("Authorization", "Bearer $token")
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("Update", "Error getting latest branch: ${e.message}")
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val body = response.body?.string()
                    val branches = JSONArray(body)
                    val latestBranch = branches.getJSONObject(0).getString("name")
                    val downloadUrl = "https://api.github.com/repos/$repo/contents/app.apk?ref=$latestBranch"
                    downloadAndInstallApk(downloadUrl)
                } else {
                    Log.e("Update", "Error getting latest branch: ${response.code}")
                }
            }
        })
    }

    private fun downloadAndInstallApk(url: String) {
        val request = Request.Builder()
            .url(url)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("Update", "Error downloading APK: ${e.message}")
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val body = response.body?.byteStream()
                    val apkFile = File(context.filesDir, "app.apk")
                    body?.use { inputStream ->
                        apkFile.outputStream().use { output ->
                            inputStream.copyTo(output)
                        }
                    }
                    installApk(apkFile)
                } else {
                    Log.e("Update", "Error downloading APK: ${response.code}")
                }
            }
        })
    }

    private fun installApk(apkFile: File) {
        val intent = Intent(Intent.ACTION_VIEW)
        intent.setDataAndType(
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                FileProvider.getUriForFile(context, "$packageName.provider", apkFile)
            } else {
                Uri.fromFile(apkFile)
            },
            "application/vnd.android.package-archive"
        )
        intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        startActivity(intent)
    }
}

使用说明

  • 替换 YOUR_GITHUB_TOKENYOUR_REPO_NAME 为实际值。
  • 调用 checkForUpdate() 方法来检查更新。

优势

使用 GitHub 进行 APK 自动更新提供了以下优势:

  • 私有更新: 更新可以通过私有 GitHub 仓库分发,确保只有授权用户才能访问。
  • 自定义更新流程: 开发者可以完全控制更新流程,包括发布频率和更新内容。
  • 提高安全性: 通过 GitHub 分发 APK 可以减少应用程序面临安全漏洞的风险。

常见问题解答

  1. 我可以更新已安装的应用程序吗? 是的,此方法可以更新已安装的应用程序,只要它们是从相同的 GitHub 仓库安装的。
  2. 如何处理更新失败? 可以在 checkForUpdate() 方法中添加错误处理逻辑,以便在更新失败时采取适当措施。
  3. 是否需要用户交互? 该方法不需要用户交互,更新过程将在后台自动进行。
  4. 是否适用于所有 Android 版本? 该方法适用于运行 Android 4.0 及更高版本的设备。
  5. 是否可以限制更新? 可以在 GitHub 上设置分支权限,以控制谁可以访问和下载更新。

结论

使用 Kotlin 通过 GitHub 自动更新 APK 为应用程序开发者提供了一个强大的工具。它允许他们控制更新流程、分发私有更新并提高安全性。通过利用 GitHub 的 API 和 Kotlin 的灵活性,开发者可以轻松实施自定义更新机制,为用户提供无缝的应用程序更新体验。