Flutter返回页面后Location Services无法自动更新问题求助
解决定位服务开启后页面不自动更新的问题
你的问题核心在于:当用户从设置页开启定位服务返回后,代码没有重新触发定位获取流程。当前逻辑仅在页面初始化时执行一次_determinePosition(),但从设置返回后未重新检查服务状态或发起定位请求,导致位置信息无法自动更新。
以下是具体解决方案:
1. 监听定位服务状态变化
利用Geolocator提供的服务状态流,实时监听定位服务的开启/关闭状态,当服务从关闭变为开启时自动重新获取定位信息。
修改onInit方法添加状态监听:
@override void onInit() { super.onInit(); // 监听定位服务状态变化 streamSubscriptionServiceStatus = Geolocator.getServiceStatusStream().listen((ServiceStatus status) { if (status == ServiceStatus.enabled) { _determinePosition(); } }); _determinePosition(); }
同时在onClose中取消订阅避免内存泄漏:
@override void onClose() { streamSubscription?.cancel(); streamSubscriptionServiceStatus?.cancel(); super.onClose(); }
2. 从设置页返回后立即重新检查
修改对话框确认按钮逻辑,在用户从设置页返回后,主动检查定位服务状态并重新发起请求:
confirm: ElevatedButton( onPressed: () async { await Geolocator.openLocationSettings(); Get.back(); // 返回后重新检查服务状态 bool enabled = await Geolocator.isLocationServiceEnabled(); if (enabled) { _determinePosition(); } }, child: Text('Confirm')),
3. 优化定位流订阅逻辑
避免重复创建位置流订阅,在每次调用_determinePosition()前取消旧订阅:
// 取消旧订阅,避免重复监听 await streamSubscription?.cancel(); streamSubscription = Geolocator.getPositionStream().listen((Position position) { latitude.value = 'Latitude: ${position.latitude}'; longitude.value = 'Longtitude: ${position.longitude}'; getAddressFromLatLang(position); });
完整修改后的代码
import 'dart:async'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../../services/screenadapter.dart'; import 'package:geolocator/geolocator.dart'; import 'package:geocoding/geocoding.dart'; class HomeController extends GetxController { var latitude = 'Getting Latitude..'.obs; var longitude = 'Getting Longtitude..'.obs; var address = 'Getting Address..'.obs; StreamSubscription<Position>? streamSubscription; StreamSubscription<ServiceStatus>? streamSubscriptionServiceStatus; late LocationSettings locationSettings; _determinePosition() async { bool serviceEnabled; LocationPermission permission; serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { return Get.defaultDialog( title: 'Location Services Disabled', middleText: 'You need to enable Location Services in Setting', confirm: ElevatedButton( onPressed: () async { await Geolocator.openLocationSettings(); Get.back(); // 返回后重新检查服务状态 bool enabled = await Geolocator.isLocationServiceEnabled(); if (enabled) { _determinePosition(); } }, child: Text('Confirm')), cancel: ElevatedButton( onPressed: () { Get.back(); }, child: Text('Cancel'))); } permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { return Future.error('Location permissions are denied'); } } if (permission == LocationPermission.deniedForever) { return Future.error( 'Location permissions are permanently denied, we cannot request permissions.'); } // 取消旧订阅,避免重复监听 await streamSubscription?.cancel(); streamSubscription = Geolocator.getPositionStream().listen((Position position) { latitude.value = 'Latitude: ${position.latitude}'; longitude.value = 'Longtitude: ${position.longitude}'; getAddressFromLatLang(position); }); return await Geolocator.getCurrentPosition( forceAndroidLocationManager: true, desiredAccuracy: LocationAccuracy.best); } Future<void> getAddressFromLatLang(Position position) async { List<Placemark> placemark = await placemarkFromCoordinates(position.latitude, position.longitude); Placemark place = placemark[0]; address.value = 'GPS: ${place.name},${place.subLocality},${place.locality}'; } RxList itemList = [ { "id": 1, "name": "Great Nature Vegetarian", "image": "images/greatnature.jpg", "Hours": "9am - 10pm", "quality": "good", }, { "id": 2, "name": "Nature Vegan", "image": "images/naturevegan.jpg", "Hours": "8.30am - 10pm", "quality": "good", }, { "id": 3, "name": "Love Vege Vegetarian", "image": "images/lovevege.jpg", "Hours": "9am - 8pm", "quality": "good", }, { "id": 4, "name": "Namasthe Vegetarian", "image": "images/namasthe.jpg", "Hours": "9am - 8.30am", "quality": "good", }, { "id": 5, "name": "Organic Vegetarian Fresh Mart", "image": "images/organic.jpg", "Hours": "8am - 9.30am", "quality": "good", }, { "id": 6, "name": "Sweet Garden Vegetarian", "image": "images/sweetgarden.jpg", "Hours": "9.10am - 10pm", "quality": "good", }, { "id": 7, "name": "Tian Xin Vegetarian", "image": "images/tianxin.jpg", "Hours": "9am - 10pm", "quality": "good", }, ].obs; Row headerBottomBarWidget() { return Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ GestureDetector( onTap: (() { Get.toNamed('/search'); }), child: Icon(Icons.search, color: Colors.white), ) ], ); } Widget headerWidget(BuildContext context) { return SizedBox( child: Padding( padding: const EdgeInsets.all(8.0), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "Good Day", style: GoogleFonts.notoSansJavanese( fontSize: ScreenAdapter.fontSize(150), fontWeight: FontWeight.w700, color: Colors.white), ), SizedBox( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Welcome back!", style: GoogleFonts.notoSansJavanese( fontSize: ScreenAdapter.fontSize(85), fontWeight: FontWeight.w700, color: Colors.white)), Obx((() => Text(address.value, overflow: TextOverflow.ellipsis, style: GoogleFonts.notoSansJavanese( fontSize: ScreenAdapter.fontSize(40), fontWeight: FontWeight.w700, color: Colors.white)))) ], ), ), ], ), ), ); } ListView listView() { return ListView.builder( padding: const EdgeInsets.only(top: 0), physics: const NeverScrollableScrollPhysics(), itemCount: itemList.length, shrinkWrap: true, itemBuilder: (context, index) => Padding( padding: EdgeInsets.fromLTRB(ScreenAdapter.width(8), 0, ScreenAdapter.width(8), ScreenAdapter.width(15)), child: Container( width: ScreenAdapter.width(1080), height: ScreenAdapter.height(300), decoration: const BoxDecoration( color: Color.fromARGB(184, 252, 249, 249), borderRadius: BorderRadius.all(Radius.circular(10.0)), boxShadow: [ BoxShadow( color: Colors.white, offset: Offset(1.0, 5.0), blurRadius: 10.0, spreadRadius: 2.0) ]), child: Row( children: [ Container( width: ScreenAdapter.width(380), decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0)), image: DecorationImage( image: AssetImage("${itemList[index]['image']}"), fit: BoxFit.cover)), ), Expanded( child: Container( padding: EdgeInsets.fromLTRB( ScreenAdapter.width(8), 0, ScreenAdapter.width(8), 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("${itemList[index]['name']}"), const Icon( Icons.arrow_forward_ios_outlined, size: 13.0, ) ], ), Text("${itemList[index]['Hours']}"), const Icon(Icons.star_border_outlined) ], ), )) ], ), ), ), ); } @override void onInit() { super.onInit(); // 监听定位服务状态变化 streamSubscriptionServiceStatus = Geolocator.getServiceStatusStream().listen((ServiceStatus status) { if (status == ServiceStatus.enabled) { _determinePosition(); } }); _determinePosition(); } @override void onClose() { streamSubscription?.cancel(); streamSubscriptionServiceStatus?.cancel(); super.onClose(); } }
内容的提问来源于stack exchange,提问作者jordan
相关产品推荐
相关产品推荐

