Flutter地图定位插件amap_flutter_location的使用
Flutter地图定位插件amap_flutter_location的使用
前述
- 高德定位Flutter插件
- 登录高德开放平台官网分别申请Android端和iOS端的key。
- 如需了解高德定位SDK的相关功能,请参阅Android定位SDK开发指南和iOS定位SDK开发指南。
使用高德定位Flutter插件
- 请参考在Flutter里使用Packages, 引入
amap_flutter_location
插件。 - 引入高德定位SDK,Android平台请参考Android Studio配置工程, iOS平台请参考ios安装定位SDK。
常见问题:
$ rm ios/Podfile
$ flutter build ios
在需要的定位功能的页面中引入定位Flutter插件的dart类
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
接口说明
设置定位参数
/// 设置定位参数
void setLocationOption(AMapLocationOption locationOption)
示例代码:
//// 是否需要地址信息,默认true
bool needAddress = true;
///逆地理信息语言类型<br>
///默认[GeoLanguage.DEFAULT] 自动适配<br>
///可选值:<br>
///<li>[GeoLanguage.DEFAULT] 自动适配</li>
///<li>[GeoLanguage.EN] 英文</li>
///<li>[GeoLanguage.ZH] 中文</li>
GeoLanguage geoLanguage;
///是否单次定位
///默认值:false
bool onceLocation = false;
///Android端定位模式, 只在Android系统上有效<br>
///默认值:[AMapLocationMode.Hight_Accuracy]<br>
///可选值:<br>
///<li>[AMapLocationMode.Battery_Saving]</li>
///<li>[AMapLocationMode.Device_Sensors]</li>
///<li>[AMapLocationMode.Hight_Accuracy]</li>
AMapLocationMode locationMode;
///Android端定位间隔<br>
///单位:毫秒<br>
///默认:2000毫秒<br>
int locationInterval = 2000;
///iOS端是否允许系统暂停定位<br>
///默认:false
bool pausesLocationUpdatesAutomatically = false;
/// iOS端期望的定位精度, 只在iOS端有效<br>
/// 默认值:最高精度<br>
/// 可选值:<br>
/// <li>[DesiredAccuracy.Best] 最高精度</li>
/// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
/// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
/// <li>[DesiredAccuracy.Kilometer] 1000米</li>
/// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
DesiredAccuracy desiredAccuracy = DesiredAccuracy.Best;
/// iOS端定位最小更新距离<br>
/// 单位:米<br>
/// 默认值:-1,不做限制<br>
double distanceFilter = -1;
///iOS 14中设置期望的定位精度权限
AMapLocationAccuracyAuthorizationMode desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.FullAccuracy;
/// iOS 14中定位精度权限由模糊定位升级到精确定位时,需要用到的场景key fullAccuracyPurposeKey 这个key要和plist中的配置一样
String fullAccuracyPurposeKey = "";
开始定位
void startLocation()
停止定位
void stopLocation()
销毁定位
高德定位Flutter插件,支持多实例,请在weidet执行dispose()时调用当前定位插件的销毁方法
void destroy()
定位结果获取
原生端以键值对map的形式回传定位结果到Flutter端, 通过onLoationChanged返回定位结果
Stream<Map<String, Object>> onLocationChanged()
注册定位结果监听
_locationPlugin
.onLocationChanged()
.listen((Map<String, Object> result) {
///result即为定位结果
}
定位结果是以map的形式返回的,具体内容为:
/// `callbackTime`:回调时间,格式为"yyyy-MM-dd HH:mm:ss"
///
/// `locationTime`:定位时间, 格式为"yyyy-MM-dd HH:mm:ss"
///
/// `locationType`: 定位类型, 具体类型可以参考https://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type
///
/// `latitude`:纬度
///
/// `longitude`:精度
///
/// `accuracy`:精确度
///
/// `altitude`:海拔, android上只有locationType==1时才会有值
///
/// `bearing`: 角度,android上只有locationType==1时才会有值
///
/// `speed`:速度, android上只有locationType==1时才会有值
///
/// `country`: 国家,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `province`: 省,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `city`: 城市,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `district`: 城镇(区),android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `street`: 街道,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `streetNumber`: 门牌号,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `cityCode`: 城市编码,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `adCode`: 区域编码, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `address`: 地址信息, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `description`: 位置语义, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
///
/// `errorCode`: 错误码,当定位失败时才会返回对应的错误码, 具体错误请参考:https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode
///
/// `errorInfo`: 错误信息, 当定位失败时才会返回
示例Demo
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
Map<String, Object>? _locationResult;
StreamSubscription<Map<String, Object>>? _locationListener;
AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
@override
void initState() {
super.initState();
/// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
///
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
/// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
///
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
///
/// [hasContains] 隐私声明中是否包含高德隐私政策说明
///
/// [hasShow] 隐私权政策是否弹窗展示告知用户
AMapFlutterLocation.updatePrivacyShow(true, true);
/// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
///
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
///
/// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
///
/// [hasAgree] 隐私权政策是否已经取得用户同意
AMapFlutterLocation.updatePrivacyAgree(true);
/// 动态申请定位权限
requestPermission();
///设置Android和iOS的apiKey<br>
///key的申请请参考高德开放平台官网说明<br>
///Android: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key
///iOS: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key
AMapFlutterLocation.setApiKey("1dbf56e2e8a4d0e4cdc2df9efd36bc71", "dfb64c0463cb53927914364b5c09aba0");
///iOS 获取native精度类型
if (Platform.isIOS) {
requestAccuracyAuthorization();
}
///注册定位结果监听
_locationListener = _locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
setState(() {
_locationResult = result;
});
});
}
@override
void dispose() {
super.dispose();
///移除定位监听
if (null != _locationListener) {
_locationListener?.cancel();
}
///销毁定位
_locationPlugin.destroy();
}
///设置定位参数
void _setLocationOption() {
AMapLocationOption locationOption = new AMapLocationOption();
///是否单次定位
locationOption.onceLocation = false;
///是否需要返回逆地理信息
locationOption.needAddress = true;
///逆地理信息的语言类型
locationOption.geoLanguage = GeoLanguage.DEFAULT;
locationOption.desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
///设置Android端连续定位的定位间隔
locationOption.locationInterval = 2000;
///设置Android端的定位模式<br>
///可选值:<br>
///<li>[AMapLocationMode.Battery_Saving]</li>
///<li>[AMapLocationMode.Device_Sensors]</li>
///<li>[AMapLocationMode.Hight_Accuracy]</li>
locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
///设置iOS端的定位最小更新距离<br>
locationOption.distanceFilter = -1;
///设置iOS端期望的定位精度
/// 可选值:<br>
/// <li>[DesiredAccuracy.Best] 最高精度</li>
/// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
/// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
/// <li>[DesiredAccuracy.Kilometer] 1000米</li>
/// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
locationOption.desiredAccuracy = DesiredAccuracy.Best;
///设置iOS端是否允许系统暂停定位
locationOption.pausesLocationUpdatesAutomatically = false;
///将定位参数设置给定位插件
_locationPlugin.setLocationOption(locationOption);
}
///开始定位
void _startLocation() {
///开始定位之前设置定位参数
_setLocationOption();
_locationPlugin.startLocation();
}
///停止定位
void _stopLocation() {
_locationPlugin.stopLocation();
}
Container _createButtonContainer() {
return new Container(
alignment: Alignment.center,
child: new Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new ElevatedButton(
onPressed: _startLocation,
child: new Text('开始定位'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white),
),
),
new Container(width: 20.0),
new ElevatedButton(
onPressed: _stopLocation,
child: new Text('停止定位'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white),
),
)
],
));
}
Widget _resultWidget(key, value) {
return new Container(
child: new Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
alignment: Alignment.centerRight,
width: 100.0,
child: new Text('$key :'),
),
new Container(width: 5.0),
new Flexible(child: new Text('$value', softWrap: true)),
],
),
);
}
@override
Widget build(BuildContext context) {
List<Widget> widgets = <Widget>[];
widgets.add(_createButtonContainer());
if (_locationResult != null) {
_locationResult?.forEach((key, value) {
widgets.add(_resultWidget(key, value));
});
}
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('AMap Location plugin example app'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: widgets,
),
));
}
///获取iOS native的accuracyAuthorization类型
void requestAccuracyAuthorization() async {
AMapAccuracyAuthorization currentAccuracyAuthorization = await _locationPlugin.getSystemAccuracyAuthorization();
if (currentAccuracyAuthorization == AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
print("精确定位类型");
} else if (currentAccuracyAuthorization == AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
print("模糊定位类型");
} else {
print("未知定位类型");
}
}
/// 动态申请定位权限
void requestPermission() async {
// 申请权限
bool hasLocationPermission = await requestLocationPermission();
if (hasLocationPermission) {
print("定位权限申请通过");
} else {
print("定位权限申请不通过");
}
}
/// 申请定位权限
/// 授予定位权限返回true, 否则返回false
Future<bool> requestLocationPermission() async {
//获取当前的权限
var status = await Permission.location.status;
if (status == PermissionStatus.granted) {
//已经授权
return true;
} else {
//未授权则发起一次申请
status = await Permission.location.request();
if (status == PermissionStatus.granted) {
return true;
} else {
return false;
}
}
}
}
以上是关于amap_flutter_location
插件的基本使用方法和一个完整的示例Demo。希望对您有所帮助!
更多关于Flutter地图定位插件amap_flutter_location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图定位插件amap_flutter_location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用 amap_flutter_location
插件在 Flutter 中实现地图定位的示例代码。amap_flutter_location
插件是用于集成高德地图定位功能的 Flutter 插件。
首先,确保你已经在你的 pubspec.yaml
文件中添加了 amap_flutter_location
依赖:
dependencies:
flutter:
sdk: flutter
amap_flutter_location: ^^最新版本号 # 请替换为最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来,在你的 Flutter 项目中实现定位功能。以下是一个完整的示例代码:
main.dart
import 'package:flutter/material.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_map/amap_flutter_map.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter AMap Location Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MapScreen(),
);
}
}
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
AmapFlutterLocation _locationPlugin = AmapFlutterLocation();
AMapController? _mapController;
LatLng? _currentPosition;
@override
void initState() {
super.initState();
_initLocation();
}
Future<void> _initLocation() async {
bool hasPermission = await _locationPlugin.checkPermission();
if (!hasPermission) {
bool requestPermission = await _locationPlugin.requestPermission();
if (requestPermission) {
_startLocation();
} else {
print("定位权限被拒绝");
}
} else {
_startLocation();
}
}
Future<void> _startLocation() async {
_locationPlugin.addLocationListener(
(AmapLocation location) async {
if (location != null && location.errorCode == 0) {
setState(() {
_currentPosition = LatLng(location.latitude!, location.longitude!);
_moveToLocation(_currentPosition!);
});
} else {
print("定位失败,错误码:${location?.errorCode}");
}
},
);
_locationPlugin.startLocation();
}
Future<void> _moveToLocation(LatLng position) async {
if (_mapController != null) {
_mapController!.moveCamera(CameraUpdate.newLatLngZoom(position, 16));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter AMap Location Demo'),
),
body: AmapView(
apiKey: '你的高德地图API Key', // 请替换为你的高德地图API Key
onMapCreated: (AMapController controller) {
_mapController = controller;
if (_currentPosition != null) {
_moveToLocation(_currentPosition!);
}
},
),
);
}
@override
void dispose() {
_locationPlugin.stopLocation();
_locationPlugin.removeLocationListener();
super.dispose();
}
}
说明
- 权限检查:在
_initLocation
方法中,我们首先检查应用是否有定位权限,如果没有,则请求权限。 - 启动定位:在获取到定位权限后,调用
_startLocation
方法启动定位服务,并添加一个定位监听器,在每次定位结果更新时回调。 - 地图显示:使用
AmapView
组件显示高德地图,并在地图创建完成后保存AMapController
实例。如果当前已有定位结果,则移动到该位置。 - 定位结果处理:在定位监听器中,如果定位成功(
errorCode
为 0),则更新当前位置,并调用_moveToLocation
方法将地图移动到该位置。 - 资源释放:在
dispose
方法中停止定位服务并移除定位监听器,以避免内存泄漏。
请确保你已经正确配置了高德地图的 API Key,并在 Android 和 iOS 项目中配置了相应的权限和设置。