You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

308 lines
11 KiB

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:geolocator/geolocator.dart';
import 'package:huixiang/data/a_map_result.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/request_permission.dart';
import 'package:intl/intl.dart';
import 'package:permission_handler/permission_handler.dart' as PH;
import '../data/address.dart';
import 'font_weight.dart';
class LocationInstance {
static LocationInstance? _instance;
LocationInstance._internal();
static LocationInstance get instance => _instance ??= LocationInstance._internal();
Future<bool> startLocation(context, Function(Position? locationData) locationCallback) async {
LocationPermission permissionStatus = await Geolocator.checkPermission();
if (permissionStatus == LocationPermission.denied) {
permissionStatus = await Geolocator.requestPermission();
}
if (permissionStatus == LocationPermission.denied) {
showTipsAlertDialog(context);
return false;
}
if (permissionStatus == LocationPermission.deniedForever) {
showTipsAlertDialog(context);
return false;
}
if (permissionStatus == LocationPermission.whileInUse || permissionStatus == LocationPermission.always) {
Position locationData = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.medium,
timeLimit: const Duration(seconds: 30),
forceAndroidLocationManager: true,
);
locationCallback.call(locationData);
}
return true;
}
void stopLocation() {}
enableLocation(context) {
showCupertinoDialog(
context: context,
builder: (context) {
return RequestPermission(
"assets/image/icon_permission_location_bg.webp",
S.of(context).nindingweigongnengweikaiqi,
S.of(context).weilexiangnintuijianfujindemendianxinxi,
S.of(context).dakaidingwei,
(result) async {
if (result) {
// final AndroidIntent intent = AndroidIntent(
// action: 'action_location_source_settings',
// package: "com.zsw.huixiang",
// );
// await intent.launch();
Geolocator.openLocationSettings();
// startLocation();
}
},
heightRatioWithWidth: 0.82,
);
},
);
}
requestDialog(context, Function(Position? result) locationCallback) {
showCupertinoDialog(
context: context,
builder: (context) {
return RequestPermission(
"assets/image/icon_permission_location_bg.webp",
S.of(context).nindingweiquanxianweiyunxu,
S.of(context).weilexiangnintuijianfujindemendianxinxi,
S.of(context).kaiqiquanxian,
(result) async {
if (result) {
await PH.openAppSettings();
if ((await Geolocator.checkPermission()) ==
LocationPermission.whileInUse ||
(await Geolocator.checkPermission()) ==
LocationPermission.always) {
startLocation(context, locationCallback);
}
}
},
heightRatioWithWidth: 0.82,
);
},
);
}
///定位权限说明弹窗
showTipsAlertDialog(context) async {
//显示对话框
showDialog(
context: context,
barrierDismissible: false,
barrierColor: null,
builder: (BuildContext context) {
return Column(
children: [
Container(
width: double.infinity,
padding: EdgeInsets.all(15),
margin: EdgeInsets.all(15),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
Icons.location_on_outlined,
color: Colors.black,
size: 22,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
// "访问精确地理位置信息权限说明",
"位置权限使用说明",
style: TextStyle(
fontSize: 18.sp,
fontWeight: MyFontWeight.regular,
color: Colors.black,
),
),
SizedBox(
height: 3.h,
),
Text(
// "为了向您推荐附近的门店信息,推荐您在使用期间让我们使用位置信息,不授权该权限不影响app正常使用。",
"为了向您推荐附近的门店信息,推荐您在使用期间让我们使用位置信息",
style: TextStyle(
fontSize: 13.sp,
fontWeight: MyFontWeight.regular,
color: Colors.black,
),
),
],
),
),
],
),
),
],
mainAxisSize: MainAxisSize.min,
);
},
);
Geolocator.requestPermission();
Navigator.of(context).pop();
}
///定位权限说明和申请弹窗
showAlertDialog(context) {
//显示对话框
showDialog(
context: context,
barrierDismissible: true,
barrierColor: null,
builder: (BuildContext context) {
return Column(
children: [
Container(
width: double.infinity,
padding: EdgeInsets.all(15),
margin: EdgeInsets.all(15),
decoration: new BoxDecoration(
color: Colors.black.withOpacity(0.6),
borderRadius: BorderRadius.circular(10),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
// "访问精确地理位置信息权限说明",
"定位服务未开启",
style: TextStyle(
fontSize: 18.sp,
fontWeight: MyFontWeight.regular,
color: Colors.white,
),
),
SizedBox(
height: 3.h,
),
Text(
// "为了向您推荐附近的门店信息,推荐您在使用期间让我们使用位置信息,不授权该权限不影响app正常使用。",
"开启后才能提供更详细的定位服务哦!",
style: TextStyle(
fontSize: 13.sp,
fontWeight: MyFontWeight.regular,
color: Colors.white,
),
),
],
),
),
GestureDetector(
child: Container(
child: Text(
"去开启",
style: TextStyle(
fontSize: 15.sp,
fontWeight: MyFontWeight.regular,
color: Colors.white,
),
),
margin: EdgeInsets.symmetric(
horizontal: 15.w, vertical: 25.h),
padding:
EdgeInsets.symmetric(vertical: 2.h, horizontal: 10.w),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(100),
),
),
onTap: () async {
await PH.openAppSettings();
if ((await Geolocator.checkPermission()) ==
LocationPermission.whileInUse ||
(await Geolocator.checkPermission()) ==
LocationPermission.always)
Navigator.of(context).pop();
},
behavior: HitTestBehavior.opaque,
),
GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
child: Icon(
Icons.close,
color: Colors.white.withOpacity(0.8),
size: 12,
),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.8),
borderRadius: BorderRadius.circular(100),
),
padding: EdgeInsets.all(5),
),
onTap: () {
Navigator.of(context).pop();
},
)
],
),
)
],
mainAxisSize: MainAxisSize.min,
);
},
);
}
///计算距离(当前位置到店位置直线距离)
String calculateDistance(Position bmfCoordinate, Position myLatLng, {bool isMi = false}) {
double mi = Geolocator.distanceBetween(
bmfCoordinate.latitude,
bmfCoordinate.longitude,
myLatLng.latitude,
myLatLng.longitude,
);
NumberFormat numberFormat = NumberFormat("#.#");
return "${numberFormat.format(mi / (isMi ? 1 : 1000))}";
}
Future<Address?>? getAddress(double lat, double lang) async {
var result = await ApiService(Dio(), showLoading: false).geocodeRegeo("$lat", "$lang");
print("address_result: $result");
try {
AMapResult aMapResult = AMapResult.fromJson(result);
Address address = Address.fromJson({
"address": aMapResult.regeocode?.formattedAddress,
"area": aMapResult.regeocode?.addressComponent?.district,
"city": aMapResult.regeocode?.addressComponent?.city,
"latitude": lat,
"longitude": lang,
"province": aMapResult.regeocode?.addressComponent?.province,
});
return address;
} catch (e) {
print("address_result_error: $e");
}
return null;
}
}