check method

Future<void> check(
  1. BuildContext context, {
  2. required String url,
  3. UpdateAvailableCallback? onUpdateAvailable,
  4. bool shouldUpdate(
    1. VersionInfo newVersion,
    2. PackageInfo currentPackage
    )?,
  5. Map<String, dynamic>? params,
})

检查更新

流程:请求API → 解析版本 → 判断是否需要更新 → 触发回调或弹窗

Implementation

Future<void> check(
  BuildContext context, {
  required String url,
  UpdateAvailableCallback? onUpdateAvailable,
  bool Function(VersionInfo newVersion, PackageInfo currentPackage)? shouldUpdate,
  Map<String, dynamic>? params,
}) async {
  _assertAndroid();
  _assertInitialized();

  _emit(UpgraderEventType.checkStart, '开始检查更新', {'url': url});

  try {
    final response = await _dio.get(url, queryParameters: params);
    if (response.statusCode != 200) {
      final errMsg = '网络请求失败,状态码: ${response.statusCode}';
      _emit(UpgraderEventType.checkError, errMsg, {
        'statusCode': response.statusCode,
      });
      throw errMsg;
    }

    _emit(UpgraderEventType.checkResponse, '检查更新响应', {
      'statusCode': response.statusCode,
      'data': response.data,
    });

    final newVersionInfo = await _parser(response.data);
    final packageInfo = await PackageInfo.fromPlatform();

    _emit(UpgraderEventType.checkCurrentVersion, '当前版本信息', {
      'version': packageInfo.version,
      'buildNumber': packageInfo.buildNumber,
      'appName': packageInfo.appName,
      'packageName': packageInfo.packageName,
    });

    _updateInfo = UpdateInfo(
      currentVersion: packageInfo.version,
      currentBuildNumber: packageInfo.buildNumber,
      latestVersion: newVersionInfo,
    );

    // 判断是否需要更新
    final hasUpdate = shouldUpdate != null
        ? shouldUpdate(newVersionInfo, packageInfo)
        : _defaultShouldUpdate(newVersionInfo, packageInfo);

    if (!hasUpdate) {
      _emit(UpgraderEventType.checkNoUpdate, '当前已是最新版本', {
        'currentVersion': packageInfo.version,
        'currentBuildNumber': packageInfo.buildNumber,
      });
      return;
    }

    _emit(UpgraderEventType.checkNewVersion, '发现新版本', {
      'currentVersion': packageInfo.version,
      'currentBuildNumber': packageInfo.buildNumber,
      'latestVersion': newVersionInfo.version,
      'latestBuildVersion': newVersionInfo.buildVersion,
      'updateStrategy': newVersionInfo.updateStrategy.name,
      'apkSize': newVersionInfo.apkSize,
      'hasMd5': newVersionInfo.apkHashCode.isNotEmpty,
      'modifyContent': newVersionInfo.modifyContent,
    });

    // 重置下载状态
    statusNotifier.value = DownloadStatus.none;
    progressNotifier.value = 0.0;

    // 优先使用回调
    if (onUpdateAvailable != null) {
      if (!context.mounted) return;
      onUpdateAvailable(context, _updateInfo!);
      return;
    }

    // 强制更新 → 全屏拦截页;可选/推荐 → Dialog
    if (!context.mounted) return;
    final strategy = newVersionInfo.updateStrategy;

    if (strategy == UpdateStrategy.forced) {
      _emit(UpgraderEventType.log, '触发强制更新页面');

      final pageBuilder = _forcedUpdatePageBuilder ??
          (ctx, info, st, pr) => DefaultForcedUpdatePage(
                updateInfo: info,
                statusNotifier: st,
                progressNotifier: pr,
              );

      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (ctx) => PopScope(
            canPop: false,
            child: pageBuilder(ctx, _updateInfo!, statusNotifier, progressNotifier),
          ),
        ),
      );
    } else if (_dialogBuilder != null) {
      _emit(UpgraderEventType.log, '弹出更新对话框 (${strategy.name})');

      showDialog(
        context: context,
        barrierDismissible: true,
        builder: (ctx) => PopScope(
          canPop: true,
          child: _dialogBuilder!(ctx, _updateInfo!, statusNotifier, progressNotifier),
        ),
      );
    } else {
      _emit(UpgraderEventType.log, '警告: 未设置 dialogBuilder 和 onUpdateAvailable');
    }
  } catch (e) {
    _emit(UpgraderEventType.checkError, '检查更新出错: $e', {'error': e.toString()});
    _errorHandler?.call(e);
  }
}