> 技术文档 > 【重磅发布】flutter_chen_updater-版本升级更新

【重磅发布】flutter_chen_updater-版本升级更新


Flutter Chen Updater

一个功能强大的Flutter应用内更新插件,支持Android APK自动下载、安装和iOS跳转App Store。

✨ 特性

  • 跨平台支持: Android APK自动更新,iOS跳转App Store
  • 智能下载: 支持断点续传、文件校验、多重备用方案
  • 权限管理: 自动处理Android安装权限、存储权限
  • 强制更新: 支持可选更新和强制更新模式
  • 进度监控: 实时下载进度回调
  • 文件校验: MD5文件完整性验证
  • 生命周期管理: 智能处理应用前后台切换
  • 自定义UI: 支持自定义更新对话框

效果预览

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

📦 安装

在你的 pubspec.yaml 文件中添加依赖:

dependencies: flutter_chen_updater: ^1.0.0

然后运行:

flutter pub get

⚙️ 权限配置

Android

android/app/src/main/AndroidManifest.xml 中添加必要权限:

<uses-permission android:name=\"android.permission.INTERNET\" /><uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" android:maxSdkVersion=\"28\" /><uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" android:maxSdkVersion=\"28\" /><uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\" /><uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />

🚀 基础用法

1. 简单更新检查

import \'package:flutter_chen_updater/flutter_chen_updater.dart\';void checkForUpdate() { final updateInfo = UpdateInfo( version: \'1.1.0\', downloadUrl: \'https://example.com/app-v1.1.0.apk\', iosUrl: \'https://apps.apple.com/app/id123456789\', description: \'1. 修复已知问题\\n2. 优化用户体验\\n3. 新增功能特性\', isForceUpdate: false, ); Updater.checkAndUpdate( context, updateInfo, onAlreadyLatest: () => print(\'已是最新版本\'), onConfirm: () => print(\'用户确认更新\'), onCancel: () => print(\'用户取消更新\'), );}

2. 带进度监控的更新

