208 lines
7.0 KiB
Dart
208 lines
7.0 KiB
Dart
import 'dart:async';
|
||
import 'dart:io';
|
||
|
||
import 'package:amap_flutter_location/amap_flutter_location.dart';
|
||
import 'package:amap_flutter_location/amap_location_option.dart';
|
||
import 'package:amap_flutter_map/amap_flutter_map.dart';
|
||
import 'package:autosos_flutter/const_config.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:permission_handler/permission_handler.dart';
|
||
import 'package:amap_flutter_base/amap_flutter_base.dart';
|
||
|
||
class MapWidget extends StatefulWidget {
|
||
const MapWidget({super.key});
|
||
|
||
@override
|
||
State<MapWidget> createState() => _MapWidgetState();
|
||
}
|
||
|
||
class _MapWidgetState extends State<MapWidget> {
|
||
AMapController? _mapController;
|
||
Map<String, Object> _locationResult = {};
|
||
late StreamSubscription<Map<String, Object>> _locationListener;
|
||
final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
|
||
|
||
@override
|
||
void dispose() {
|
||
super.dispose();
|
||
_locationListener.cancel();
|
||
_locationPlugin.destroy();
|
||
}
|
||
|
||
@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>
|
||
///
|
||
/// 定位Flutter插件提供了单独的设置ApiKey的接口,
|
||
/// 使用接口的优先级高于通过Native配置ApiKey的优先级(通过Api接口配置后,通过Native配置文件设置的key将不生效),
|
||
/// 使用时可根据实际情况决定使用哪种方式
|
||
///
|
||
///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(ConstConfig.androidKey, ConstConfig.iosKey);
|
||
|
||
///iOS 获取native精度类型
|
||
if (Platform.isIOS) {
|
||
requestAccuracyAuthorization();
|
||
}
|
||
|
||
var option = AMapLocationOption();
|
||
_locationPlugin.setLocationOption(option);
|
||
|
||
///注册定位结果监听
|
||
_locationListener = _locationPlugin
|
||
.onLocationChanged()
|
||
.listen((Map<String, Object> result) {
|
||
setState(() {
|
||
_locationResult = result;
|
||
});
|
||
print("location=$_locationResult");
|
||
});
|
||
_locationPlugin.startLocation();
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
// 在页面渲染完成后执行代码
|
||
// 例如,你可以在此处执行需要在页面加载完成后执行的操作
|
||
});
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
AMapWidget map = AMapWidget(
|
||
///必须正确设置的合规隐私声明,否则SDK不会工作,会造成地图白屏等问题。
|
||
privacyStatement: ConstConfig.amapPrivacyStatement,
|
||
apiKey: ConstConfig.amapApiKeys,
|
||
mapType: MapType.navi,
|
||
scaleEnabled: false,
|
||
myLocationStyleOptions: MyLocationStyleOptions(
|
||
true,
|
||
circleFillColor: Colors.lightBlue,
|
||
circleStrokeColor: Colors.blue,
|
||
circleStrokeWidth: 1,
|
||
),
|
||
onMapCreated: (AMapController controller) {
|
||
setState(() {
|
||
_mapController = controller;
|
||
getApprovalNumber();
|
||
});
|
||
_moveCamera(_locationResult);
|
||
},
|
||
);
|
||
return Expanded(
|
||
child: Stack(
|
||
children: [
|
||
Container(
|
||
margin: const EdgeInsets.only(top: 10, bottom: 10),
|
||
decoration: const BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.all(Radius.circular(5))),
|
||
child: map,
|
||
),
|
||
Positioned(
|
||
bottom: 20,
|
||
right: 20,
|
||
child: Image.asset(
|
||
"images/3.0x/current_location.png",
|
||
width: 30,
|
||
height: 30,
|
||
),
|
||
)
|
||
],
|
||
));
|
||
}
|
||
|
||
void _moveCamera(Map<String, Object> result) {
|
||
double lat = double.parse(result['latitude'] as String);
|
||
double lng = double.parse(result['longitude'] as String);
|
||
if (_mapController != null) {
|
||
_mapController!.moveCamera(CameraUpdate.newCameraPosition(
|
||
CameraPosition(target: LatLng(lat, lng),zoom: 18)));
|
||
}
|
||
|
||
}
|
||
|
||
///获取审图号
|
||
void getApprovalNumber() async {
|
||
//普通地图审图号
|
||
String? mapContentApprovalNumber =
|
||
await _mapController?.getMapContentApprovalNumber();
|
||
//卫星地图审图号
|
||
String? satelliteImageApprovalNumber =
|
||
await _mapController?.getSatelliteImageApprovalNumber();
|
||
print('地图审图号(普通地图): $mapContentApprovalNumber');
|
||
print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
|
||
}
|
||
|
||
void requestPermission() async {
|
||
// 申请权限
|
||
bool hasLocationPermission = await requestLocationPermission();
|
||
if (hasLocationPermission) {
|
||
print("定位权限申请通过");
|
||
} else {
|
||
print("定位权限申请不通过");
|
||
}
|
||
}
|
||
|
||
/// 申请定位权限
|
||
/// 授予定位权限返回true, 否则返回false
|
||
Future<bool> requestLocationPermission() async {
|
||
//获取当前的权限
|
||
var status = await Permission.locationAlways.status;
|
||
if (status == PermissionStatus.granted) {
|
||
//已经授权
|
||
return true;
|
||
} else {
|
||
//未授权则发起一次申请
|
||
status = await Permission.locationAlways.request();
|
||
if (status == PermissionStatus.granted) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
///获取iOS native的accuracyAuthorization类型
|
||
void requestAccuracyAuthorization() async {
|
||
AMapAccuracyAuthorization currentAccuracyAuthorization =
|
||
await _locationPlugin.getSystemAccuracyAuthorization();
|
||
if (currentAccuracyAuthorization ==
|
||
AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
|
||
print("精确定位类型");
|
||
} else if (currentAccuracyAuthorization ==
|
||
AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
|
||
print("模糊定位类型");
|
||
} else {
|
||
print("未知定位类型");
|
||
}
|
||
}
|
||
}
|