yx_app_upgrade_flutter/README.md

295 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# YX App Upgrade Flutter
一款轻量、现代且易用的 Flutter 应用内更新插件。支持 Android 的"下载-安装"全流程iOS 自动跳转 App Store。提供「一键检查更新」与「静默检查 + 用户决定」两种常见用法,并内置完善的权限处理与安装策略。
## ✨ 特性
- **🎯 智能平台适配**Android 直下直装iOS 跳转 App Store
- **🔄 灵活的更新策略**
- **一键检查**:自动拉取、对比版本、弹窗提示
- **静默检查**:后台获取更新信息,适合冷启动或用户主动点击前的预检查
- **🎨 现代化 UI**
- Material 风格对话框
- **📝 富文本支持**:更新日志支持粗体、斜体、代码块、高亮等格式
- 进度与状态可视化
- **🛡️ 权限适配完善**:针对不同 Android 版本的存储、安装、通知权限自动处理
- **🌐 网络可配置**证书校验、超时、默认方法、Headers 等
- **🔧 安装策略灵活**:系统流程/预检查权限/智能策略可选
- **🏪 应用市场支持**:支持多应用市场白名单,智能检测设备已安装的市场
- **📦 多种更新方式**:应用市场、浏览器下载、应用内下载
## 📦 安装
`pubspec.yaml` 中添加依赖:
```yaml
dependencies:
yx_app_upgrade_flutter: ^1.0.0
```
## 🚀 快速开始
### 方式一:一键检查更新(推荐)
这是最简单的方式,一行代码即可完成检查更新并显示升级对话框:
```dart
import 'package:yx_app_upgrade_flutter/app_upgrade_plugin.dart';
void checkUpdate(BuildContext context) {
// 可选:一次性配置常用选项
AppUpgradeSimple.instance.configure(
const UpgradeConfig(
showNoUpdateToast: true,
autoInstall: false,
),
);
// 一行调用,自动拉取并展示升级对话框
AppUpgradeSimple.instance.checkUpdate(
context: context,
future: () async {
// 调用您的 API 获取版本信息
final response = await http.get('https://your-api.com/check-update');
final data = json.decode(response.body);
// 返回 AppUpgradeVersion 对象
return AppUpgradeVersion(
versionName: data['versionName'],
versionBuildNumber: data['versionBuildNumber'],
isForce: data['isForceUpdate'] ?? false,
updateContent: data['updateContent'],
downloadUrl: data['downloadUrl'],
appStoreUrl: data['appStoreUrl'],
apkSize: data['apkSize'],
apkMd5: data['apkMd5'],
// 应用市场配置
appMarkets: (data['appMarkets'] as List?)
?.map((e) => AppMarket.fromString(e))
.toList(),
// 支持的更新方式
supportedMethods: [
AppUpgradeMethod.market,
AppUpgradeMethod.browser,
AppUpgradeMethod.inApp,
],
);
},
);
}
```
### 方式二:静默检查 + 由用户决定
此方式适用于:
1. **App 启动时**:在后台静默检查是否有更新,如果有则在合适的时机(如用户点击"版本更新"按钮时)展示,避免打断用户操作。
2. **红点提示**:检查到有更新时仅显示红点,用户点击后才弹出对话框。
```dart
// 1. 静默检查更新(不显示任何 UI
final upgradeInfo = await AppUpgradeSimple.instance.silentCheckUpdate(
future: () async {
// 调用您的 API
return AppUpgradeVersion(...);
},
);
// 2. 根据结果处理
if (upgradeInfo != null && upgradeInfo.hasUpdate) {
// 有新版本,可以显示红点或在用户点击时调用弹窗
print('发现新版本: ${upgradeInfo.versionName}');
// 在需要展示弹窗的时机(如用户点击按钮):
AppUpgradeSimple.instance.showPreparedUpgrade(
context: context,
info: upgradeInfo, // 传入刚才获取的 info
);
}
```
### 常用配置
```dart
// 预设配置:
AppUpgradeSimple.instance.configure(UpgradeConfig.development); // 开发模式(详细日志+提示)
AppUpgradeSimple.instance.configure(UpgradeConfig.production); // 生产模式(静默+性能优化)
// 自定义配置:
AppUpgradeSimple.instance.configure(const UpgradeConfig(
showNoUpdateToast: true,
autoInstall: false,
installTimeout: 60,
enableDebugLog: true,
requireInstallPermission: false, // 默认不需要权限,直接安装
));
```
## 🎨 UI 能力与富文本
### 富文本更新日志
更新内容 (`updateContent`) 支持简单的 Markdown 风格富文本,让更新日志更清晰:
- **粗体**`**重要内容**`
- **斜体**`__斜体内容__`
- **代码块**`` `version 2.0` ``
- **高亮**`[特别注意]`
示例:
```text
1. 新增 **深色模式** 支持
2. 修复 `Login` 页面崩溃问题
3. [推荐] 性能大幅优化
```
### 对话框特性
- **发现新版本**(强制/非强制)
- 强制更新:不可关闭,必须更新
- 非强制更新:可稍后更新,支持后台下载
- **版本信息卡片**显示当前版本、新版本、APK 大小
- **下载进度展示**:实时显示下载进度百分比和状态
- **安装状态检测**:自动检测安装结果,支持重试
## ⚙️ Android 配置
### 1) 权限
`android/app/src/main/AndroidManifest.xml` 中添加:
```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- Android 13+ 通知权限(可选) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<!-- Android 9 写储存权限SDK 28 及以下需要) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<!-- FileProviderAndroid 7.0+ APK 安装必需) -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<!-- Android 11+ 查询声明:允许打开浏览器处理 HTTP/HTTPS URL -->
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
</queries>
</manifest>
```
### 2) FileProvider 路径
创建 `android/app/src/main/res/xml/file_paths.xml`
```xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- External storage -->
<external-path name="external_files" path="." />
<!-- Internal app storage -->
<files-path name="files" path="." />
<!-- Cache directory -->
<cache-path name="cache" path="." />
<!-- External cache -->
<external-cache-path name="external_cache" path="." />
<!-- Downloads directory -->
<external-path name="downloads" path="Download/" />
<!-- External app-specific files directory (Android/data/包名/files/) -->
<!-- 用于权限被拒绝时,使用应用私有目录存储下载的 APK -->
<external-files-path name="external_app_files" path="." />
</paths>
```
## 📡 服务端返回协议
服务端需要返回包含以下字段的 JSON
```json
{
"isForceUpdate": false,
"versionBuildNumber": 101,
"versionName": "1.0.1",
"updateContent": "1. 新增 **深色模式**\n2. 修复 `Bug`",
"downloadUrl": "https://your-cdn.com/app-release.apk",
"appStoreUrl": "https://apps.apple.com/app/id123456789",
"apkSize": 25165824,
"apkMd5": "d41d8cd98f00b204e9800998ecf8427e",
"appMarkets": ["huawei", "xiaomi", "oppo"],
"supportedMethods": ["market", "browser", "inApp"]
}
```
### 关键字段说明
- **versionBuildNumber**(必填):版本号(整数),用于比较。如果大于当前版本号,则提示更新。
- **versionName**(必填):版本名称,如 "1.0.1"。如果 BuildNumber 相同但 VersionName 更大(字典序),也会提示更新。
- **appMarkets**可选Android 应用市场白名单。配置后,优先尝试跳转已安装且在白名单中的市场。
- **supportedMethods**可选指定支持的更新方式market/browser/inApp
## 🔧 进阶能力
### 1) 网络配置
支持开发/生产环境切换,以及自定义 HTTP 配置(如 Headers、超时
```dart
// 自动选择Debug 绕过证书、Release 严格校验)
AppUpgradePlugin().configureHttp(HttpConfig.auto);
// 手动配置:
AppUpgradePlugin().configureHttp(const HttpConfig(
ignoreCertificate: false,
enableLog: true,
connectTimeout: 30,
headers: {'Authorization': 'Bearer xxx'},
));
```
### 2) 权限助手Android
```dart
import 'package:yx_app_upgrade_flutter/core/permission_helper.dart';
// 检查并请求存储权限
final hasStorage = await PermissionHelper.checkAndRequestStoragePermission(context: context);
// 检查并请求安装权限
final hasInstall = await PermissionHelper.checkAndRequestInstallPermission(context: context);
```
### 3) 预下载 APK
```dart
// 后台预下载 APK不显示 UI
final apkPath = await AppUpgradeSimple.instance.preDownloadApk(
url: 'https://your-cdn.com/app-release.apk',
onProgress: (progress) {
print('下载进度: ${progress.percentage}%');
},
);
```
## 🤝 贡献
欢迎提交 Issue 与 Pull Request
## 📄 许可证
MIT License