import 'dart:io'; import 'package:get/get.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; class WebController extends GetxController { var title = ''; var url = ''; InAppWebViewController? webViewController; final isLoading = true.obs; final loadingProgress = 0.0.obs; final canGoBack = false.obs; // 添加是否可以回退的观察变量 // final _externalSchemes = [ // 'mailto:', // 'tel:', // 'sms:', // 'geo:', // 'intent:', // 'market:' // ]; @override void onInit() { if (Get.arguments != null) { title = Get.arguments['title'] ?? ''; url = Get.arguments['url'] ?? ''; } loadUserAgent(); super.onInit(); } Future loadUserAgent() async { initWebView(await generateUserAgent()); } Future generateUserAgent() async { try { final deviceInfo = DeviceInfoPlugin(); final packageInfo = await PackageInfo.fromPlatform(); if (Platform.isIOS) { final iosInfo = await deviceInfo.iosInfo; // 使用类似 Safari 的 UA 格式 return 'Mozilla/5.0 (iPhone; CPU iPhone OS ${iosInfo.systemVersion.replaceAll('.', '_')} like Mac OS X) ' 'AppleWebKit/605.1.15 (KHTML, like Gecko) ' 'Version/${packageInfo.version} Mobile/15E148 Safari/604.1'; } else { final androidInfo = await deviceInfo.androidInfo; // 使用简化的 Android UA 格式,避免 WebView 标识 return 'Mozilla/5.0 (Linux; Android ${androidInfo.version.release}; ${androidInfo.model}) ' 'AppleWebKit/537.36 (KHTML, like Gecko) ' 'Version/${packageInfo.version} Mobile Safari/537.36'; } } catch (e) { // 如果获取设备信息失败,返回一个通用的安全 UA return 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) ' 'AppleWebKit/605.1.15 (KHTML, like Gecko) ' 'Version/16.6 Mobile/15E148 Safari/604.1'; } } String? userAgent; void initWebView(String ua) { userAgent = ua; // InAppWebView 的初始化在 WebView 组件中完成 // 这里只需要设置 URL if (url.isNotEmpty) { // URL 将在 WebView 组件中加载 } } // 设置 WebViewController 的引用 void setWebViewController(InAppWebViewController controller) { webViewController = controller; // 设置 User Agent if (userAgent != null) { webViewController?.setSettings( settings: InAppWebViewSettings( userAgent: userAgent!, javaScriptEnabled: true, useShouldOverrideUrlLoading: true, useOnLoadResource: true, mediaPlaybackRequiresUserGesture: false, allowsInlineMediaPlayback: true, iframeAllow: "camera; microphone", iframeAllowFullscreen: true, ), ); } } // 检查是否可以回退的方法 Future checkCanGoBack() async { try { if (webViewController != null) { final canBack = await webViewController!.canGoBack(); canGoBack.value = canBack; } } catch (e) { // 如果检查失败,默认设置为false canGoBack.value = false; } return canGoBack.value; } // 回退方法 Future goBack() async { if (canGoBack.value && webViewController != null) { await webViewController!.goBack(); // 回退后重新检查状态 checkCanGoBack(); } } // 刷新方法 Future reload() async { if (webViewController != null) { await webViewController!.reload(); } } String? parseIntentUrl(String url) { if (!url.startsWith("intent://")) return url; // 提取 scheme final schemeMatch = RegExp(r"scheme=([a-zA-Z0-9.+-]+);").firstMatch(url); final scheme = schemeMatch?.group(1) ?? "https"; // 替换 intent:// -> scheme:// var cleanUrl = url .replaceFirst("intent://", "$scheme://") .replaceAll(RegExp(r"#Intent;.*;end$"), ""); return cleanUrl; } String? parseFallbackUrl(String url) { final match = RegExp(r"S\.browser_fallback_url=([^;]+);").firstMatch(url); return match != null ? Uri.decodeComponent(match.group(1)!) : null; } }