import 'dart:async'; import 'dart:convert'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:geolocator/geolocator.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:permission_handler/permission_handler.dart'; // 确保引用这个做权限请求 class MapController extends GetxController with BaseControllerMixin { @override String get builderId => 'map'; InAppWebViewController? webViewController; StreamSubscription? positionStream; final RxBool isLocationPermissionGranted = false.obs; // 缓存最后一次的位置,防止 WebView 加载慢于定位 Position? _lastKnownPosition; // 是否已经初始化过地图中心 bool _hasInitializedMapCenter = false; @override void onInit() { super.onInit(); requestLocationPermission(); } @override void onClose() { positionStream?.cancel(); super.onClose(); } // 请求权限 void requestLocationPermission() async { var status = await Permission.locationWhenInUse.request(); print("权限状态: $status"); // 在控制台看这个输出 if (status.isGranted) { isLocationPermissionGranted.value = true; showToast('定位权限已获取'); _startLocationTracking(); } else if (status.isPermanentlyDenied) { // iOS 特性:如果你之前点过“不允许”,之后再请求都会直接进这里 isLocationPermissionGranted.value = false; // 引导用户去设置页面开启 openAppSettings(); } else { // 第一次被拒绝,或者其他情况 isLocationPermissionGranted.value = false; showErrorToast('需要定位权限才能显示您的位置'); } } // 开启定位监听 void _startLocationTracking() async { // 再次检查服务是否开启 bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { return; } const LocationSettings locationSettings = LocationSettings( accuracy: LocationAccuracy.high, distanceFilter: 50, // 移动更新范围 ); // 先获取一次当前位置,用于快速初始化中心 Geolocator.getCurrentPosition().then((position) { _lastKnownPosition = position; _syncLocationToMap(position, isInit: true); }); // 持续监听 positionStream = Geolocator.getPositionStream(locationSettings: locationSettings) .listen((Position position) { _lastKnownPosition = position; _syncLocationToMap(position, isInit: false); }); } // 将位置同步给 JS void _syncLocationToMap(Position position, {required bool isInit}) { if (webViewController == null) return; // 如果是第一次定位,或者 WebView 刚加载完且从未设置过中心 if (isInit || !_hasInitializedMapCenter) { webViewController!.evaluateJavascript( source: "initLocation(${position.latitude}, ${position.longitude})" ); _hasInitializedMapCenter = true; } else { // 后续只更新图标位置,不强行移动地图中心(防止用户拖动地图看别处时被拉回) webViewController!.evaluateJavascript( source: "updateMyLocation(${position.latitude}, ${position.longitude}, ${position.heading})" ); } } // WebView 加载完成回调 void onWebViewLoadStop() { // 页面加载完了,如果我们已经拿到了定位数据,立刻设置地图中心 if (_lastKnownPosition != null) { _syncLocationToMap(_lastKnownPosition!, isInit: true); } // 如果业务需要,可以在这里加载默认的推荐路径 // loadRecommendedRoute(); } // 模拟:获取你的后台推荐路径 void loadRecommendedRoute() { // 示例数据 List> routePoints = [ [116.397428, 39.90923], [116.398000, 39.90950], [116.400000, 39.91000], ]; String jsonPoints = jsonEncode(routePoints); webViewController?.evaluateJavascript(source: "drawCustomRoute($jsonPoints)"); } }