import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:logger/logger.dart'; import 'package:device_info_plus/device_info_plus.dart'; import '../models/channel_app_model.dart'; import 'network/api.dart'; import 'dart:math' as math; /// 版本更新服务类 class VersionUpdateService extends GetxService { static VersionUpdateService get to => Get.find(); final Logger _logger = Logger(); // 游客登录显示状态 final isShowTourists = false.obs; /// 获取当前应用版本信息 Future getCurrentVersion() async { try { final packageInfo = await PackageInfo.fromPlatform(); return '${packageInfo.version}+${packageInfo.buildNumber}'; } catch (e) { _logger.e('获取当前版本信息失败: $e'); return '1.0.0'; } } /// 获取当前平台信息 Future getCurrentPlatformInfo() async { if (kIsWeb) { return const PlatformInfo( platform: 'web', storeType: AppStoreType.official, channel: UserChannel.OFFICIAL, ); } if (Platform.isIOS) { return const PlatformInfo( platform: 'ios', storeType: AppStoreType.appStore, channel: UserChannel.GLOBAL_APPLE, ); } if (Platform.isAndroid) { // 根据设备品牌判断应用商店类型 return await getAndroidStoreInfoByBrand(); } return const PlatformInfo( platform: 'unknown', storeType: AppStoreType.unknown, channel: UserChannel.UNKNOWN, ); } /// 根据设备品牌获取应用商店信息 Future getAndroidStoreInfoByBrand() async { try { final deviceInfo = DeviceInfoPlugin(); final androidInfo = await deviceInfo.androidInfo; final brand = androidInfo.brand.toLowerCase(); return const PlatformInfo( platform: 'android', storeType: AppStoreType.official, channel: UserChannel.OFFICIAL, ); // switch (brand) { // case 'huawei': // case 'honor': // return PlatformInfo( // platform: 'android', // storeType: // brand == 'huawei' ? AppStoreType.huawei : AppStoreType.honor, // channel: brand == 'huawei' ? '华为应用市场' : '荣耀应用市场', // ); // case 'xiaomi': // case 'redmi': // return const PlatformInfo( // platform: 'android', // storeType: AppStoreType.xiaomi, // channel: '小米应用商店', // ); // case 'oppo': // case 'oneplus': // return const PlatformInfo( // platform: 'android', // storeType: AppStoreType.oppo, // channel: 'OPPO软件商店', // ); // case 'vivo': // case 'iqoo': // return const PlatformInfo( // platform: 'android', // storeType: AppStoreType.vivo, // channel: 'vivo应用商店', // ); // default: // return const PlatformInfo( // platform: 'android', // storeType: AppStoreType.googlePlay, // channel: 'Google Play', // ); // } } catch (e) { _logger.e('获取Android设备信息失败: $e'); return const PlatformInfo( platform: 'android', storeType: AppStoreType.googlePlay, channel: UserChannel.UNKNOWN, ); } } /// 检查版本更新 Future checkForUpdate() async { try { final currentVersion = await getCurrentVersion(); final platformInfo = await getCurrentPlatformInfo(); // 调用后端接口获取最新版本信息 final response = await Api.getChannelApp({'channel': platformInfo.channel.value}); _logger.d('获取渠道包信息:$response'); if (response == null || !response.containsKey('app')) { return VersionUpdateInfo( hasUpdate: false, currentVersion: currentVersion, latestVersion: currentVersion, updateType: UpdateType.none, ); } //final channelAppResponse = ChannelAppResponse.fromJson(response); // 直接从response中获取app信息 final appInfo = AppInfo.fromJson(response['app']); _logger.d('获取到的最新版本信息: ${appInfo.toJson()}'); // 设置游客登录显示状态 isShowTourists.value = appInfo.tourists; _logger.d('从服务器获取游客登录配置: ${appInfo.tourists}'); // if (channelAppResponse.code != 0 || channelAppResponse.data == null) { // _logger.w('获取版本信息失败: ${channelAppResponse.msg}'); // return VersionUpdateInfo( // hasUpdate: false, // currentVersion: currentVersion, // latestVersion: currentVersion, // updateType: UpdateType.none, // ); // } // final appInfo = channelAppResponse.data!.app; final hasUpdate = _compareVersions(currentVersion, appInfo.version); // 判断更新类型:如果主版本号不同则强制更新 UpdateType updateType = UpdateType.none; if (hasUpdate) { final isForceUpdate = _shouldForceUpdate(currentVersion, appInfo.version); updateType = isForceUpdate ? UpdateType.force : UpdateType.optional; } return VersionUpdateInfo( hasUpdate: hasUpdate, currentVersion: currentVersion.split('+')[0], latestVersion: appInfo.version.split('+')[0], appInfo: appInfo, updateType: updateType, ); } catch (e) { _logger.e('检查版本更新失败: $e'); // 发生错误时,保持默认值 false isShowTourists.value = false; final currentVersion = await getCurrentVersion(); return VersionUpdateInfo( hasUpdate: false, currentVersion: currentVersion, latestVersion: currentVersion, updateType: UpdateType.none, ); } } /// 判断是否需要强制更新 /// 当主版本号(第一位数字)不同时返回true bool _shouldForceUpdate(String current, String latest) { try { // 拆分版本号与构建号 final currentParts = current.split('+'); final latestParts = latest.split('+'); // 解析版本号 (major.minor.patch) final currentVersions = currentParts[0].split('.').map(int.parse).toList(); final latestVersions = latestParts[0].split('.').map(int.parse).toList(); // 比较主版本号(第一位) if (currentVersions.isNotEmpty && latestVersions.isNotEmpty) { if (currentVersions[0] != latestVersions[0]) { return true; } } // 检查是否有两个或更多的 + 号,如果有则强制更新 if (latest.split('+').length > 2) { return true; } return false; } catch (e) { _logger.e('判断强制更新失败: $e'); return false; } } /// 比较版本号 /// 返回true表示需要更新(远程版本更高) bool _compareVersions(String current, String latest) { // 拆分版本号与构建号 final currentParts = current.split('+')[0]; final latestParts = latest.split('+')[0]; // 解析版本号 (major.minor.patch) final currentVersions = currentParts.split('.').map(int.parse).toList(); final latestVersions = latestParts.split('.').map(int.parse).toList(); // 使用较小的长度进行比较,避免索引越界 final minLength = math.min(currentVersions.length, latestVersions.length); // 逐级比较版本号 for (var i = 0; i < minLength; i++) { if (latestVersions[i] > currentVersions[i]) return true; if (latestVersions[i] < currentVersions[i]) return false; } // 如果前面的版本号都相同,比较长度 // 更长的版本号被认为是更新的版本(如 1.0.1 > 1.0) return latestVersions.length > currentVersions.length; } /// 解析版本号字符串为数字数组 List _parseVersion(String version) { final parts = version.split('.'); final result = []; for (int i = 0; i < 3; i++) { if (i < parts.length) { result.add(int.tryParse(parts[i]) ?? 0); } else { result.add(0); } } return result; } /// 执行更新操作 Future performUpdate(VersionUpdateInfo updateInfo) async { if (!updateInfo.hasUpdate || updateInfo.appInfo == null) { return false; } final platformInfo = await getCurrentPlatformInfo(); try { switch (platformInfo.storeType) { case AppStoreType.appStore: return await _openAppStore(); case AppStoreType.googlePlay: return await _openGooglePlay(); case AppStoreType.huawei: return await _openHuaweiStore(); case AppStoreType.xiaomi: return await _openXiaomiStore(); case AppStoreType.oppo: return await _openOppoStore(); case AppStoreType.vivo: return await _openVivoStore(); case AppStoreType.honor: return await _openHonorStore(); case AppStoreType.official: return await _openOfficialDownload(updateInfo.appInfo!.address!); default: return await _openOfficialDownload(updateInfo.appInfo!.address!); } } catch (e) { _logger.e('执行更新失败: $e'); return false; } } /// 打开iOS App Store Future _openAppStore() async { // 这里需要替换为实际的App Store ID const appStoreUrl = 'https://apps.apple.com/app/id你的应用ID'; return await _launchUrl(appStoreUrl); } /// 打开Google Play Future _openGooglePlay() async { // 这里需要替换为实际的包名 const packageName = 'com.yourcompany.deepvoice'; const playStoreUrl = 'https://play.google.com/store/apps/details?id=$packageName'; return await _launchUrl(playStoreUrl); } /// 打开华为应用市场 Future _openHuaweiStore() async { const huaweiStoreUrl = 'appmarket://details?id=com.yourcompany.deepvoice'; return await _launchUrl(huaweiStoreUrl); } /// 打开小米应用商店 Future _openXiaomiStore() async { const xiaomiStoreUrl = 'mimarket://details?id=com.yourcompany.deepvoice'; return await _launchUrl(xiaomiStoreUrl); } /// 打开OPPO软件商店 Future _openOppoStore() async { const oppoStoreUrl = 'oppomarket://details?packagename=com.yourcompany.deepvoice'; return await _launchUrl(oppoStoreUrl); } /// 打开vivo应用商店 Future _openVivoStore() async { const vivoStoreUrl = 'vivomarket://details?id=com.yourcompany.deepvoice'; return await _launchUrl(vivoStoreUrl); } /// 打开荣耀应用市场 Future _openHonorStore() async { const honorStoreUrl = 'honormarket://details?id=com.yourcompany.deepvoice'; return await _launchUrl(honorStoreUrl); } /// 打开官网下载 Future _openOfficialDownload(String downloadUrl) async { return await _launchUrl(downloadUrl); } /// 启动URL Future _launchUrl(String url) async { try { final uri = Uri.parse(url); if (await canLaunchUrl(uri)) { return await launchUrl(uri, mode: LaunchMode.externalApplication); } return false; } catch (e) { _logger.e('启动URL失败: $e'); return false; } } }