Browse Source

feat(启动页): 添加网络连接检查功能

在启动流程中增加网络连接检查,确保应用初始化前有可用网络
添加 connectivity_plus 依赖用于检测网络状态
实现网络检查失败时的重试机制和用户提示
weicu
lxm 1 year ago
parent
commit
c4fcbed15d
  1. 111
      lib/modules/splash/controllers/splash_controller.dart
  2. 1
      pubspec.yaml

111
lib/modules/splash/controllers/splash_controller.dart

@ -4,6 +4,8 @@ import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:http/http.dart' as http;
import '../../../data/models/appconfig.dart';
import '../../../data/models/appconfig_model.dart';
@ -44,14 +46,14 @@ class SplashController extends GetxController {
return;
}
// 步骤 2: 并行执行所有启动任务,并等待它们全部完成
// 步骤 3: 并行执行所有启动任务,并等待它们全部完成
// Future.wait 会等待数组中所有的 Future 都完成后才继续
await Future.wait([
_startLoadingAnimation(), // 任务1: 最小动画时长
_performParallelTasks(), // 任务2: 其他所有后台任务
]);
// 步骤 3: 所有任务(动画和后台)都已完成,触发导航
// 步骤 4: 所有任务(动画和后台)都已完成,触发导航
_canNavigate.value = true;
}
@ -81,6 +83,76 @@ class SplashController extends GetxController {
return completer.future;
}
/// 网络连接检查
/// 网络连接检查 - 阻塞版本
Future<void> _checkNetworkStatus() async {
while (true) {
// 无限循环直到网络检查成功
try {
final connectivityResult = await Connectivity().checkConnectivity();
// 检查是否有网络连接
if (connectivityResult.contains(ConnectivityResult.none)) {
// 显示弹窗并等待用户操作
await _showNoNetworkDialogAndWait();
continue; // 重新检查
}
// 进一步检查网络连通性
final hasInternet = await _checkInternetConnection();
if (!hasInternet) {
// 显示弹窗并等待用户操作
await _showNoNetworkDialogAndWait();
continue; // 重新检查
}
// 网络检查成功,跳出循环
Logger.d(_tag, '网络检查成功,继续APP初始化流程');
break;
} catch (e) {
Logger.e(_tag, '网络检查失败: $e');
// 显示弹窗并等待用户操作
await _showNoNetworkDialogAndWait();
continue; // 重新检查
}
}
}
/// 检查实际的网络连通性
Future<bool> _checkInternetConnection() async {
final testUrls = [
'https://api.voitrans.net/ping', // 国内服
'https://hw.api.voitrans.net/ping', // 海外服
'https://www.baidu.com', // 百度
'https://www.google.com', // Google
];
for (final url in testUrls) {
try {
final response = await http.get(
Uri.parse(url.trim()), // 去除空格
headers: {'User-Agent': 'Voitrans-App'}, // 有助于后端识别
).timeout(const Duration(seconds: 5));
if (response.statusCode == 200) {
Logger.d(_tag, '网络连接检查成功: $url');
return true;
}
} on TimeoutException {
Logger.w(_tag, '网络连接超时: $url');
continue;
} on Exception catch (e) {
Logger.w(_tag, '网络连接失败: $url, 错误: $e');
continue;
}
}
Logger.e(_tag, '所有网络连接检查均失败');
return false;
}
/// 动画任务:返回一个在动画结束时完成的 Future
Future<void> _startLoadingAnimation() {
const totalDuration = 1500; // 动画总时长1.5秒
@ -103,6 +175,8 @@ class SplashController extends GetxController {
/// 将所有并行的后台任务打包成一个 Future
Future<void> _performParallelTasks() async {
//步骤2:检查网络连接状态
await _checkNetworkStatus();
// 同样使用 Future.wait,确保此函数在所有子任务完成后才结束
await Future.wait([
_requestTrackingPermissionAsync(),
@ -211,3 +285,36 @@ class SplashController extends GetxController {
}
}
}
/// 显示无网络连接对话框并等待用户操作(阻塞版本)
Future<void> _showNoNetworkDialogAndWait() async {
final completer = Completer<void>();
WidgetsBinding.instance.addPostFrameCallback((_) {
Get.dialog(
AlertDialog(
title: Row(
children: [
const Icon(Icons.wifi_off, color: Colors.orange),
const SizedBox(width: 8),
Text('networkError'.tr), // 无网络连接
],
),
content: Text('networkConnectionFailed'.tr), // 网络连接失败,请检查网络设置
actions: [
TextButton(
onPressed: () {
Get.back(); // 关闭弹窗
completer.complete(); // 完成Future,继续执行
},
child: Text('retry'.tr), // 重试
),
],
),
barrierDismissible: false, // 不允许点击外部关闭
);
});
// 等待用户点击重试按钮
return completer.future;
}

1
pubspec.yaml

@ -74,6 +74,7 @@ dependencies:
dio: ^5.8.0+1
sqflite: ^2.4.2
path: ^1.9.1
connectivity_plus: ^6.1.5 # 网络连接检测依赖
speech:
path: local_plugins/speech
azure_speech:

Loading…
Cancel
Save