Files
2026-09-03 17:50:23 +08:00

108 lines
3.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
/// 强制更新页:检测到新版本时的全屏阻塞页。
/// PopScope 禁返回(Android 系统返回 / iOS 边缘滑动均不可退出)。
/// 2026-09-03 改为浏览器下载:App 内 PackageInstaller 会话安装在小米等
/// ROM 上点系统确认框后失败(下载/写入正常但最终安装被拒),而系统浏览器
/// 下载 APK 后经通知栏走 ROM 自己的安装器可正常完成,故下载链接改由浏览器
/// 打开,不再 App 内下载/安装。仅点「立即更新」按钮时打开浏览器,不自动
/// 跳转;安装完成(versionName 追上服务器)后下次启动不再提示。
class UpdateScreen extends StatefulWidget {
final String version;
final String url;
final String notes;
const UpdateScreen({
super.key,
required this.version,
required this.url,
this.notes = '',
});
@override
State<UpdateScreen> createState() => _UpdateScreenState();
}
class _UpdateScreenState extends State<UpdateScreen> {
String? _message;
Future<void> _openBrowser() async {
final uri = Uri.tryParse(widget.url);
if (uri == null) {
setState(() => _message = '下载链接无效,请联系管理员');
return;
}
try {
final ok = await launchUrl(uri, mode: LaunchMode.externalApplication);
if (!mounted) return;
setState(() {
_message = ok ? '已打开浏览器下载,完成后点击通知栏的安装提示即可更新' : '打开浏览器失败,请点「立即更新」重试';
});
} catch (_) {
if (!mounted) return;
setState(() => _message = '打开浏览器失败,请点「立即更新」重试');
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return PopScope(
canPop: false,
child: Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.system_update_alt,
size: 64, color: theme.colorScheme.primary),
const SizedBox(height: 16),
Text('发现新版本 ${widget.version}',
style: theme.textTheme.headlineSmall),
const SizedBox(height: 12),
if (widget.notes.isNotEmpty)
Text(widget.notes,
textAlign: TextAlign.center,
style: const TextStyle(height: 1.6)),
const SizedBox(height: 24),
FilledButton.icon(
onPressed: _openBrowser,
icon: const Icon(Icons.open_in_browser),
label: const Text('立即更新'),
style: FilledButton.styleFrom(
minimumSize: const Size(200, 48),
textStyle: const TextStyle(fontSize: 16),
),
),
const SizedBox(height: 16),
Text(
'新版本需在浏览器下载 APK 后手动安装\n安装完成后请重新打开应用',
textAlign: TextAlign.center,
style: theme.textTheme.bodySmall
?.copyWith(color: theme.colorScheme.error),
),
if (_message != null) ...[
const SizedBox(height: 12),
Text(
_message!,
textAlign: TextAlign.center,
style: TextStyle(
height: 1.5,
color: _message!.startsWith('已打开')
? Colors.green
: theme.colorScheme.error,
),
),
],
],
),
),
),
),
);
}
}