import 'dart:io'; import 'package:dating_touchme_app/config/env_config.dart'; import 'package:dating_touchme_app/controller/global.dart'; import 'package:dating_touchme_app/controller/overlay_controller.dart'; import 'package:dating_touchme_app/im/im_manager.dart'; import 'package:dating_touchme_app/network/network_service.dart'; import 'package:dating_touchme_app/pages/main/main_page.dart'; import 'package:dating_touchme_app/pages/mine/login_page.dart'; import 'package:dating_touchme_app/pages/setting/teenager_mode_page.dart'; import 'package:dating_touchme_app/rtc/rtc_manager.dart'; import 'package:dating_touchme_app/widget/live/draggable_overlay_widget.dart'; import 'package:dating_touchme_app/widget/user_agreement_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:fluwx/fluwx.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'extension/my_cupertino_localizations.dart'; void main() async { // 设置全局错误处理 FlutterError.onError = (FlutterErrorDetails details) { FlutterError.presentError(details); if (kReleaseMode) { // 在生产环境中,可以将错误发送到错误收集服务 print('Flutter Error: ${details.exception}'); } }; // 处理异步错误 PlatformDispatcher.instance.onError = (error, stack) { print('Platform Error: $error'); print('Stack: $stack'); return true; }; try { WidgetsFlutterBinding.ensureInitialized(); // 初始化GetStorage await GetStorage.init(); // 设置环境配置 - 根据是否为release模式 EnvConfig.setEnvironment(Environment.dev); // 初始化RTC,如果失败也不阻止应用启动 try { await RTCManager.instance.initialize(appId: '4c2ea9dcb4c5440593a418df0fdd512d'); } catch (e) { print('RTC初始化失败: $e'); } // 注意:IM初始化改为异步,在应用启动后执行,避免阻塞应用启动 // IM初始化将在 MyApp 的 initState 中异步执行 // 初始化全局依赖 final networkService = NetworkService(); Get.put(networkService); Get.put(networkService.userApi); Get.put(networkService.homeApi); // 初始化全局 Overlay 控制器 Get.put(OverlayController()); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.dark, statusBarBrightness: Brightness.light, systemNavigationBarColor: Colors.white, systemNavigationBarIconBrightness: Brightness.dark, ), ); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); if (Platform.isIOS) { SystemChrome.setEnabledSystemUIMode( SystemUiMode.manual, overlays: [SystemUiOverlay.top], ); } } catch (e, stackTrace) { print('应用初始化失败: $e'); print('堆栈跟踪: $stackTrace'); // 即使初始化失败,也尝试启动应用 } runApp( GetMaterialApp( debugShowCheckedModeBanner: false, locale: Locale('zh', 'CN'), // 使用GetX的locale supportedLocales: const [Locale('zh', 'CN')], /// 国际化配置 代理 localizationsDelegates: const [ ChineseArabicMonthDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, // iOS ], theme: ThemeData( scaffoldBackgroundColor: Colors.white, // 设置导航栏样式 appBarTheme: AppBarTheme( systemOverlayStyle: SystemUiOverlayStyle( systemNavigationBarColor: Colors.white, systemNavigationBarIconBrightness: Brightness.light, ), ), ), builder: (context, child) { final smartDialogBuilder = FlutterSmartDialog.init(); return smartDialogBuilder( context, Stack( children: [ child ?? const SizedBox(), // 全局 overlay 组件 Obx(() { try { if (Get.isRegistered()) { final overlayController = Get.find(); return overlayController.showOverlay.value ? DraggableOverlayWidget( size: 60, backgroundColor: const Color.fromRGBO(0, 0, 0, 0.6), onClose: () { overlayController.hide(); }, ) : const SizedBox.shrink(); } } catch (e) { print('获取OverlayController失败: $e'); } return const SizedBox.shrink(); }), ], ), ); }, home: MyApp(), ), ); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { Fluwx fluwx = Fluwx(); bool _screenUtilInitialized = false; bool _showAgreementDialog = false; @override void initState() { super.initState(); _initFluwx(); // 异步初始化IM,避免阻塞应用启动 _initIMAsync(); // 检查是否已同意协议 _checkAgreement(); } /// 检查是否已同意用户协议 void _checkAgreement() { final storage = GetStorage(); final hasAgreed = storage.read('hasAgreedUserAgreement') ?? false; if (!hasAgreed) { // 延迟显示弹框,确保UI已初始化 WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { _showAgreementDialog = true; }); }); } } /// 处理同意协议 void _onAgreeAgreement() { final storage = GetStorage(); storage.write('hasAgreedUserAgreement', true); setState(() { _showAgreementDialog = false; }); } /// 处理不同意协议 - 退出应用 void _onDisagreeAgreement() { if (Platform.isIOS) { // iOS上退出应用 exit(0); } else { // Android上退出应用 SystemNavigator.pop(); } } /// 异步初始化IM SDK,避免阻塞应用启动 void _initIMAsync() { // 使用 Future.delayed 确保在应用完全启动后再初始化 Future.delayed(const Duration(milliseconds: 500), () async { try { print('🚀 开始异步初始化IM SDK(懒加载模式)...'); print('📋 AppKey: 1165251016193374#demo'); // 使用 ensureInitialized 方法,确保 init 至少被调用过一次 await IMManager.instance.ensureInitialized(appKey: '1165251016193374#demo'); print('✅ IM SDK异步初始化完成'); } catch (e, stackTrace) { print('❌ IM SDK异步初始化失败'); print('错误类型: ${e.runtimeType}'); print('错误信息: $e'); print('堆栈跟踪:'); print('$stackTrace'); // 检查是否是特定错误 if (e.toString().contains('PlatformException')) { print('⚠️ 可能是原生层配置问题,请检查:'); print(' 1. Android: 检查 AndroidManifest.xml 中的权限配置'); print(' 2. iOS: 检查 Info.plist 中的权限配置'); print(' 3. 检查网络连接'); } // IM初始化失败不应该阻止应用运行 } }); } _initFluwx() async { try { await fluwx.registerApi( appId: 'wx57624b8918fdd95c', doOnAndroid: true, doOnIOS: true, universalLink: 'https://your.univerallink.com/link/', ); await fluwx.isWeChatInstalled; } catch (e) { print('微信SDK初始化失败: $e'); // 微信SDK初始化失败不应该阻止应用运行 } } // This widget is the root of your application. @override Widget build(BuildContext context) { // ScreenUtil.init 只应该初始化一次,不应该在每次build时调用 if (!_screenUtilInitialized) { ScreenUtil.init(context, designSize: const Size(375, 812)); _screenUtilInitialized = true; } // 判断token是否为空 final storage = GetStorage(); final userId = storage.read('userId'); final teenagerMode = storage.read('teenagerMode') ?? false; GlobalData().teenagerMode = teenagerMode; Widget homeWidget; if(teenagerMode){ homeWidget = TeenagerModePage(); } else if (userId != null && userId.isNotEmpty) { // 如果token不为空,显示主页;如果token为空,显示登录页面 GlobalData().userId = userId; homeWidget = MainPage(); } else { homeWidget = LoginPage(); } // 如果需要显示协议弹框,则显示 if (_showAgreementDialog) { return Stack( children: [ homeWidget, UserAgreementDialog( onAgree: _onAgreeAgreement, onDisagree: _onDisagreeAgreement, ), ], ); } return homeWidget; } }