You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
  }
}

问题分析

  1. 异常捕获不完整:仅捕获通用异常,未处理Geolocator特有的定位服务禁用、权限变更等异常,这些场景会导致latitude/longitude未赋值,保持初始null。
  2. 缺失定位服务状态检查:即使权限开启,设备定位服务(GPS/网络定位)可能未启用,此时定位请求会直接失败,但代码未做校验。
  3. 无超时与精度优化:getCurrentPosition默认无超时限制,若定位长时间无法获取,后续代码会拿到空值;LocationAccuracy.low精度较低,部分场景下定位成功率不足。
  4. 网络请求参数错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 09:40:16