From 845c2b3c36a66e8074388b5699449d8266aa7bdd Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Fri, 15 Aug 2025 21:09:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=90=AF=E5=8A=A8=E9=A1=B5):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=BD=91=E7=BB=9C=E8=BF=9E=E6=8E=A5=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在启动流程中增加网络连接检查,确保应用初始化前有可用网络 添加 connectivity_plus 依赖用于检测网络状态 实现网络检查失败时的重试机制和用户提示 --- .../splash/controllers/splash_controller.dart | 111 +++++++++++++++++- pubspec.yaml | 1 + 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/lib/modules/splash/controllers/splash_controller.dart b/lib/modules/splash/controllers/splash_controller.dart index 5c90dacca..3bf9f9071 100644 --- a/lib/modules/splash/controllers/splash_controller.dart +++ b/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 _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 _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 _startLoadingAnimation() { const totalDuration = 1500; // 动画总时长1.5秒 @@ -103,6 +175,8 @@ class SplashController extends GetxController { /// 将所有并行的后台任务打包成一个 Future Future _performParallelTasks() async { + //步骤2:检查网络连接状态 + await _checkNetworkStatus(); // 同样使用 Future.wait,确保此函数在所有子任务完成后才结束 await Future.wait([ _requestTrackingPermissionAsync(), @@ -211,3 +285,36 @@ class SplashController extends GetxController { } } } + +/// 显示无网络连接对话框并等待用户操作(阻塞版本) +Future _showNoNetworkDialogAndWait() async { + final completer = Completer(); + + 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; +} diff --git a/pubspec.yaml b/pubspec.yaml index 615a2346a..075c5b698 100644 --- a/pubspec.yaml +++ b/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: