- 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>
4.4 KiB
4.4 KiB
Flutter 版本更新接入指南
模块:xuqm_flutter_update · 功能:App 版本检查、商店跳转、APK 直接下载
1. 安装
在 pubspec.yaml 中添加:
dependencies:
xuqm_flutter_update:
git:
url: https://xuqinmin.com/xuqinmin12/XuqmGroup-FlutterSDK.git
ref: v0.2.0
path: packages/update
2. 检查版本更新
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. 打开商店
// 自动判断平台:iOS → App Store,Android → marketUrl
await sdk.openStore(info);
4. 直接下载 APK(Android)
// 打开 APK 下载链接(使用系统浏览器或下载器)
await sdk.openDownloadUrl(info);
5. 强制更新处理
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. 开发模式(模拟低版本)
// 仅在开发/测试时使用,模拟当前版本为 1,触发更新提示
XuqmUpdateSdk.devSetAppVersion(1, '0.0.1');
8. 完整示例
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());
}