You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
7.2 KiB
233 lines
7.2 KiB
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/themes/app_theme.dart';
|
|
import 'core/themes/theme_service.dart';
|
|
import 'core/bindings/initial_binding.dart';
|
|
import 'data/services/login_service.dart';
|
|
import 'dart:ui' as ui;
|
|
import 'modules/splash/controllers/splash_controller.dart';
|
|
|
|
bool _deepLinkHandlerInitialized = false;
|
|
|
|
void main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
// 初始化存储
|
|
await GetStorage.init();
|
|
|
|
// 加载环境变量
|
|
await dotenv.load(fileName: ".env");
|
|
print("环境变量加载成功");
|
|
|
|
// 初始化登录服务
|
|
Get.put(LoginService());
|
|
|
|
// 延迟初始化深链接处理器,确保Flutter完全准备好
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
Future.delayed(const Duration(milliseconds: 1500), () {
|
|
_initDeepLinkHandler();
|
|
});
|
|
});
|
|
|
|
runApp(MainApp());
|
|
}
|
|
|
|
// 初始化深链接处理器
|
|
void _initDeepLinkHandler() {
|
|
if (_deepLinkHandlerInitialized) return;
|
|
_deepLinkHandlerInitialized = true;
|
|
|
|
print("🔗 初始化深链接处理器");
|
|
|
|
const platform = MethodChannel('com.saitong.voitrans/deeplink');
|
|
|
|
platform.setMethodCallHandler((call) async {
|
|
print("🔗 Flutter 收到深链接调用: ${call.method}");
|
|
|
|
if (call.method == 'handleDeepLink') {
|
|
final arguments = call.arguments as Map<dynamic, dynamic>;
|
|
print("🔗 深链接参数: $arguments");
|
|
|
|
final url = arguments['url'] as String?;
|
|
if (url != null) {
|
|
print("🔗 处理深链接 URL: $url");
|
|
await _handleDeepLinkNavigation(url);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (call.method == 'handleSharedFile') {
|
|
final arguments = call.arguments as Map<dynamic, dynamic>;
|
|
final filePath = arguments['filePath'] as String?;
|
|
if (filePath == null || filePath.isEmpty) return;
|
|
await _handleSharedAudioFile(filePath);
|
|
return;
|
|
}
|
|
});
|
|
|
|
print("✅ 深链接处理器初始化完成");
|
|
}
|
|
|
|
// 处理深链接导航
|
|
Future<void> _handleDeepLinkNavigation(String url) async {
|
|
print("🔗 开始处理深链接导航: $url");
|
|
|
|
try {
|
|
final uri = Uri.parse(url);
|
|
print("🔗 解析URI: scheme=${uri.scheme}, host=${uri.host}, path=${uri.path}");
|
|
|
|
if (uri.scheme == 'deepvoice' && uri.host == 'qqmusic') {
|
|
print("🔗 检测到QQ音乐登录回调");
|
|
|
|
// 等待SplashController注册
|
|
int retryCount = 0;
|
|
const maxRetries = 10;
|
|
|
|
while (retryCount < maxRetries) {
|
|
try {
|
|
if (Get.isRegistered<SplashController>()) {
|
|
print("🔗 找到SplashController,处理QQ音乐登录");
|
|
final controller = Get.find<SplashController>();
|
|
controller.handleQQMusicLogin();
|
|
return;
|
|
}
|
|
} catch (e) {
|
|
print("🔗 获取SplashController失败: $e");
|
|
}
|
|
|
|
retryCount++;
|
|
print("🔗 等待SplashController注册 ($retryCount/$maxRetries)");
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
}
|
|
|
|
print("❌ 超时等待SplashController注册");
|
|
}
|
|
} catch (e) {
|
|
print("❌ 处理深链接时出错: $e");
|
|
}
|
|
}
|
|
|
|
Future<void> _handleSharedAudioFile(String filePath) async {
|
|
try {
|
|
if (!File(filePath).existsSync()) {
|
|
print("❌ 分享文件不存在: $filePath");
|
|
return;
|
|
}
|
|
|
|
int retryCount = 0;
|
|
const maxRetries = 10;
|
|
while (retryCount < maxRetries) {
|
|
try {
|
|
Get.toNamed(
|
|
Routes.meeting,
|
|
arguments: {
|
|
'filePath': filePath,
|
|
},
|
|
);
|
|
return;
|
|
} catch (e) {
|
|
retryCount++;
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print("❌ 处理分享文件失败: $e");
|
|
}
|
|
}
|
|
|
|
class MainApp extends StatelessWidget {
|
|
const MainApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// 在应用构建时立即初始化深链接处理
|
|
_initDeepLinkHandler();
|
|
// 获取保存的主题设置
|
|
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<AppLifecycleManager>()) return;
|
|
unawaited(
|
|
Get.find<AppLifecycleManager>().refreshBleWakeupPolicy(
|
|
route: routing?.current,
|
|
),
|
|
);
|
|
},
|
|
debugShowCheckedModeBanner: false,
|
|
translations: AppTranslations(),
|
|
localizationsDelegates: const [
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
],
|
|
locale: AppTranslations.deviceLocale(),
|
|
fallbackLocale: AppTranslations.getSmartFallbackLocale(),
|
|
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,
|
|
// );
|
|
// },
|
|
// );
|
|
}
|
|
}
|
|
|