amap_flutter_location_plus_x_maintained
高德定位 SDK 的 Flutter 插件,封装 Android 和 iOS 原生定位能力。插件支持多实例、连续定位、单次定位、逆地理信息、iOS 14+ 定位精度授权和高德隐私合规初始化。
当前维护版本针对以下 SDK 版本验证:
- Android:高德定位 SDK
11.1.000 - iOS:CocoaPods
AMapLocation 2.11.1 - Flutter:
>=3.29.0
安装
在应用的 pubspec.yaml 中添加:
dependencies:
amap_flutter_location_plus_x_maintained: ^1.1.0
然后执行:
flutter pub get
使用前配置
默认高德模式下,插件不替应用保存 API Key;宿主应用需要按照自己的隐私合规流程完成以下配置。Core Location 模式会按需触发系统定位权限请求,但用途说明和权限策略仍由宿主应用负责。
1. 配置高德 API Key
分别在高德开放平台申请 Android 和 iOS Key,并在应用运行时传入。不要把真实 Key 写入插件源码、示例代码或日志。
2. 配置 Android
宿主应用的 android/app/src/main/AndroidManifest.xml 至少声明定位权限:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
如果应用需要后台定位,还需要根据 Android 版本配置 ACCESS_BACKGROUND_LOCATION、前台服务权限及对应的前台服务。定位权限仍须由宿主应用在运行时申请。
由于插件的 Android 原生依赖使用 compileOnly,宿主应用必须提供高德 Android 定位 SDK 运行时依赖:
dependencies {
implementation 'com.amap.api:location:11.1.000'
}
如果宿主应用同时使用其他高德插件,请确认它们使用的高德 SDK 版本和类没有重复打包;版本冲突时以宿主应用的统一依赖策略为准。
3. 配置 iOS
在宿主应用的 Info.plist 中配置用途说明:
<key>NSLocationWhenInUseUsageDescription</key>
<string>用于获取当前位置。</string>
需要后台定位时,再按业务和系统版本补充 NSLocationAlwaysAndWhenInUseUsageDescription、后台 Location Updates 能力等配置。需要从模糊定位临时提升到精确定位时,配置 NSLocationTemporaryUsageDescriptionDictionary,并让字典中的 Key 与 fullAccuracyPurposeKey 一致。
4. Apple Silicon iOS 模拟器
官方 AMapLocation 依赖的 AMapFoundation 当前不提供 arm64-simulator slice。默认模式会保留真机的高德实现,但在 Apple Silicon 模拟器上只能生成 x86_64 模拟器包,不能运行在只接受 arm64 的新模拟器环境中。
插件提供一个显式的 Core Location 模式,用于在不加载 AMapLocation 的情况下运行模拟器。该模式保留原有 Dart/MethodChannel API,但它不是高德定位 SDK:
- 坐标来自 Apple Core Location,坐标系为
WGS84,不是高德常用的GCJ-02; - 逆地理编码使用系统
CLGeocoder,字段和结果覆盖范围不等同于高德逆地理; setApiKey和高德隐私接口仅为兼容 API 返回成功,不会初始化高德 SDK;- 有效定位结果会额外返回
locationSource: core_location和coordinateSystem: wgs84,便于业务区分数据来源。
CocoaPods 在 pod install 时还不知道稍后 Xcode 会选择真机还是模拟器,因此不能自动按目标设备切换依赖。切换到模拟器模式时,在宿主 App 根目录执行:
flutter clean
flutter pub get
AMAP_FLUTTER_LOCATION_BACKEND=core_location pod install --project-directory=ios
AMAP_FLUTTER_LOCATION_BACKEND=core_location flutter run --device-id=<arm64 模拟器 UDID>
如果宿主 App 使用的是 Flutter 自动生成的插件链接,先执行 flutter pub get 再执行上面的 pod install,确保 CocoaPods 使用当前插件源码。
如果宿主 App 的 ios/Podfile 还手工声明了 pod 'AMapLocation', '2.11.1',Core Location 模式下必须同步移除或按 AMAP_FLUTTER_LOCATION_BACKEND 条件跳过这条声明;否则宿主仍会把不支持 arm64-simulator 的高德依赖安装进来,插件自身的切换不会生效。
切回真机高德模式时执行:
AMAP_FLUTTER_LOCATION_BACKEND=amap pod install --project-directory=ios
AMAP_FLUTTER_LOCATION_BACKEND=amap flutter run --device-id=<真机 UDID>
Core Location 模式仍需要在宿主 Info.plist 中配置 NSLocationWhenInUseUsageDescription。如果 App 同时依赖 amap_map,它仍可能单独引入不支持 arm64-simulator 的 AMapFoundation;只修改本定位插件不能消除地图插件带来的架构限制。
基本用法
建议在用户同意隐私政策后,按顺序完成隐私状态、API Key、监听、定位参数和启动:
import 'package:amap_flutter_location_plus_x_maintained/amap_flutter_location_plus.dart';
import 'package:amap_flutter_location_plus_x_maintained/amap_location_option.dart';
final location = AMapFlutterLocation();
Future<void> start() async {
await AMapFlutterLocation.updatePrivacyShow(true, true);
await AMapFlutterLocation.updatePrivacyAgree(true);
await AMapFlutterLocation.setApiKey(
androidKey,
iosKey,
);
final subscription = location.onLocationChanged().listen((result) {
final errorCode = result['errorCode'];
if (errorCode != null) {
// 根据业务展示或记录定位失败原因。
return;
}
final latitude = result['latitude'];
final longitude = result['longitude'];
// 使用 latitude、longitude 以及可选的地址字段。
});
final option = AMapLocationOption(
onceLocation: true,
needAddress: true,
)..fullAccuracyPurposeKey = 'AMapLocationScene';
await location.setLocationOption(option);
await location.startLocation();
// 页面销毁时:
// await location.stopLocation();
// await subscription.cancel();
// await location.destroy();
}
onLocationChanged() 返回 Stream<Map<String, Object>>。常见字段包括:
callbackTime:插件回调时间;locationTime:原生定位时间;latitude、longitude、accuracy:坐标和精度;locationType:高德定位类型;country、province、city、district、street、streetNumber:逆地理信息;address、description:格式化地址和位置语义;addressSource:地址来源,可能为amap_native或amap_native_regeo;errorCode、errorInfo:定位失败时的错误信息。
生命周期和注意事项
updatePrivacyShow、updatePrivacyAgree必须在定位接口前调用,并且应与应用自己的隐私同意流程一致。setApiKey、setLocationOption、startLocation、stopLocation和destroy都返回Future<void>,调用方应等待执行完成并处理PlatformException。AMapFlutterLocation支持多实例;每个实例只接收自己的定位事件。- 页面销毁时应停止定位、取消监听并调用
destroy(),避免原生定位客户端和 Dart 订阅泄漏。 AMapLocationOption.androidLocationScene设置为AMapAndroidLocationScene.SignIn时,Android 会使用单次高精度签到场景预设。- 插件只负责原生 SDK 桥接,不负责业务层的权限申请、隐私弹窗、Key 管理、坐标持久化或地址展示。
许可证
本项目保留高德定位插件原有 LICENSE 文件中的许可和免责声明。使用高德 SDK 时,还应遵守高德开放平台及其 SDK 的服务条款、隐私政策和合规要求。