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.
 
 
 
 
 
 

329 lines
12 KiB

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:geolocator/geolocator.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 getInstance() {
if (_instance == null) {
_instance = LocationInstance._internal();
}
return _instance!;
}
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) {
bool isNext = true;
Future.delayed(Duration(seconds: 5), () {
if (isNext) {
EasyLoading.dismiss();
}
});
Position locationData = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.medium,
timeLimit: const Duration(seconds: 30),
forceAndroidLocationManager: true,
);
isNext = false;
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,
);
},
);
}
///计算距离(当前位置到店位置直线距离)
static Future<String> calculateDistance(
Position bmfCoordinate, Position myLatLng,
{bool isMi = false}) async {
double mi = Geolocator.distanceBetween(
bmfCoordinate.latitude,
bmfCoordinate.longitude,
myLatLng.latitude,
myLatLng.longitude,
);
NumberFormat numberFormat = NumberFormat("#.#");
return "${numberFormat.format(mi / (isMi ? 1 : 1000))}";
}
// ///坐标系转换(高德转百度)
// static Future<Latlng> coordConvert(Latlng latLng) async {
// return BMFCalculateUtils.coordConvert(
// coordinate: latLng,
// fromType: BMF_COORD_TYPE.COMMON,
// toType: BMF_COORD_TYPE.BD09LL);
// }
Future<Address?>? getAddress(double lat, double lang) async {
var result = await ApiService(Dio()).geocodeRegeo("$lat", "$lang");
print("address_result: $result");
if (result["status"] == "1" &&
result["regeocode"] != null &&
result["regeocode"]["addressComponent"] != null) {
Address address = Address.fromJson({
"address": result["regeocode"]["formatted_address"],
"area": result['regeocode']["addressComponent"]["district"],
"city": result['regeocode']["addressComponent"]["city"],
"latitude": lat,
"longitude": lang,
"province": result['regeocode']["addressComponent"]["province"],
});
return address;
}
return null;
}
}