Flutter----实现定位+范围限制(距离目的地1000米才能打卡)

Flutter----实现定位+范围限制(距离⽬的地1000⽶才能打卡)余干二小
需求:
1.实现设备的定位
2.当前位置和⽬标位置的1000⽶范围内才能打卡
该页⾯就是简单的进去的时候就获取定位,如果定位获取到了就停⽌定位,并toast是否可以打卡的消息。扫描电镜与透射电镜
采⽤的定位的插件:
flutter_bmflocation: ^2.0.0-nullsafety.0
##为什么使⽤百度地图的插件?⽽不是其他的插件
采⽤的是百度地图的插件,这个星期尝试了三个插件,第⼀个最先使⽤的location插件,不需要申请啥开发者啥的直接可以⽤的,但是悲哀的是时不时会失灵的,怀疑是⽹络问题,回调死活进不去。第⼆个尝试的是⾼德地图的,为什么呢,搜索的时候⼤家都⽤⾼德的,所以我也去试验了⼀下,但是⾼德地图明
显很久没有维护了,现在flutter是空安全的,但是它明显是⽼的,不⽀持空安全,导致调试的时候⾮常⿇烦,虽然可以⽤,但是为了以后⽅便还是被pass。然后选择了百度,明显百度有在维护,有⽀持空安全和不⽀持空安全的版本,所以选择了它。
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:math';
import 'package:app_flutter/common/global.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bmflocation/bdmap_location_flutter_plugin.dart';
import 'package:flutter_bmflocation/flutter_baidu_location.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_android_option.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_ios_option.dart';
class ImageUploadRoute extends StatefulWidget {
ImageUploadRoute({Key? key, this.title}) : super(key: key);
final String? title;
@override
_ImageUploadState createState() => _ImageUploadState();
}
class _ImageUploadState extends State<ImageUploadRoute> {
//编辑⽂本
late TextEditingController _controller;
//定位相关
double lat1=0.0;//当前的维度
double lng1=0.0;//当前的经度
double lat2=0.0;//⽬的地的维度
double lng2=0.0;//⽬的地的经度
int limitMmeters=1000;//限制上传的距离,⼀公⾥范围内
late Map<String, Object>? _loationResult=null;
BaiduLocation? _baiduLocation;
822uu
late StreamSubscription<Map<String, Object>?> _locationListener;
LocationFlutterPlugin _locationPlugin = new LocationFlutterPlugin();
//初始化的时候打开定位相关
@override气缸耗气量计算
void initState() {
super.initState();
_controller = TextEditingController();
/// 动态申请定位权限
_questPermission();人口结构
/// 设置ios端ak, android端ak可以直接在清单⽂件中配置
LocationFlutterPlugin.setApiKey("jInwiO1AhcbkZyz0Z9ZL9fC88pThdGZP");
_locationListener = _ResultCallback().listen((Map<String, Object>? result) {      setState(() {
_loationResult = result;
print("longitude$result['longitude']");
try {
_baiduLocation = BaiduLocation.fromMap(result);
isInArea();
//          print(_baiduLocation);路易十四时代
} catch (e) {
print(e);
}
});
});
_startLocation();//开启位置监听
}
@override
void dispose() {
_controller.dispose();
super.dispose();
if (null != _locationListener) {
_locationListener.cancel();
}
}
/
// 设置android端和ios端定位参数
void _setLocOption() {
/// android 端设置定位参数
BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption();
androidOption.setCoorType("bd09ll"); // 设置返回的位置坐标系类型
androidOption.setIsNeedAltitude(true); // 设置是否需要返回海拔⾼度信息
androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息
androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息
androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述
androidOption.setOpenGps(true); // 设置是否需要使⽤gps
androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式
androidOption.setScanspan(1000); // 设置发起定位请求时间间隔
Map androidMap = Map();
/// ios 端设置定位参数
BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption();
iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
iosOption.setBMKLocationCoordinateType(
"BMKLocationCoordinateTypeBMK09LL"); // 设置返回的位置坐标系类型
iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应⽤位置类型
iosOption.setLocationTimeout(10); // 设置位置获取超时时间
iosOption.setDesiredAccuracy("kCLLocationAccuracyBest"); // 设置预期精度参数
iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间
iosOption.setDistanceFilter(100); // 设置定位最⼩更新距离
iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位
iosOption.setPauseLocUpdateAutomatically(true); //  定位是否会被系统⾃动暂停
Map iosMap = Map();
_locationPlugin.prepareLoc(androidMap, iosMap);
}
/// 启动定位
void _startLocation() {
if (null != _locationPlugin) {
if (null != _locationPlugin) {
_setLocOption();
_locationPlugin.startLocation();
}
}
/// 停⽌定位
void _stopLocation() {
if (null != _locationPlugin) {
_locationPlugin.stopLocation();
}
}
double  _rad(double d) {
return d * pi / 180.0;
}
double  _getDistance(double lat1, double lng1, double lat2, double lng2) {
/// 单位:⽶
/// def :地球半径
double def = 6378137.0;
double radLat1 = _rad(lat1);
double radLat2 = _rad(lat2);
double a = radLat1 - radLat2;
double b = _rad(lng1) - _rad(lng2);
double s = 2 * asin(sqrt(pow(sin(a / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2)));
return (s * def ).roundToDouble();
}
//是否在范围内?
void isInArea(){
lat1=_baiduLocation?.latitude??0;//如果没值那么0
lng1=_baiduLocation?.longitude??0;//如果没值那么0
double distance=_getDistance(lat1,lng1,lat2,lng2);
if(lat1!=0&&lng1!=0){//正确的获取到了坐标
if(limitMmeters>=distance){//在范围内允许
Global.showCenterToast("允许打卡");
_stopLocation();
}else{//在范围外
Global.showCenterToast("不在范围内,当前距离⽬标位置$distance⽶,打卡范围为$limitMmeters⽶");        _stopLocation();
}
}else{
Global.showCenterToast("位置获取中!");
}
}
//页⾯的控件布局
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("定位"),),
body:Stack(
children: [
Positioned(//占满屏幕
top: 0,
bottom: 0,
left: 0,
right: 0,
child: Column(
children: [
children: [
TextField(
maxLines: 10,
minLines: 3,
controller:_controller,
decoration:InputDecoration(                        ,                        fillColor:Colors.white ,
filled: true,
hintText: "签收情况",
),
),
],
)),
],
)
);
}
}

本文发布于:2024-09-21 02:31:57,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/297744.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:定位   设置   是否   返回   需要   位置
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议