main.dart
9.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:csp_amap_flutter_location/amap_flutter_location.dart';
import 'package:csp_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();
}
/// 应用状态类
/// 管理定位功能和UI展示
class _MyAppState extends State<MyApp> {
/// 存储定位结果
Map<String, Object>? _locationResult;
/// 定位结果监听器
StreamSubscription<Map<String, Object>>? _locationListener;
/// 高德定位插件实例
final 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
/// key的申请请参考高德开放平台官网说明
/// 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",
ohosKey: "1dbf56e2e8a4d0e4cdc2df9efd36bc71");
/// iOS 获取native精度类型
/// 仅在iOS平台上检查定位精度授权状态
if (Platform.isIOS) {
requestAccuracyAuthorization();
}
/// 注册定位结果监听
/// 通过监听器接收定位结果并更新UI
_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();
/// 是否单次定位
/// false表示连续定位
locationOption.onceLocation = true;
/// 是否需要返回逆地理信息
/// true表示需要返回地址信息
locationOption.needAddress = true;
/// 是否需要返回逆地理编码信息
locationOption.locatingWithReGeocode = true;
/// 逆地理信息的语言类型
/// 默认为自动适配当前系统语言
locationOption.geoLanguage = GeoLanguage.DEFAULT;
/// iOS 14定位精度权限设置
/// 设置为模糊定位精度
locationOption.desiredLocationAccuracyAuthorizationMode =
AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
/// iOS 14精确定位目的key
/// 需要与info.plist中配置一致
locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
/// 设置Android端连续定位的定位间隔
/// 单位:毫秒
locationOption.locationInterval = 2000;
/// 设置Android端的定位模式
/// 可选值:
/// [AMapLocationMode.Battery_Saving] 低功耗模式
/// [AMapLocationMode.Device_Sensors] 仅设备模式
/// [AMapLocationMode.Hight_Accuracy] 高精度模式
locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
/// 设置iOS端的定位最小更新距离
/// -1表示不限制距离
locationOption.distanceFilter = -1;
/// 设置iOS端期望的定位精度
/// 可选值:
/// [DesiredAccuracy.Best] 最高精度
/// [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
/// [DesiredAccuracy.NearestTenMeters] 10米
/// [DesiredAccuracy.Kilometer] 1000米
/// [DesiredAccuracy.ThreeKilometers] 3000米
locationOption.desiredAccuracy = DesiredAccuracy.Best;
/// 设置iOS端是否允许系统暂停定位
/// false表示不允许系统暂停定位
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: const Text('开始定位'),
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.blue),
foregroundColor: WidgetStateProperty.all(Colors.white),
),
),
new Container(width: 20.0),
new ElevatedButton(
onPressed: _stopLocation,
child: const Text('停止定位'),
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.blue),
foregroundColor: WidgetStateProperty.all(Colors.white),
),
)
],
));
}
/// 创建结果显示组件
/// 用于显示定位结果的每一项键值对
/// @param key 定位结果的键
/// @param value 定位结果的值
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: const Text('ST 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;
}
}
}
}