Position.longitude/latitude常无返回或返回null,权限已正常开启
Flutter Geolocator定位返回值异常排查与修复
问题描述
使用Geolocator获取定位时,Position.longitude或latitude多数情况下无返回值,偶尔返回null,定位权限已正常开启,无权限相关问题。
用户提供代码如下:
_LoadingScreenState 代码
class _LoadingScreenState extends State<LoadingScreen> { double latitude; double longitude ; @override void initState() { getLocation(); } void getLocation() async{ Location location = new Location(); await location.getCurrentLocation(); latitude = (location.latitude); longitude= (location.longitude); getData(); } void getData() async{ http.Response response = await http.get(Uri.parse('https://samples.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude &appid= $apiKey')); if(response.statusCode == 200){ String data = response.body ; var decodedData = jsonDecode(data); var weatherDescription = decodedData["weather"][0]["description"]; int id = decodedData["weather"][0]["id"]; double temp = decodedData["main"]["temp"]; String city = decodedData["name"]; print("hi"); print(id); print(temp); print(city); print(latitude); print(longitude); } else { print(response.statusCode); } }
Location 类代码
import 'package:geolocator/geolocator.dart'; import 'package:flutter/material.dart'; class Location{ double latitude ; double longitude ; Future <void> getCurrentLocation() async{ try { Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.low); latitude = position.latitude; longitude = position.longitude; } catch (exception){ print(exception); } } }
问题分析
- 异常捕获不完整:仅捕获通用异常,未处理Geolocator特有的定位服务禁用、权限变更等异常,这些场景会导致
latitude/longitude未赋值,保持初始null。 - 缺失定位服务状态检查:即使权限开启,设备定位服务(GPS/网络定位)可能未启用,此时定位请求会直接失败,但代码未做校验。
- 无超时与精度优化:
getCurrentPosition默认无超时限制,若定位长时间无法获取,后续代码会拿到空值;LocationAccuracy.low精度较低,部分场景下定位成功率不足。 - 网络请求参数错误:URL中
lon=$longitude后存在多余空格,会导致参数解析失败。
修复方案
1. 完善Location类的定位逻辑
import 'package:geolocator/geolocator.dart'; class Location{ double? latitude ; double? longitude ; Future<void> getCurrentLocation() async{ // 检查定位服务是否开启 bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { print("定位服务未开启,请打开设备定位"); return; } // 二次确认权限状态 LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { print("定位权限被拒绝"); return; } } try { // 设置超时限制与更高精度 Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, timeLimit: const Duration(seconds: 10) ); latitude = position.latitude; longitude = position.longitude; } on LocationServiceDisabledException { print("定位服务已被禁用"); } on PermissionDeniedException { print("定位权限被拒绝"); } on TimeoutException { print("定位请求超时"); } catch (e) { print("定位失败: $e"); } } }
2. 添加空值校验,避免无效请求
void getLocation() async{ Location location = Location(); await location.getCurrentLocation(); // 确认定位值有效后再发起网络请求 if(location.latitude != null && location.longitude != null){ latitude = location.latitude; longitude = location.longitude; getData(); } else { print("未获取到有效定位信息"); // 此处可添加重试逻辑或用户提示 } }
3. 修正网络请求参数
http.Response response = await http.get(Uri.parse('https://samples.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&appid=$apiKey'));
额外建议
- 增加定位重试机制:首次定位失败时,可尝试2-3次请求提升成功率。
- 改用
getPositionStream:若需持续获取定位,监听定位流比单次请求更稳定可靠。
内容的提问来源于stack exchange,提问作者Eman Ateyeh
相关产品推荐
相关产品推荐

