欢迎光临
我们一直在努力

Flutter定位开发实战:权限申请、坐标转换与地址解析完整流程

最近在做一个 Flutter 项目,需要实现:

  • 获取用户当前位置
  • 展示当前位置名称
  • 支持 iOS 和 Android
  • 用户拒绝授权时能够降级处理

刚开始以为很简单:

Geolocator.getCurrentPosition()

结果真正落地后才发现,定位功能远比想象中复杂:

  • Android 和 iOS 权限配置不同
  • 用户可能拒绝定位授权
  • 国内地图坐标系和 GPS 坐标系不一致
  • API Key 不能直接写进客户端
  • 定位失败时需要有降级方案

本文把完整实现流程记录下来。


一、项目依赖

dependencies:
flutter:
sdk: flutter

geolocator: ^10.1.0
permission_handler: ^11.0.1
http: ^1.1.0

flutter pub get

二、配置定位权限

Android

android/app/src/main/AndroidManifest.xml

<manifest>

<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"/>

</manifest>

如果是骑手、轨迹追踪等场景,可以额外增加:

<uses-permission
android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

普通 App 不建议申请后台定位。

iOS

ios/Runner/Info.plist

<key>NSLocationWhenInUseUsageDescription</key>
<string>用于获取当前位置信息</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>用于持续获取位置服务</string>

这里漏配置是最常见的问题之一。

很多人遇到:

定位无响应

实际上是权限描述没有配置。

三、封装定位服务

创建:

lib/utils/location_service.dart

import 'package:flutter/foundation.dart';
import 'package:geolocator/geolocator.dart';

class LocationService {

static Future<Position?> getCurrentPosition() async {

final serviceEnabled =
await Geolocator.isLocationServiceEnabled();

if (!serviceEnabled) {
await Geolocator.openLocationSettings();
return null;
}

LocationPermission permission =
await Geolocator.checkPermission();

if (permission == LocationPermission.denied) {
permission =
await Geolocator.requestPermission();
}

if (
permission == LocationPermission.denied ||
permission == LocationPermission.deniedForever
) {
await Geolocator.openAppSettings();
return null;
}

try {

return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
timeLimit: const Duration(seconds: 8),
);

} catch (e) {

debugPrint('定位失败: $e');
return null;
}
}
}

四、为什么定位成功了地图还会偏移?

这是国内定位开发最容易踩的坑。

很多开发者拿到经纬度后直接使用

position.latitude
position.longitude

然后发现:

地图标点偏移
位置不准确

原因是:

GPS原始坐标:WGS84

国内地图坐标:
GCJ02

两者并不一致。

在国内地图场景中,建议统一转换为 GCJ02 后再进行展示和计算。

五、为什么坐标转换要放后端?

很多项目喜欢:

客户端直接请求地图服务

这样虽然开发快,但有一个问题:

API Key暴露

只要别人反编译 APK:

Key直接泄露

后续可能产生大量盗刷。

因此推荐:

Flutter
↓
业务后端
↓
位置服务

统一由后端代理调用。

六、后端实现坐标转换与逆地理编码

Node.js 示例:

require('dotenv').config()

const express = require('express')
const axios = require('axios')

const app = express()

app.use(express.json())

统一请求头:

const LTS_HEADERS = {
Authorization: `Bearer ${process.env.LTS_API_KEY}`,
'Content-Type': 'application/json',
}

接口:

app.post('/api/location/resolve', async (req, res) => {

const { lat, lng } = req.body

try {

const convRes = await axios.post(
'https://lts.maiyun.net/api/service/geoconv',
{
from: 0,
points: [{ lat, lng }]
},
{
headers: LTS_HEADERS
}
)

if (
convRes.data.result !== 1 ||
!convRes.data.list?.length
) {
throw new Error('坐标转换失败')
}

const gcj02 = convRes.data.list[0]

const geoRes = await axios.post(
'https://lts.maiyun.net/api/service/geocode',
{
from: 3,
point: {
lat: gcj02.lat,
lng: gcj02.lng
}
},
{
headers: LTS_HEADERS
}
)

res.json({
gcj02Lat: gcj02.lat,
gcj02Lng: gcj02.lng,
address:
geoRes.data.address?.name ?? ''
})

} catch (e) {

res.status(500).json({
error: '位置解析失败'
})
}
})

七、定位失败怎么办?

真实用户环境里

关闭GPS
拒绝授权
系统限制
弱网环境

都可能导致定位失败。

因此建议增加降级策略。

例如:

GPS定位失败
↓
IP粗略定位
↓
用户手动选择位置

不要把定位成功率完全押在 GPS 上。

八、Flutter调用后端

final result =
await ApiService.resolveLocation(
position.latitude,
position.longitude,
);

获取返回结果:

setState(() {

_lat =
(result['gcj02Lat'] as num).toDouble();

_lng =
(result['gcj02Lng'] as num).toDouble();

_address =
result['address'] ?? '';

});

注意:

as num

不要直接:

as double

否则后端返回整数时容易出现:

type int is not a subtype of double

九、几个真实踩坑记录

问题原因解决方案
iOS定位无响应 Info.plist缺权限描述 补齐NSLocation字段
Android无法定位 Manifest缺权限声明 增加ACCESS_FINE_LOCATION
地图标点偏移 WGS84直接展示 转GCJ02
定位一直等待 没设置超时 增加timeLimit
API被盗刷 Key写在客户端 后端代理
定位失败白屏 没做降级 增加IP定位和手动选择

十、总结

一个看似简单的定位功能,实际涉及:

  • 权限管理
  • 系统兼容
  • 坐标转换
  • 地址解析
  • 接口安全
  • 异常降级

真正上线后,往往不是定位接口本身最耗时间,而是各种边界情况处理。

本文示例中使用的位置服务接口完成坐标转换和逆地理编码,同类能力在地图服务平台中都比较常见。选择时重点关注:

  • 坐标转换支持情况
  • 逆地理编码准确率
  • 接口稳定性
  • 调用成本

把这些基础能力做好之后,附近门店、轨迹记录、顺风车、配送、骑手定位等场景基本都能顺利落地。

赞(0)
未经允许不得转载:171主机测评 » Flutter定位开发实战:权限申请、坐标转换与地址解析完整流程
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址