autosos_flutter/lib/pages/home/widgets/map_widget.dart

208 lines
7.0 KiB
Dart
Raw Normal View History

2024-03-16 15:52:12 +08:00
import 'dart:async';
import 'dart:io';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
2024-03-16 14:15:04 +08:00
import 'package:amap_flutter_map/amap_flutter_map.dart';
import 'package:autosos_flutter/const_config.dart';
import 'package:flutter/material.dart';
2024-03-16 15:52:12 +08:00
import 'package:permission_handler/permission_handler.dart';
2024-03-16 18:11:34 +08:00
import 'package:amap_flutter_base/amap_flutter_base.dart';
2024-03-16 14:15:04 +08:00
class MapWidget extends StatefulWidget {
const MapWidget({super.key});
@override
State<MapWidget> createState() => _MapWidgetState();
}
class _MapWidgetState extends State<MapWidget> {
2024-03-25 22:12:38 +08:00
AMapController? _mapController;
2024-03-16 18:11:34 +08:00
Map<String, Object> _locationResult = {};
late StreamSubscription<Map<String, Object>> _locationListener;
final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
@override
void dispose() {
super.dispose();
_locationListener.cancel();
_locationPlugin.destroy();
}
2024-03-16 15:52:12 +08:00
@override
void initState() {
super.initState();
2024-03-16 18:11:34 +08:00
2024-03-16 15:52:12 +08:00
/// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看如果未包含或者没有弹窗展示高德定位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
2024-03-16 18:11:34 +08:00
AMapFlutterLocation.setApiKey(ConstConfig.androidKey, ConstConfig.iosKey);
2024-03-16 15:52:12 +08:00
///iOS 获取native精度类型
if (Platform.isIOS) {
requestAccuracyAuthorization();
}
2024-03-25 22:12:38 +08:00
var option = AMapLocationOption();
_locationPlugin.setLocationOption(option);
2024-03-16 18:11:34 +08:00
2024-03-16 15:52:12 +08:00
///注册定位结果监听
_locationListener = _locationPlugin
.onLocationChanged()
.listen((Map<String, Object> result) {
setState(() {
_locationResult = result;
});
2024-03-16 18:11:34 +08:00
print("location=$_locationResult");
2024-03-16 15:52:12 +08:00
});
2024-03-16 18:11:34 +08:00
_locationPlugin.startLocation();
2024-03-25 22:12:38 +08:00
WidgetsBinding.instance.addPostFrameCallback((_) {
// 在页面渲染完成后执行代码
// 例如,你可以在此处执行需要在页面加载完成后执行的操作
});
2024-03-16 18:11:34 +08:00
}
2024-03-16 15:52:12 +08:00
2024-03-16 14:15:04 +08:00
@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();
});
2024-03-25 22:12:38 +08:00
_moveCamera(_locationResult);
2024-03-16 14:15:04 +08:00
},
);
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,
),
)
],
));
}
2024-03-25 22:12:38 +08:00
void _moveCamera(Map<String, Object> result) {
2024-03-16 18:11:34 +08:00
double lat = double.parse(result['latitude'] as String);
double lng = double.parse(result['longitude'] as String);
2024-03-25 22:12:38 +08:00
if (_mapController != null) {
_mapController!.moveCamera(CameraUpdate.newCameraPosition(
CameraPosition(target: LatLng(lat, lng),zoom: 18)));
}
2024-03-16 18:11:34 +08:00
}
2024-03-16 15:52:12 +08:00
2024-03-16 14:15:04 +08:00
///获取审图号
void getApprovalNumber() async {
//普通地图审图号
String? mapContentApprovalNumber =
2024-03-25 22:12:38 +08:00
await _mapController?.getMapContentApprovalNumber();
2024-03-16 14:15:04 +08:00
//卫星地图审图号
String? satelliteImageApprovalNumber =
2024-03-25 22:12:38 +08:00
await _mapController?.getSatelliteImageApprovalNumber();
2024-03-16 14:15:04 +08:00
print('地图审图号(普通地图): $mapContentApprovalNumber');
print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
}
2024-03-16 15:52:12 +08:00
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 =
2024-03-16 18:11:34 +08:00
await _locationPlugin.getSystemAccuracyAuthorization();
2024-03-16 15:52:12 +08:00
if (currentAccuracyAuthorization ==
AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
print("精确定位类型");
} else if (currentAccuracyAuthorization ==
AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
print("模糊定位类型");
} else {
print("未知定位类型");
}
}
2024-03-16 14:15:04 +08:00
}