| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- package com.narutohuo.xindazhou.common.version
- import android.app.Activity
- import android.content.Context
- import android.content.pm.PackageManager
- import androidx.core.content.pm.PackageInfoCompat
- import androidx.fragment.app.FragmentActivity
- import androidx.lifecycle.LifecycleOwner
- import androidx.lifecycle.lifecycleScope
- import com.narutohuo.xindazhou.common.log.LogHelper
- import com.narutohuo.xindazhou.common.network.ApiManager
- import com.narutohuo.xindazhou.common.version.datasource.remote.VersionRemoteDataSourceImpl
- import com.narutohuo.xindazhou.common.version.repository.VersionRepository
- import com.narutohuo.xindazhou.common.version.ui.UpdateDialogFragment
- import kotlinx.coroutines.launch
- /**
- * 版本更新管理器
- *
- * 封装版本检查的完整逻辑,包括:
- * - 获取当前版本号
- * - 检查服务器版本
- * - 显示更新对话框
- * - 处理强制更新
- *
- * 使用方式:
- * ```kotlin
- * // 在 Application 中初始化
- * VersionUpdateManager.init(context)
- *
- * // 在 Activity 中检查更新(自动获取版本号)
- * VersionUpdateManager.checkUpdate(activity)
- *
- * // 或者手动指定版本号
- * VersionUpdateManager.checkUpdate(activity, platform = 1, versionCode = 100)
- * ```
- */
- object VersionUpdateManager {
-
- private const val PLATFORM_ANDROID = 1 // 平台类型:1-安卓,2-鸿蒙,3-iOS
-
- /**
- * 初始化版本更新管理器
- *
- * 需要在 Application.onCreate() 中调用
- *
- * @param context 上下文
- * @param platform 平台类型(默认 1-安卓)
- */
- fun init(context: Context, platform: Int = PLATFORM_ANDROID) {
- // 初始化 ApiManager 的 baseUrlProvider(如果还未设置)
- if (ApiManager.baseUrlProvider == null) {
- // 这里需要从 ServerConfigManager 获取,但为了避免循环依赖,
- // 建议在 Application 中先设置 ApiManager.baseUrlProvider
- LogHelper.w("VersionUpdateManager", "ApiManager.baseUrlProvider 未设置,版本检查可能失败")
- }
- }
-
- /**
- * 检查版本更新(自动获取当前版本号)
- *
- * @param activity Activity 实例(用于显示对话框和获取版本号)
- * @param platform 平台类型(默认 1-安卓)
- * @param onForceUpdateDismiss 强制更新时,用户关闭对话框的回调(可选,默认退出应用)
- */
- fun checkUpdate(
- activity: FragmentActivity,
- platform: Int = PLATFORM_ANDROID,
- onForceUpdateDismiss: (() -> Unit)? = null
- ) {
- val currentVersionCode = getCurrentVersionCode(activity)
- checkUpdate(activity, platform, currentVersionCode, onForceUpdateDismiss)
- }
-
- /**
- * 检查版本更新(手动指定版本号)
- *
- * @param activity Activity 实例(用于显示对话框)
- * @param platform 平台类型(默认 1-安卓)
- * @param currentVersionCode 当前版本号
- * @param onForceUpdateDismiss 强制更新时,用户关闭对话框的回调(可选,默认退出应用)
- */
- fun checkUpdate(
- activity: FragmentActivity,
- platform: Int,
- currentVersionCode: Int,
- onForceUpdateDismiss: (() -> Unit)? = null
- ) {
- // 使用 LifecycleOwner 的 lifecycleScope,自动管理协程生命周期
- activity.lifecycleScope.launch {
- try {
- // 创建数据源和 Repository
- val remoteDataSource = com.narutohuo.xindazhou.common.version.datasource.remote.VersionRemoteDataSourceImpl()
- val versionRepository = VersionRepository(remoteDataSource)
-
- // 检查版本(如果没有版本,返回 null,不影响启动)
- val versionResponse = versionRepository.checkVersion(platform, currentVersionCode)
-
- // 如果有新版本,显示更新对话框
- if (versionResponse != null && versionRepository.hasUpdate(versionResponse)) {
- val dialog = UpdateDialogFragment.create(
- versionResponse = versionResponse,
- onDismiss = {
- // 对话框关闭后的回调
- if (versionRepository.isForceUpdate(versionResponse)) {
- // 强制更新时,如果用户关闭对话框,执行回调或退出应用
- if (onForceUpdateDismiss != null) {
- onForceUpdateDismiss()
- } else {
- activity.finish()
- }
- }
- }
- )
- dialog.show(activity.supportFragmentManager, "UpdateDialogFragment")
- }
- } catch (e: Exception) {
- // 版本检查失败不影响应用启动
- // 可以记录日志,但不显示错误提示
- LogHelper.e("VersionUpdateManager", "版本检查失败", e)
- }
- }
- }
-
- /**
- * 检查版本更新(使用 LifecycleOwner,适用于 Fragment)
- *
- * @param lifecycleOwner LifecycleOwner(Activity 或 Fragment)
- * @param activity Activity 实例(用于显示对话框和获取版本号)
- * @param platform 平台类型(默认 1-安卓)
- * @param onForceUpdateDismiss 强制更新时,用户关闭对话框的回调(可选,默认退出应用)
- */
- fun checkUpdate(
- lifecycleOwner: LifecycleOwner,
- activity: FragmentActivity,
- platform: Int = PLATFORM_ANDROID,
- onForceUpdateDismiss: (() -> Unit)? = null
- ) {
- val currentVersionCode = getCurrentVersionCode(activity)
- lifecycleOwner.lifecycleScope.launch {
- try {
- // 创建数据源和 Repository
- val remoteDataSource = VersionRemoteDataSourceImpl()
- val versionRepository = VersionRepository(remoteDataSource)
-
- // 检查版本(如果没有版本,返回 null,不影响启动)
- val versionResponse = versionRepository.checkVersion(platform, currentVersionCode)
-
- // 如果有新版本,显示更新对话框
- if (versionResponse != null && versionRepository.hasUpdate(versionResponse)) {
- val dialog = UpdateDialogFragment.create(
- versionResponse = versionResponse,
- onDismiss = {
- // 对话框关闭后的回调
- if (versionRepository.isForceUpdate(versionResponse)) {
- // 强制更新时,如果用户关闭对话框,执行回调或退出应用
- if (onForceUpdateDismiss != null) {
- onForceUpdateDismiss()
- } else {
- activity.finish()
- }
- }
- }
- )
- dialog.show(activity.supportFragmentManager, "UpdateDialogFragment")
- }
- } catch (e: Exception) {
- // 版本检查失败不影响应用启动
- // 可以记录日志,但不显示错误提示
- LogHelper.e("VersionUpdateManager", "版本检查失败", e)
- }
- }
- }
-
- /**
- * 获取当前应用的版本号
- *
- * @param context 上下文
- * @return 版本号,如果获取失败返回 1
- */
- fun getCurrentVersionCode(context: Context): Int {
- return try {
- val packageManager = context.packageManager
- val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
- // 使用 PackageInfoCompat 统一处理,兼容所有版本
- PackageInfoCompat.getLongVersionCode(packageInfo).toInt()
- } catch (e: PackageManager.NameNotFoundException) {
- // 记录异常
- LogHelper.e("VersionUpdateManager", "无法获取版本号", e)
- 1 // 默认版本号
- }
- }
- }
|