IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> uni-app 小程序获取实时定位和车辆签到(wx.getLocation方法) -> 正文阅读

[移动开发]uni-app 小程序获取实时定位和车辆签到(wx.getLocation方法)

一、需求描述

????????实现一个车辆定位签到功能,获取当前车辆的实时定位,当车辆到达签到点1公里范围内时,可以进行签到,当大于1公里时,禁止签到。同时用户还可以手动刷新定位。

二、wx.getLocation

? ? ? ? 在之前的博客中,我写了一篇使用wx.onLocationChange进行定位签到的方法,见文章链接?uni-app 小程序获取实时定位和车辆签到(wx.onLocationChange方法),后面微信官方在2022年7月14日发布了一篇关于 “地理位置接口新增与相关流程调整” 的公告,见链接?地理位置接口新增与相关流程调整 | 微信开放社区公告说自 2022 年 7 月 14 日起,开发者在使用下表地理位置相关接口时,需要提前在 app.json 中进行配置:

????????对于普通开发者,2022 年 7 月 14 日后发布的小程序,这8个API都需要在小程序管理后台完成权限申请,申请通过才能够在项目中使用,而我当时使用的wx.onLocationChange申请了多次一直被后台驳回,大概意思就是我这种定位签到应用场景,wx.onLocationChange支持的应用场景只支持下图所示的类目,而我的项目不符合wx.onLocationChange的应用场景,不需要实时监听用户的地理位置变化,所以没办法只能改为使用wx.getLocation方法。

?三、wx.getLocation使用流程

1、接口权限开通

????????在 “小程序管理后台 -「开发」-「开发管理」-「接口设置」” 中完成wx.getLocation API权限申请;

?2、manifest.json(或app.json)配置

? ? ? ? uni-app需要在manifest.json配置"requiredPrivateInfos" : [ "getLocation" ]

3、核心代码

<template>
	<view class="container">
		<view class="map-box">
			<map id="myMap" :scale="14" :latitude="myLat" :longitude="myLon" :markers="markers" :circles="circles"></map>
			<view class="local-icon" @click="authorization"></view>
		</view>
		<view class="btn-box">
			<view class="cancel" v-if="info.workStatus == 1" @click="handleCancelTask">取消任务</view>
			<view class="submit" @click="handleSubmitSign" v-if="isAuth">确认签到</view>
			<view class="submit2" v-else>确认签到</view>
		</view>
	</view>
</template>

