|
|
|
@ -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; |
|
|
|
} |
|
|
|
|