- Android: correct version header 0.5.x→0.4.x, add sdk-license to module table, update artifact versions to 0.4.10 - iOS: correct min version iOS 14→16, bump version to 0.2.0, update SPM ref to from: "0.2.0" - RN: fix version 0.3.x→0.2.x, standardize npm registry URL, add @xuqm/rn-license to module table - Flutter: update git ref to v0.2.2, add xuqm_flutter_license to module tables - Add new docs: ios/license, rn/push, rn/license, flutter/push, flutter/update, flutter/license - tenant-platform: make appKey a computed ref in Push/VersionManagementView to fix service gating reactivity on route change - tenant-platform: add requestActivation API endpoint - tenant-platform: add IM service gating UI (checkServiceEnabled + activation dialog) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
181 行
4.4 KiB
Markdown
181 行
4.4 KiB
Markdown
# Flutter 版本更新接入指南
|
||
|
||
**模块**:`xuqm_flutter_update` · **功能**:App 版本检查、商店跳转、APK 直接下载
|
||
|
||
---
|
||
|
||
## 1. 安装
|
||
|
||
在 `pubspec.yaml` 中添加:
|
||
|
||
```yaml
|
||
dependencies:
|
||
xuqm_flutter_update:
|
||
git:
|
||
url: https://xuqinmin.com/xuqinmin12/XuqmGroup-FlutterSDK.git
|
||
ref: v0.2.0
|
||
path: packages/update
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 检查版本更新
|
||
|
||
```dart
|
||
import 'package:xuqm_flutter_update/xuqm_flutter_update.dart';
|
||
|
||
final sdk = XuqmUpdateSdk();
|
||
final info = await sdk.checkAppUpdate();
|
||
|
||
if (info.needsUpdate) {
|
||
print('新版本: ${info.versionName}');
|
||
print('更新说明: ${info.changeLog}');
|
||
print('强制更新: ${info.forceUpdate}');
|
||
}
|
||
```
|
||
|
||
`checkAppUpdate()` 会自动读取当前 App 的 versionCode 和 versionName(通过 `package_info_plus`),并与服务端对比。
|
||
|
||
---
|
||
|
||
## 3. 打开商店
|
||
|
||
```dart
|
||
// 自动判断平台:iOS → App Store,Android → marketUrl
|
||
await sdk.openStore(info);
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 直接下载 APK(Android)
|
||
|
||
```dart
|
||
// 打开 APK 下载链接(使用系统浏览器或下载器)
|
||
await sdk.openDownloadUrl(info);
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 强制更新处理
|
||
|
||
```dart
|
||
import 'package:flutter/material.dart';
|
||
import 'package:xuqm_flutter_update/xuqm_flutter_update.dart';
|
||
|
||
Future<void> checkAndHandleUpdate(BuildContext context) async {
|
||
final sdk = XuqmUpdateSdk();
|
||
final info = await sdk.checkAppUpdate();
|
||
|
||
if (!info.needsUpdate) return;
|
||
|
||
if (info.forceUpdate) {
|
||
// 强制更新:不可关闭的 Dialog
|
||
showDialog(
|
||
context: context,
|
||
barrierDismissible: false,
|
||
builder: (_) => AlertDialog(
|
||
title: const Text('发现重要更新'),
|
||
content: Text('当前版本已不可用,请升级至 ${info.versionName}'),
|
||
actions: [
|
||
TextButton(
|
||
onPressed: () => sdk.openStore(info),
|
||
child: const Text('立即更新'),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
} else {
|
||
// 可选更新:普通 Dialog
|
||
showDialog(
|
||
context: context,
|
||
builder: (_) => AlertDialog(
|
||
title: Text('发现新版本 ${info.versionName}'),
|
||
content: Text(info.changeLog ?? ''),
|
||
actions: [
|
||
TextButton(onPressed: () => Navigator.pop(context), child: const Text('稍后')),
|
||
TextButton(onPressed: () => sdk.openStore(info), child: const Text('立即更新')),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. AppUpdateInfo 字段说明
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `needsUpdate` | `bool` | 是否有新版本 |
|
||
| `forceUpdate` | `bool` | 是否强制更新 |
|
||
| `versionName` | `String?` | 新版本名称(如 `1.2.3`)|
|
||
| `versionCode` | `int?` | 新版本号 |
|
||
| `changeLog` | `String?` | 更新说明 |
|
||
| `downloadUrl` | `String?` | APK 直接下载地址(Android)|
|
||
| `appStoreUrl` | `String?` | App Store 链接(iOS)|
|
||
| `marketUrl` | `String?` | 各大应用商店链接(Android)|
|
||
|
||
---
|
||
|
||
## 7. 开发模式(模拟低版本)
|
||
|
||
```dart
|
||
// 仅在开发/测试时使用,模拟当前版本为 1,触发更新提示
|
||
XuqmUpdateSdk.devSetAppVersion(1, '0.0.1');
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 完整示例
|
||
|
||
```dart
|
||
import 'package:flutter/material.dart';
|
||
import 'package:xuqm_flutter_sdk/xuqm_flutter_sdk.dart';
|
||
import 'package:xuqm_flutter_update/xuqm_flutter_update.dart';
|
||
|
||
void main() async {
|
||
WidgetsFlutterBinding.ensureInitialized();
|
||
await XuqmSDK.initialize(XuqmInitOptions(appKey: 'your_app_key'));
|
||
runApp(const MyApp());
|
||
}
|
||
|
||
class MyApp extends StatefulWidget {
|
||
const MyApp({super.key});
|
||
|
||
@override
|
||
State<MyApp> createState() => _MyAppState();
|
||
}
|
||
|
||
class _MyAppState extends State<MyApp> {
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
WidgetsBinding.instance.addPostFrameCallback((_) => _checkUpdate());
|
||
}
|
||
|
||
Future<void> _checkUpdate() async {
|
||
final sdk = XuqmUpdateSdk();
|
||
final info = await sdk.checkAppUpdate();
|
||
if (info.needsUpdate && mounted) {
|
||
showDialog(
|
||
context: context,
|
||
barrierDismissible: !info.forceUpdate,
|
||
builder: (_) => AlertDialog(
|
||
title: Text('新版本 ${info.versionName}'),
|
||
content: Text(info.changeLog ?? ''),
|
||
actions: [
|
||
if (!info.forceUpdate)
|
||
TextButton(onPressed: () => Navigator.pop(context), child: const Text('稍后')),
|
||
TextButton(onPressed: () => sdk.openStore(info), child: const Text('更新')),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) => const MaterialApp(home: Scaffold());
|
||
}
|
||
```
|