<script>
	import { host } from '../../config/config.js'
	export default {
		name: 'sign',
		data() {
			return {
				centerLon: 0,	// 中心经度
				centerLat: 0, 	// 中心纬度
				circles: [],	// 中心签到圈
				radius: 0,  	// 签到半径
				myLon: 0,    	// 当前定位经度
				myLat:0,	  	// 当前定位纬度
				markers: [],	// 当前定位标记点
				distance: 99999,// 车辆到签到中心点距离
				isAuth: false // 是否授权定位
			}
		},
		methods: {
			// 获取中心点坐标, 获取签到圈
			getCoordinate() {
				uni.request({
					url: host + '/api/v1/mini/driver/getCoordinate',
					method: 'GET',
					header:{
						'Content-Type' : 'application/json',
						token : uni.getStorageSync("TOKEN")
					},
					data: {},
					success: res => {
						if(res.data.code === "0") {
							console.log('中心的坐标', JSON.parse(JSON.stringify(res.data.data)))
							this.centerLon = res.data.data.longitude;
							this.centerLat = res.data.data.latitude;
							this.radius = res.data.data.radius;
							this.circles = [{
								longitude: this.centerLon,
								latitude: this.centerLat,
								fillColor: "#FF2B431A",
								color: "#FF0000",
								radius: this.radius,
								strokeWidth: 1
							}]
						} else {
							uni.showToast({
								title: res.data.msg,
								icon: 'none',
								duration: 2000
							});
						}
					},
					fail: () => {},
					complete: () => {}
				});
			},
 			// 获取用户是否授权定位
			authorization() {
				wx.authorize({
					scope: 'scope.userLocation',
					success: (res) => {
						console.log('获取授权成功');
						this.isAuth = true;
						uni.showLoading({
							title: '定位中...'
						});
						wx.getLocation({
							success: (res) => {
								console.log("获取当前初始位置成功", res);
								uni.hideLoading();
								this.drawLocaltionPoint(res);
							},
							fail: (err) => {
								console.log('获取当前初始位置失败', err);
								uni.hideLoading();
							}
						})
					},
					fail: (err) => {
						console.log('获取授权失败', err);
						this.handleOpenSetting();
					}
				})
			},
			// 用户授权定位
			handleOpenSetting() {
				uni.showModal({
					title: '温馨提示',
					content: '获取权限失败,需要获取您的地理位置才能为您提供更好的服务!是否授权获取地理位置?',
					success: (res) => {
						if (res.confirm) {
							wx.openSetting({
							    success: (res) => {
							        if (res.authSetting["scope.userLocation"]) {   // 用户同意授权
										console.log("用户同意授权");
										this.authorization();
							        }
							    }
							})
						}
					}
				});
			},
			// 绘制定位点
			drawLocaltionPoint(res) {
				console.log('绘制定位点:', res.longitude, res.latitude);
				this.myLon = res.longitude;
				this.myLat = res.latitude;
				this.markers = [{
					id: 1,
					longitude: this.myLon,
					latitude: this.myLat,
					iconPath: "../../static/img/record/point.png",
					width: 25,
					height: 25
				}]
			},
			// 确认签到,点击按钮时重新获取用户地理位置
			handleSubmitSign() {
				uni.showLoading({
					title: '定位中...'
				});
				wx.getLocation({
					success: (res) => {
						console.log("获取当前位置成功", res);
						uni.hideLoading();
						this.drawLocaltionPoint(res);
						this.handleSign();
					},
					fail: (err) => {
						console.log('获取当前位置失败', err);
						uni.hideLoading();
						this.handleSign();
					}
				})
			},
			// 签到
			handleSign() {
				this.distance = this.getDistance();
				console.log('签到距离:', this.distance, ' 签到半径:', this.radius);
				// 签到时进行判断,小于签到半径就签到成功,否则提示签到失败
				if(this.distance <= this.radius) {	
					// todo 签到成功,调用签到接口
				} else {
					uni.showToast({
						title: '签到失败,当前未在签到范围内,请稍后重试',
						icon: 'none',
						duration: 2500
					});
				}
			},
			// 获取当前位置距离签到点的距离
			getDistance() {
				let red1 = this.myLat * Math.PI / 180.0;
				let red2 = this.centerLat * Math.PI / 180.0;
				let a = red1 - red2;
				let b = this.myLon * Math.PI / 180.0 - this.centerLon * Math.PI / 180.0;
				let R = 6378137;
				let distance = R * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(red1) * Math.cos(red2) * Math.pow(Math.sin(b / 2), 2)));
				return distance.toFixed(2) * 1;
			}
		},
		onLoad(option) {
			this.getCoordinate();
			this.authorization();
		}
	}
</script>

<style lang="less" scoped>
	.submit {
		color: #FFF;
		background: #FF2A41;
	}
	.submit2 {
		color: #FFF;
		background: #FF95A0;
	}
</style>

四、说明

????????wx.getLocation是有调用频率限制的:

? ? ? ? 1. 在开发版或体验版中,30秒内调用getLocation,仅第一次有效,剩余返回fail。

? ? ? ? 2. 正式版中,为保证小程序正常运行同时不过度消耗用户电量,一定时间内(根据设备情况判断)调用getLocation,仅第一次会返回实时定位信息,剩余返回与第一次定位相同的信息。

? ? ? ? 不管是体验版还是正式版,我都进行了兼容处理,使页面提示更加的友好,符合用户的操作习惯,在体验版中,如果30秒内再次点击确认签到,wx.getLocation会返回fail,执行到上面代码的第142行里面去,然后调用handleSign,签到距离大于半径,进行提示“签到失败,当前未在签到范围内,请稍后重试”;如果是正式版,如果30秒内再次点击确认签到,wx.getLocation会返回上一次的执行结果,执行到上面代码的第136行里面去,然后调用handleSign,签到距离大于半径,进行提示“签到失败,当前未在签到范围内,请稍后重试”所以,不管是正式版还是体验版,当用户频繁调用wx.getLocation,都会提示“签到失败,当前未在签到范围内,请稍后重试”,让用户以为是自己没有到达签到点的问题,当频繁调用频率一过,就会获得新的地理坐标,从而让用户体验更加的友好。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:26:57  更:2022-10-22 21:29:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 22:23:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码