import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_intro/flutter_intro.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'core/utils/app_lifecycle_manager.dart'; import 'routes/app_pages.dart'; import 'routes/app_routes.dart'; import 'core/translations/app_translations.dart'; import 'core/theme/app_theme.dart'; import 'core/theme/theme_service.dart'; import 'core/bindings/initial_binding.dart'; import 'core/utils/logger.dart'; import 'core/services/native_localization_sync.dart'; import 'data/models/appconfig.dart'; import 'data/services/login_service.dart'; import 'modules/meeting/controllers/meeting_home_controller.dart'; import 'modules/splash/controllers/splash_controller.dart'; bool _deepLinkHandlerInitialized = false; void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化存储 await GetStorage.init(); // 恢复 AI 入口可见性缓存(绑定/解绑时写入,与登录/网络无关) AppConfig.loadHideAiAssistantFromCache(); // 加载环境变量 await dotenv.load(fileName: ".env"); Logger.i("Main", "环境变量加载成功"); // 初始化文件日志 await Logger.initFileLog(); // 监听 native 通话翻译日志上报,统一写入 Dart 的同一个 app_*.log(一次启动只有一个日志文件) const EventChannel('com.yunqiinnovation.ble_service/call_log_events') .receiveBroadcastStream() .listen((e) { if (e is String) Logger.appendNative(e); }); const EventChannel('azure_speech/call_log_events') .receiveBroadcastStream() .listen((e) { if (e is String) Logger.appendNative(e); }); // 初始化登录服务 Get.put(LoginService()); // 延迟初始化深链接处理器,确保Flutter完全准备好 WidgetsBinding.instance.addPostFrameCallback((_) { Future.delayed(const Duration(milliseconds: 1500), () { _initDeepLinkHandler(); }); }); runApp(MainApp()); } // 初始化深链接处理器 void _initDeepLinkHandler() { if (_deepLinkHandlerInitialized) return; _deepLinkHandlerInitialized = true; Logger.d("DeepLink", "初始化深链接处理器"); const platform = MethodChannel('com.saitong.voitrans/deeplink'); platform.setMethodCallHandler((call) async { Logger.d("DeepLink", "Flutter 收到深链接调用: ${call.method}"); if (call.method == 'handleDeepLink') { final arguments = call.arguments as Map; Logger.d("DeepLink", "深链接参数: $arguments"); final url = arguments['url'] as String?; if (url != null) { Logger.d("DeepLink", "处理深链接 URL: $url"); await _handleDeepLinkNavigation(url); } return; } if (call.method == 'handleSharedFile') { final arguments = call.arguments as Map; final filePath = arguments['filePath'] as String?; if (filePath == null || filePath.isEmpty) return; await _handleSharedAudioFile(filePath); return; } }); Logger.i("DeepLink", "深链接处理器初始化完成"); } // 处理深链接导航 Future _handleDeepLinkNavigation(String url) async { Logger.d("DeepLink", "开始处理深链接导航: $url"); try { final uri = Uri.parse(url); Logger.d("DeepLink", "解析URI: scheme=${uri.scheme}, host=${uri.host}, path=${uri.path}"); if (uri.scheme == 'deepvoice' && uri.host == 'qqmusic') { Logger.i("DeepLink", "检测到QQ音乐登录回调"); // 等待SplashController注册 int retryCount = 0; const maxRetries = 10; while (retryCount < maxRetries) { try { if (Get.isRegistered()) { Logger.i("DeepLink", "找到SplashController,处理QQ音乐登录"); final controller = Get.find(); controller.handleQQMusicLogin(); return; } } catch (e) { Logger.e("DeepLink", "获取SplashController失败", e); } retryCount++; Logger.d("DeepLink", "等待SplashController注册 ($retryCount/$maxRetries)"); await Future.delayed(const Duration(milliseconds: 500)); } Logger.w("DeepLink", "超时等待SplashController注册"); } } catch (e) { Logger.e("DeepLink", "处理深链接时出错", e); } } Future _handleSharedAudioFile(String filePath) async { try { if (!File(filePath).existsSync()) { Logger.w("DeepLink", "分享文件不存在: $filePath"); return; } int retryCount = 0; const maxRetries = 10; while (retryCount < maxRetries) { try { if (Get.isRegistered()) { final controller = Get.find(); controller.addAudio(filePath); return; } Get.toNamed( Routes.meeting, arguments: { 'filePath': filePath, }, ); return; } catch (e) { retryCount++; await Future.delayed(const Duration(milliseconds: 300)); } } } catch (e) { Logger.e("DeepLink", "处理分享文件失败", e); } } class MainApp extends StatelessWidget { const MainApp({super.key}); @override Widget build(BuildContext context) { // 在应用构建时立即初始化深链接处理 _initDeepLinkHandler(); WidgetsBinding.instance.addPostFrameCallback((_) { unawaited(NativeLocalizationSync.syncToNative()); }); // 获取保存的主题设置 final themeMode = ThemeService().getThemeMode(); return ScreenUtilInit( designSize: const Size(375, 812), minTextAdapt: true, splitScreenMode: true, builder: (_, child) { return GetMaterialApp( title: 'Voitrans', theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, themeMode: themeMode, // 使用提前获取的主题模式 initialBinding: InitialBinding(), initialRoute: Routes.splash, getPages: AppPages.pages, routingCallback: (routing) { if (!Get.isRegistered()) return; unawaited( Get.find().refreshBleWakeupPolicy( route: routing?.current, ), ); }, debugShowCheckedModeBanner: false, translations: AppTranslations(), localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], locale: AppTranslations.deviceLocale(), fallbackLocale: AppTranslations.fallbackLocale, supportedLocales: AppTranslations.supportedLocales, builder: EasyLoading.init( builder: (BuildContext context, Widget? widget) { EasyLoading.instance.userInteractions = false; return MediaQuery( data: MediaQuery.of(context).copyWith( textScaler: TextScaler.noScaling, ), child: Intro( padding: EdgeInsets.zero, child: widget!, ), ); }, ), ); }); // // 使用 ScreenUtilInit 包装整个应用 // return ScreenUtilInit( // designSize: const Size(375, 812), // 设计稿尺寸,根据你的设计稿调整 // minTextAdapt: true, // splitScreenMode: true, // builder: (context, child) { // return GetMaterialApp( // title: 'VoiTrans', // theme: AppTheme.lightTheme, // darkTheme: AppTheme.darkTheme, // themeMode: ThemeService().getThemeMode(), // initialRoute: Routes.splash, // getPages: AppPages.pages, // initialBinding: InitialBinding(), // translations: AppTranslations(), // locale: Get.deviceLocale, // fallbackLocale: const Locale('en', 'US'), // debugShowCheckedModeBanner: false, // ); // }, // ); } }