387 lines
14 KiB
Dart
Executable File
387 lines
14 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/widgets.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 '../../../../flavors.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;
|
||
AMapController? mapController;
|
||
Map<String, Object>? _addressInfo;
|
||
|
||
late StreamSubscription<Map<String, Object>> _locationListener;
|
||
|
||
AMapFlutterLocation _amapLocationPlugin = 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);
|
||
AMapFlutterLocation.setApiKey(F.aMapKey.androidKey, F.aMapKey.iosKey);
|
||
|
||
/// 动态申请定位权限
|
||
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(
|
||
// "anroid ApiKey", "ios ApiKey");
|
||
|
||
///iOS 获取native精度类型
|
||
if (Platform.isIOS) {
|
||
requestAccuracyAuthorization();
|
||
}
|
||
|
||
///注册定位结果监听
|
||
_locationListener = _amapLocationPlugin
|
||
.onLocationChanged()
|
||
.listen((Map<String, Object> result) {
|
||
setState(() {
|
||
_addressInfo = result;
|
||
});
|
||
});
|
||
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
_startLocation();
|
||
});
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
super.dispose();
|
||
|
||
///移除定位监听
|
||
_locationListener.cancel();
|
||
|
||
///销毁定位
|
||
_amapLocationPlugin.destroy();
|
||
}
|
||
|
||
///设置定位参数
|
||
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;
|
||
|
||
///将定位参数设置给定位插件
|
||
_amapLocationPlugin.setLocationOption(locationOption);
|
||
}
|
||
|
||
///开始定位
|
||
void _startLocation() {
|
||
///开始定位之前设置定位参数
|
||
_setLocationOption();
|
||
_amapLocationPlugin.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, right: 25.w, top: 40.h, bottom: 40.w),
|
||
child: Center(
|
||
child: Text(
|
||
'地理位置'.tr,
|
||
textAlign: TextAlign.center,
|
||
style: TextStyle(fontSize: 50.sp),
|
||
softWrap: true,
|
||
overflow: TextOverflow.visible,
|
||
),
|
||
),
|
||
),
|
||
SizedBox(
|
||
child: (_addressInfo != null &&
|
||
_addressInfo!.containsKey('latitude'))
|
||
? Column(
|
||
children: <Widget>[
|
||
SizedBox(
|
||
height: 1.sw / 5 * 4,
|
||
width: 1.sw,
|
||
child: AMapWidget(
|
||
apiKey: AMapApiKey(
|
||
iosKey: F.aMapKey.iosKey,
|
||
androidKey: F.aMapKey.androidKey),
|
||
// 初始化地图中心
|
||
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;
|
||
},
|
||
onLocationChanged: (AMapLocation location) {
|
||
print("onLocationChanged ${location}");
|
||
},
|
||
),
|
||
),
|
||
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))),
|
||
),
|
||
Container(
|
||
constraints: BoxConstraints(maxHeight: 150.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);
|
||
},
|
||
),
|
||
],
|
||
)
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
///获取iOS native的accuracyAuthorization类型
|
||
void requestAccuracyAuthorization() async {
|
||
AMapAccuracyAuthorization currentAccuracyAuthorization =
|
||
await _amapLocationPlugin.getSystemAccuracyAuthorization();
|
||
if (currentAccuracyAuthorization ==
|
||
AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
|
||
print("精确定位类型");
|
||
} else if (currentAccuracyAuthorization ==
|
||
AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
|
||
print("模糊定位类型");
|
||
} else {
|
||
print("未知定位类型");
|
||
}
|
||
}
|
||
|
||
/// 动态申请定位权限
|
||
void requestPermission() async {
|
||
// 申请权限
|
||
final bool hasLocationPermission =
|
||
await PermissionDialog.request(Permission.location);
|
||
if (hasLocationPermission) {
|
||
print("定位权限申请通过");
|
||
} else {
|
||
print("定位权限申请不通过");
|
||
}
|
||
}
|
||
|
||
/// 从上级界面进入 当前界面即将出现
|
||
@override
|
||
void didPush() {
|
||
super.didPush();
|
||
}
|
||
|
||
/// 返回上一个界面 当前界面即将消失
|
||
@override
|
||
void didPop() {
|
||
super.didPop();
|
||
}
|
||
|
||
/// 从下级返回 当前界面即将出现
|
||
@override
|
||
void didPopNext() {
|
||
super.didPopNext();
|
||
}
|
||
|
||
/// 进入下级界面 当前界面即将消失
|
||
@override
|
||
void didPushNext() {
|
||
super.didPushNext();
|
||
|
||
_amapLocationPlugin.stopLocation();
|
||
_amapLocationPlugin.destroy();
|
||
}
|
||
}
|