377 lines
13 KiB
Dart
Executable File
377 lines
13 KiB
Dart
Executable File
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:amap_flutter_base/amap_flutter_base.dart';
|
|
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:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:star_lock/mine/addLock/lockAddress/gaode/lockAddressGaoDe_state.dart';
|
|
import 'package:star_lock/widget/permission/permission_dialog.dart';
|
|
|
|
import '../../../../appRouters.dart';
|
|
import '../../../../app_settings/app_colors.dart';
|
|
import '../../../../blue/blue_manage.dart';
|
|
import '../../../../flavors.dart';
|
|
import '../../../../tools/appRouteObserver.dart';
|
|
import '../../../../tools/titleAppBar.dart';
|
|
import 'lockAddressGaoDe_logic.dart';
|
|
|
|
class LockAddressGaoDePage extends StatefulWidget {
|
|
const LockAddressGaoDePage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<LockAddressGaoDePage> createState() => _LockAddressGaoDePageState();
|
|
}
|
|
|
|
class _LockAddressGaoDePageState extends State<LockAddressGaoDePage>
|
|
with RouteAware {
|
|
final LockAddressGaoDeLogic logic = Get.put(LockAddressGaoDeLogic());
|
|
final LockAddressGaoDeState state = Get.find<LockAddressGaoDeLogic>().state;
|
|
|
|
// 高德地图
|
|
static AMapApiKey amapApiKeys =
|
|
AMapApiKey(iosKey: F.aMapKey.iosKey, androidKey: F.aMapKey.androidKey);
|
|
|
|
AMapController? mapController;
|
|
AMapFlutterLocation location = AMapFlutterLocation();
|
|
|
|
PermissionStatus? permissionStatus;
|
|
Map<String, Object>? addressInfo;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
AMapFlutterLocation.updatePrivacyAgree(true);
|
|
AMapFlutterLocation.updatePrivacyShow(true, true);
|
|
AMapFlutterLocation.setApiKey(F.aMapKey.androidKey, F.aMapKey.iosKey);
|
|
requestPermission();
|
|
}
|
|
|
|
// Future<void> requestPermission() async {
|
|
// final status = await Permission.location.request();
|
|
// AppLog.log("Permission.location.request()=status:$status");
|
|
// permissionStatus = status;
|
|
// if(Platform.isIOS){
|
|
// _setLocationOption();
|
|
// requestIOSLocation();
|
|
// }
|
|
// switch (status) {
|
|
// case PermissionStatus.denied:
|
|
// // AppLog.log("拒绝");
|
|
// break;
|
|
// case PermissionStatus.granted:
|
|
// if(Platform.isIOS){
|
|
// // _setLocationOption();
|
|
// // requestIOSLocation();
|
|
// }else{
|
|
// requestAndroidLocation();
|
|
// location.startLocation();
|
|
// }
|
|
// break;
|
|
// case PermissionStatus.limited:
|
|
// // AppLog.log("限制");
|
|
// break;
|
|
// case PermissionStatus.permanentlyDenied:
|
|
// // AppLog.log("永久的否认");
|
|
// break;
|
|
// case PermissionStatus.provisional:
|
|
// // AppLog.log("临时");
|
|
// break;
|
|
// default:
|
|
// // AppLog.log("其他状态");
|
|
// // requestLocation();
|
|
// break;
|
|
// }
|
|
// }
|
|
|
|
Future<void> requestPermission() async {
|
|
final bool status = await PermissionDialog.request(Permission.location);
|
|
if(Platform.isIOS){
|
|
_setLocationOption();
|
|
requestIOSLocation();
|
|
}
|
|
|
|
if (!Platform.isIOS || status) {
|
|
requestAndroidLocation();
|
|
location.startLocation();
|
|
}
|
|
}
|
|
|
|
Future<void> requestAndroidLocation() async {
|
|
location.onLocationChanged().listen((Map<String, Object> event) {
|
|
if (event.isNotEmpty) {
|
|
setState(() {
|
|
addressInfo = event;
|
|
});
|
|
location.stopLocation();
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> requestIOSLocation() async {
|
|
location = AMapFlutterLocation()
|
|
..setLocationOption(AMapLocationOption())
|
|
..onLocationChanged().listen((Map<String, Object> event) {
|
|
// AppLog.log("listenLocationChanged$event");
|
|
// EasyLoading.dismiss();
|
|
if (event.isNotEmpty) {
|
|
setState(() {
|
|
addressInfo = event;
|
|
});
|
|
// location.stopLocation();
|
|
}
|
|
})
|
|
..startLocation();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.white,
|
|
appBar: TitleAppBar(
|
|
barTitle: '锁地址'.tr,
|
|
haveBack: true,
|
|
backgroundColor: AppColors.mainColor,
|
|
),
|
|
body: ListView(
|
|
children: <Widget>[
|
|
Container(
|
|
margin: EdgeInsets.only(left: 25.w, top: 40.h, bottom: 40.w),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: <Widget>[
|
|
Text('地理位置'.tr, style: TextStyle(fontSize: 50.sp)),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(
|
|
child: (addressInfo != null && addressInfo!.containsKey('latitude'))
|
|
? Column(
|
|
children: <Widget>[
|
|
SizedBox(
|
|
height: 1.sw / 5 * 4,
|
|
width: 1.sw,
|
|
child: AMapWidget(
|
|
apiKey: amapApiKeys,
|
|
// 初始化地图中心
|
|
initialCameraPosition: CameraPosition(
|
|
target: LatLng(
|
|
double.parse(
|
|
addressInfo!['latitude'].toString()),
|
|
double.parse(
|
|
addressInfo!['longitude'].toString())),
|
|
zoom: 10.0,
|
|
),
|
|
//定位小蓝点
|
|
myLocationStyleOptions: MyLocationStyleOptions(
|
|
true,
|
|
),
|
|
// 普通地图normal,卫星地图satellite,夜间视图night,导航视图 navi,公交视图bus,
|
|
mapType: MapType.normal,
|
|
// 缩放级别范围
|
|
minMaxZoomPreference:
|
|
const MinMaxZoomPreference(3, 20),
|
|
// 隐私政策包含高德 必须填写
|
|
privacyStatement: const AMapPrivacyStatement(
|
|
hasAgree: true, hasContains: true, hasShow: true),
|
|
// 地图创建成功时返回AMapController
|
|
onMapCreated: (AMapController controller) {
|
|
mapController = controller;
|
|
},
|
|
),
|
|
),
|
|
Container(
|
|
// color: Colors.red,
|
|
margin:
|
|
EdgeInsets.only(left: 25.w, top: 20.h, right: 25.w),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: <Widget>[
|
|
Flexible(
|
|
child: Text('检查以确保以下地址是正确的'.tr,
|
|
style: TextStyle(fontSize: 24.sp))),
|
|
],
|
|
),
|
|
),
|
|
// SizedBox(height: 20.h),
|
|
Container(
|
|
// color: Colors.red,
|
|
// height: 45.h,
|
|
margin: EdgeInsets.only(
|
|
left: 25.w, top: 20.h, right: 25.w),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Row(
|
|
children: <Widget>[
|
|
Expanded(
|
|
child: Text(
|
|
addressInfo!['address'].toString() ??
|
|
'',
|
|
style: const TextStyle(
|
|
color: Colors.grey,
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.w500,
|
|
overflow: TextOverflow.clip))),
|
|
],
|
|
),
|
|
SizedBox(height: 5.h),
|
|
Container(
|
|
height: 1.h,
|
|
color: AppColors.mainColor,
|
|
),
|
|
],
|
|
)),
|
|
],
|
|
)
|
|
: SizedBox(
|
|
height: 1.sw / 5 * 4 + 65.h * 2,
|
|
child: Center(child: Text('地图加载中,请稍候。。。'.tr))),
|
|
),
|
|
SizedBox(height: 200.h),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
children: <Widget>[
|
|
TextButton(
|
|
child: Text(
|
|
'跳过'.tr,
|
|
style: TextStyle(color: Colors.black, fontSize: 24.sp),
|
|
),
|
|
onPressed: () {
|
|
Get.toNamed(Routers.addLockSelectCountryPage, arguments: <String, Object>{
|
|
'addressInfo': {},
|
|
'pwdTimestamp': state.pwdTimestamp.value,
|
|
'lockInfo': state.lockInfo,
|
|
'featureValue': state.featureValue,
|
|
'featureSettingValue': state.featureSettingValue,
|
|
'featureSettingParams': state.featureSettingParams,
|
|
});
|
|
},
|
|
),
|
|
TextButton(
|
|
child: Text(
|
|
'下一步'.tr,
|
|
style: TextStyle(color: Colors.black, fontSize: 24.sp),
|
|
),
|
|
onPressed: () {
|
|
if (addressInfo!.isEmpty) {
|
|
logic.showToast('还未获取到位置信息哦,请耐心等待一下!'.tr);
|
|
return;
|
|
}
|
|
Get.toNamed(Routers.saveLockPage, arguments: <String, Object?>{
|
|
'addressInfo': addressInfo,
|
|
'pwdTimestamp': state.pwdTimestamp.value,
|
|
'lockInfo': state.lockInfo,
|
|
'featureValue': state.featureValue,
|
|
'featureSettingValue': state.featureSettingValue,
|
|
'featureSettingParams': state.featureSettingParams,
|
|
'isFromMap': 1,
|
|
});
|
|
// Navigator.pushNamed(context, Routers.saveLockPage);
|
|
},
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
///设置定位参数
|
|
void _setLocationOption() {
|
|
AMapLocationOption locationOption = AMapLocationOption();
|
|
|
|
///是否单次定位
|
|
locationOption.onceLocation = true;
|
|
|
|
///是否需要返回逆地理信息
|
|
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.Battery_Saving;
|
|
|
|
///设置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.BestForNavigation;
|
|
|
|
///设置iOS端是否允许系统暂停定位
|
|
locationOption.pausesLocationUpdatesAutomatically = false;
|
|
|
|
///将定位参数设置给定位插件
|
|
location.setLocationOption(locationOption);
|
|
}
|
|
|
|
@override
|
|
void didChangeDependencies() {
|
|
super.didChangeDependencies();
|
|
|
|
/// 路由订阅
|
|
AppRouteObserver().routeObserver.subscribe(this, ModalRoute.of(context)!);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
AppRouteObserver().routeObserver.unsubscribe(this);
|
|
super.dispose();
|
|
|
|
BlueManage().disconnect();
|
|
|
|
location.stopLocation();
|
|
location.destroy();
|
|
}
|
|
|
|
/// 从上级界面进入 当前界面即将出现
|
|
@override
|
|
void didPush() {
|
|
super.didPush();
|
|
}
|
|
|
|
/// 返回上一个界面 当前界面即将消失
|
|
@override
|
|
void didPop() {
|
|
super.didPop();
|
|
}
|
|
|
|
/// 从下级返回 当前界面即将出现
|
|
@override
|
|
void didPopNext() {
|
|
super.didPopNext();
|
|
}
|
|
|
|
/// 进入下级界面 当前界面即将消失
|
|
@override
|
|
void didPushNext() {
|
|
super.didPushNext();
|
|
|
|
location.stopLocation();
|
|
location.destroy();
|
|
}
|
|
}
|