void checkForUpdateWithProgress() { final updateInfo = UpdateInfo( version: \'1.1.0\', downloadUrl: \'https://example.com/app-v1.1.0.apk\', description: \'更新说明\', fileHash: \'abc123def456\', // 可选:文件MD5校验 hashAlgorithm: \'md5\', fileSize: 15 * 1024 * 1024, // 15MB ); Updater.checkAndUpdate( context, updateInfo, onProgress: (progress) { print(\'下载进度: ${(progress.progress * 100).toStringAsFixed(1)}%\'); print(\'已下载: ${progress.downloaded} / ${progress.total}\'); }, onConfirm: () => print(\'开始下载更新\'), );}

3. 强制更新示例

void forceUpdate() { final updateInfo = UpdateInfo( version: \'2.1.0\', description: \'重要安全更新,请立即升级\', downloadUrl: \'https://example.com/app-v2.1.0.apk\', isForceUpdate: true, // 强制更新,用户无法取消 ); Updater.checkAndUpdate(context, updateInfo);}

4. 自定义对话框

4.1 使用 dialogBuilder 自定义
Future<bool> customDialog(BuildContext context, UpdateInfo updateInfo) { return showDialog<bool>( context: context, barrierDismissible: !updateInfo.isForceUpdate, builder: (context) => AlertDialog( title: Text(\'发现新版本 ${updateInfo.version}\'), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(updateInfo.description), if (updateInfo.fileSize != null) Padding(  padding: const EdgeInsets.only(top: 8.0),  child: Text(\'大小: ${(updateInfo.fileSize! / 1024 / 1024).toStringAsFixed(1)}MB\'), ), ], ), actions: [ if (!updateInfo.isForceUpdate) TextButton( onPressed: () => Navigator.pop(context, false), child: const Text(\'稍后更新\'), ), ElevatedButton( onPressed: () => Navigator.pop(context, true), child: const Text(\'立即更新\'), ), ], ), ) ?? false;}void checkWithCustomDialog() { final updateInfo = UpdateInfo( version: \'1.1.0\', downloadUrl: \'https://example.com/app.apk\', description: \'重要更新说明\', ); Updater.checkAndUpdate( context, updateInfo, dialogBuilder: customDialog, );}
4.2 使用 UpdateDialog 灵活配置
void checkWithFlexibleDialog() { final updateInfo = UpdateInfo( version: \'1.2.0\', downloadUrl: \'https://example.com/app.apk\', description: \'• 修复重要安全漏洞\\n• 优化启动速度\\n• 新增夜间模式\', fileSize: 25 * 1024 * 1024, // 25MB ); showDialog<bool>( context: context, barrierDismissible: !updateInfo.isForceUpdate, builder: (context) => UpdateDialog( updateInfo: updateInfo, // 自定义标题 title: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue, Colors.purple], ), ), child: Row( children: [ Icon(Icons.system_update, color: Colors.white), const SizedBox(width: 8), Text(  \'重要更新 V${updateInfo.version}\',  style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold,  ), ), ], ), ), // 自定义内容 content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(16), child: Column(  crossAxisAlignment: CrossAxisAlignment.start,  children: [ Text(  \'更新内容\',  style: Theme.of(context).textTheme.titleMedium?.copyWith(  fontWeight: FontWeight.bold,  ), ), const SizedBox(height: 8), Text(updateInfo.description), const SizedBox(height: 12), if (updateInfo.fileSize != null)  Container(  padding: const EdgeInsets.symmetric(horizontal: 12,vertical: 6,  ),  decoration: BoxDecoration(color: Colors.grey.shade100,borderRadius: BorderRadius.circular(16),  ),  child: Text(\'安装包大小: ${(updateInfo.fileSize! / 1024 / 1024).toStringAsFixed(1)}MB\',style: Theme.of(context).textTheme.bodySmall,  ),  ),  ], ), ), ], ), // 自定义底部操作栏 footer: Container( padding: const EdgeInsets.all(16), child: Row( children: [ if (!updateInfo.isForceUpdate) ...[  Expanded( child: OutlinedButton(  onPressed: () => Navigator.pop(context, false),  child: const Text(\'稍后提醒\'), ),  ),  const SizedBox(width: 12), ], Expanded(  flex: updateInfo.isForceUpdate ? 1 : 1,  child: ElevatedButton.icon( onPressed: () => Navigator.pop(context, true), icon: const Icon(Icons.download), label: const Text(\'立即更新\'),  ), ), ], ), ), ), );}

5. 纯下载功能

void downloadOnly() { final updateInfo = UpdateInfo( version: \'1.1.0\', downloadUrl: \'https://example.com/app.apk\', description: \'更新包\', ); Updater.download(updateInfo).listen((progress) { if (progress.isCompleted && progress.filePath != null) { print(\'下载完成: ${progress.filePath}\'); // 稍后安装 Updater.installApk( progress.filePath!, onSuccess: () => print(\'安装成功\'), onError: (error) => print(\'安装失败: $error\'), ); } else if (progress.isFailed) { print(\'下载失败: ${progress.error}\'); } });}

6. 版本比较

void checkVersionUpdate() { final currentVersion = \'1.0.0\'; final newVersion = \'1.1.0\'; final needUpdate = Updater.needUpdate(currentVersion, newVersion); print(\'是否需要更新: $needUpdate\');}

📚 API 文档

UpdateInfo 类

更新信息配置类:

class UpdateInfo { final String version;  // 新版本号 (必需) final String? downloadUrl; // Android APK下载链接 final String? iosUrl; // iOS App Store链接 final String description; // 更新说明 (必需) final bool isForceUpdate; // 是否强制更新 final String? fileHash; // 文件哈希值 (可选) final String? hashAlgorithm; // 哈希算法 (默认: \'md5\') final int? fileSize;  // 文件大小 (字节) final Map<String, dynamic>? extra; // 额外数据}

Updater 类

主要更新器类:

静态方法
  • checkAndUpdate() - 检查并更新应用
  • download() - 纯下载方法(不自动安装)
  • installApk() - 安装APK文件
  • needUpdate() - 版本比较
  • cancelDownload() - 取消下载
  • dispose() - 清理资源

DownloadProgress 类

下载进度信息:

class DownloadProgress { final int downloaded; // 已下载字节数 final int total;  // 总字节数 final double progress; // 进度 (0.0 - 1.0) final DownloadStatus status; // 下载状态 final String? error; // 错误信息 final String? filePath; // 文件路径}

DownloadStatus 枚举

enum DownloadStatus { idle, // 空闲 downloading, // 下载中 paused, // 暂停 completed, // 完成 failed, // 失败 cancelled, // 取消 installing // 安装中}

🔧 高级功能

文件校验

插件支持MD5文件完整性校验:

final updateInfo = UpdateInfo( version: \'1.1.0\', downloadUrl: \'https://example.com/app.apk\', description: \'安全更新\', fileHash: \'a1b2c3d4e5f6...\', hashAlgorithm: \'md5\',);

权限处理

插件自动处理以下权限:

  1. 存储权限 (Android 9及以下)
  2. 安装权限 (Android 8+)
  3. 网络权限

对于缺失权限,插件会:

  • 自动请求权限
  • 引导用户到系统设置页面
  • 监听应用生命周期自动重试

生命周期管理

插件智能处理应用前后台切换:

  • 用户跳转权限设置后返回应用时自动重试安装
  • 后台下载任务保持活跃
  • 应用退出时自动清理资源

💡 错误处理

插件提供完善的错误处理机制:

Updater.checkAndUpdate( context, updateInfo, onProgress: (progress) { if (progress.isFailed) { // 处理下载失败 showDialog( context: context, builder: (_) => AlertDialog( title: const Text(\'下载失败\'), content: Text(progress.error ?? \'未知错误\'), actions: [ TextButton(  onPressed: () => Navigator.pop(context),  child: const Text(\'确定\'), ), ], ), ); } },);

🚦 最佳实践

  1. 版本检查: 建议在应用启动时检查更新
  2. 网络判断: 在检查更新前判断网络状态
  3. 用户体验: 避免在关键操作时弹出更新提示
  4. 资源清理: 应用退出时调用 Updater.dispose()
  5. 错误日志: 记录更新过程中的错误信息用于调试

❓ 常见问题

Q: Android安装失败怎么办?

A: 检查是否授予了\"安装未知应用\"权限,插件会自动引导用户设置。

Q: 下载速度慢怎么办?

A: 插件使用Android系统下载管理器和HTTP备用方案,确保最佳下载体验。

Q: 如何支持增量更新?

A: 当前版本不支持增量更新,建议使用文件校验确保完整性。

Q: iOS如何实现自动更新?

A: iOS由于系统限制只能跳转App Store,无法实现APK式的自动更新。

⚠️ 注意事项

  1. Android权限

    • Android 6.0+ 需要运行时申请存储权限
    • Android 8.0+ 需要安装未知来源应用权限
    • Android 10+ 使用作用域存储,无需存储权限
  2. 文件安全

    • 建议使用HTTPS下载链接
    • 强烈推荐设置fileHash进行文件完整性校验
    • 下载的APK文件会自动进行基础验证
  3. 用户体验

    • 避免在用户进行重要操作时弹出更新提示
    • 强制更新应谨慎使用,仅在安全更新时使用
    • 提供清晰的更新说明和文件大小信息

📄 许可证

MIT License