320 lines
11 KiB
Dart
320 lines
11 KiB
Dart
|
|
|
|||
|
|
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:flutter_screenutil/flutter_screenutil.dart';
|
|||
|
|
import 'package:permission_handler/permission_handler.dart';
|
|||
|
|
import 'package:amap_flutter_map/amap_flutter_map.dart';
|
|||
|
|
import 'package:amap_flutter_base/amap_flutter_base.dart';
|
|||
|
|
|
|||
|
|
import '../../../app_settings/app_colors.dart';
|
|||
|
|
import '../../../main.dart';
|
|||
|
|
|
|||
|
|
class LockAddressGaoDePage extends StatefulWidget {
|
|||
|
|
const LockAddressGaoDePage({Key? key}) : super(key: key);
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
State<LockAddressGaoDePage> createState() => _LockAddressGaoDePageState();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>{
|
|||
|
|
// 高德地图
|
|||
|
|
Map<String, Object>? _locationResult;
|
|||
|
|
StreamSubscription<Map<String, Object>>? _locationListener;
|
|||
|
|
final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
|
|||
|
|
late AMapController _mapController;
|
|||
|
|
|
|||
|
|
static const CameraPosition _kInitialPosition = CameraPosition(
|
|||
|
|
target: LatLng(113.919112, 22.653728),
|
|||
|
|
zoom: 10.0,
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
List<Widget> get _approvalNumberWidget => <Widget>[];
|
|||
|
|
|
|||
|
|
@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;
|
|||
|
|
if (_locationResult != null) {
|
|||
|
|
_locationResult?.forEach((key, value) {
|
|||
|
|
print("key:$key value:$value");
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
_startLocation();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
Widget build(BuildContext context) {
|
|||
|
|
///使用默认属性创建一个地图
|
|||
|
|
final AMapWidget map = AMapWidget(
|
|||
|
|
apiKey: const AMapApiKey(androidKey: '900f72eeee0f21e435cebb0ef155582a', iosKey: '4dfdec97b7bf0b8c13e94777103015a9'),
|
|||
|
|
onMapCreated: onMapCreated,
|
|||
|
|
// initialCameraPosition: _kInitialPosition
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return Stack(
|
|||
|
|
children: [
|
|||
|
|
Container(
|
|||
|
|
height: MediaQuery.of(context).size.height,
|
|||
|
|
width: MediaQuery.of(context).size.width,
|
|||
|
|
child: map,
|
|||
|
|
),
|
|||
|
|
Positioned(
|
|||
|
|
left: 10.w, bottom: 30.h,
|
|||
|
|
child: Container(
|
|||
|
|
alignment: Alignment.centerLeft,
|
|||
|
|
child: Column(
|
|||
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|||
|
|
children: _approvalNumberWidget),
|
|||
|
|
)
|
|||
|
|
),
|
|||
|
|
Positioned(
|
|||
|
|
left: 20.w, right: 20.w, bottom: 100.h,
|
|||
|
|
child: Container(
|
|||
|
|
// height: h(106),
|
|||
|
|
decoration: BoxDecoration(
|
|||
|
|
color: AppColors.mainColor,
|
|||
|
|
borderRadius: BorderRadius.circular(15.w),
|
|||
|
|
),
|
|||
|
|
child:Column(
|
|||
|
|
children: [
|
|||
|
|
Container(
|
|||
|
|
// height: h(53),
|
|||
|
|
padding: EdgeInsets.only(top: 15.h, bottom: 15, left:15.w, right: 15.w),
|
|||
|
|
child: Row(
|
|||
|
|
children: [
|
|||
|
|
Image.asset('images/main/icon_addUserShowAddress.png', width: 30.w, height: 30.w),
|
|||
|
|
SizedBox(width: 10.w),
|
|||
|
|
Expanded(
|
|||
|
|
child: Text("广东省深圳市宏发科技园", style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500, overflow: TextOverflow.clip))
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
Container(height: 1.h, color: const Color(0xFF021732),),
|
|||
|
|
Container(
|
|||
|
|
// height: h(52),
|
|||
|
|
padding: EdgeInsets.only(top: 15.h, bottom: 15, left:15.w, right: 15.w),
|
|||
|
|
child: Row(
|
|||
|
|
children: [
|
|||
|
|
Image.asset('images/main/icon_addUserAddressShowTime.png', width: 30.w, height: 30.w),
|
|||
|
|
SizedBox(width: 10.w,),
|
|||
|
|
Expanded(
|
|||
|
|
child: Text("2023.8.22 15.14", style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),)
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
),
|
|||
|
|
],
|
|||
|
|
)
|
|||
|
|
),),
|
|||
|
|
],
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void onMapCreated(AMapController controller) {
|
|||
|
|
setState(() {
|
|||
|
|
_mapController = controller;
|
|||
|
|
getApprovalNumber();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 获取审图号
|
|||
|
|
void getApprovalNumber() async {
|
|||
|
|
//普通地图审图号
|
|||
|
|
String? mapContentApprovalNumber =
|
|||
|
|
await _mapController.getMapContentApprovalNumber();
|
|||
|
|
//卫星地图审图号
|
|||
|
|
String? satelliteImageApprovalNumber =
|
|||
|
|
await _mapController.getSatelliteImageApprovalNumber();
|
|||
|
|
setState(() {
|
|||
|
|
if (null != mapContentApprovalNumber) {
|
|||
|
|
_approvalNumberWidget.add(Text(mapContentApprovalNumber));
|
|||
|
|
}
|
|||
|
|
if (null != satelliteImageApprovalNumber) {
|
|||
|
|
_approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
print('地图审图号(普通地图): $mapContentApprovalNumber');
|
|||
|
|
print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
///设置定位参数
|
|||
|
|
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();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
///获取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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// @override
|
|||
|
|
// void dispose() {
|
|||
|
|
// super.dispose();
|
|||
|
|
//
|
|||
|
|
// _stopLocation();
|
|||
|
|
//
|
|||
|
|
// ///移除定位监听
|
|||
|
|
// if (null != _locationListener) {
|
|||
|
|
// _locationListener?.cancel();
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// ///销毁定位
|
|||
|
|
// _locationPlugin.destroy();
|
|||
|
|
//
|
|||
|
|
// print("高德地图定位销毁了");
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
@override
|
|||
|
|
void dispose() {
|
|||
|
|
super.dispose();
|
|||
|
|
|
|||
|
|
_stopLocation();
|
|||
|
|
|
|||
|
|
///移除定位监听
|
|||
|
|
if (null != _locationListener) {
|
|||
|
|
_locationListener?.cancel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
///销毁定位
|
|||
|
|
_locationPlugin.destroy();
|
|||
|
|
|
|||
|
|
print("地图界面销毁了");
|
|||
|
|
}
|
|||
|
|
}
|