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

Posted 小矮马

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,都会提示“签到失败,当前未在签到范围内,请稍后重试”,让用户以为是自己没有到达签到点的问题,当频繁调用频率一过,就会获得新的地理坐标,从而让用户体验更加的友好。

uni-app1 uniapp介绍 & 使用 + 小程序实时获取视频播放时间

文章目录

一、uni-app介绍

1、诞生背景

  1. 多端泛滥。现在是一个多端泛滥的时代,用户被分散到了各个平台,随着微信小程序的兴起,各个平台迅速也推出了自己的小程序。为了覆盖到更多的用户,企业增加了非常多的运营成本,开发人员增加了非常多的学习成本。
  2. 体验不好。过去也有一些跨平台框架,但是在开发体验上不是太好。
  3. 生态不够丰富。 过去的跨平台开发框架在生态上不够丰富,开发者想获取好用的sdk是比较难得到的。

在这样的背景下Dcloud公司决定打造一个终极的跨平台解决方案,即uni-app

2、uni-app是什么(what、where)

uni-app是一个使用vue.js开发所有前端应用的框架,开发者编写一套代码,可以发布到iOS、Android、web(响应式)、以及各种小程序(微信 / 支付宝 / 百度)、快应用等多个平台。

3、uni-app的优势(why)

  1. 跨平台更多,正真做到一段代码多端发行,支持原生代码混写和原生sdk集成
  2. 运行体验良好。组件、api与微信小程序一致,兼容weex原生渲染
  3. 通用技术栈,学习成本更低。vue的的语法,微信小程序的api,对于前端开发人员来说更容易上手
  4. 开放生态,组件更丰富。支持通过npm安装第三方包;支持微信小程序自定义组件以及sdk;兼容mpvue组件及项目;app端支持与原生混合编码

4、uni-app的功能框架图

二、使用uni-app(how)

1、下载安装&创建项目

大家通过官网就可以下载HBuilder,并进行初步的项目创建

2、多端运行

1、在进行微信小程序调试时,要先开启安全设置里面的端口服务,并且在初次进行小程序调试时需要输入微信开发者工具的路径

2、在进行模拟器(手机)调试时,要先打开模拟器的权限,并且,在使用模拟器调试时,要先HBuilder打开模拟器,否则是检测不到模拟器的

3、完成上述步骤之后,就可以在HBuilder中的 ‘ 运行 ’ 开始调试了

3、uni-app操作

操作参照项备注
标签微信小程序(组件)
配置页面微信小程序page.json
配置tabber微信小程序pages.json 中提供了 tabBar 配置
数据绑定vue v-bind :
界面、应用生命周期微信小程序绝大多数采用了小程序的生命周期
组件生命周期vue这里uni将各个平台的生命周期进行封装、统一,我们在开发的时候需要注意个别生命周期只能特定的平台使用。大家在开发过程中如果遇到兼容问题可以翻阅文档中查看说明。
事件定义和传参vuev-on 和 @ 进行事件绑定,传参方式也和vue一致,$event 获取元数据
组件vue父子间传值与vue中完全一致
跳转及传参微信小程序首先:微信小程序中页面跳转方法之一为wx.navigateTo(),在uniapp中方法为uni.navigateTo(),要把wx. 改为uni. 。其次:最好还是按照uniapp官方文档来使用api,在web页面使用this.$router也是可以进行跳转的,但是在小程序以及app就会报错。使用官方api会根据不同的页面进行不同的解析。
循环遍历vuev-for=‘item in list’ :key=‘index’
条件渲染vuev-if v-else v-show
数据改变,页面更更新vue没有setData方法

三、其他

微信小程序实时获取视频播放时间(秒)

使用 bindtimeupdate=“timeUpdate” 事件类型
具体请看官方文档

<video bindtimeupdate="timeUpdate" src='视频地址’ poster="视频封面地址"page-gesturecontrols>
</video>

timeUpdate: function (e) //实时播放进度秒数
	var currentTime = parselnt(e.detail.currentTime)
	console.log("视频播放到第" + currentTime + "秒")//查看正在播放时间,以秒为单位

以上是关于uni-app 小程序获取实时定位和车辆签到(wx.getLocation方法)的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序怎么破定位

uni-app1 uniapp介绍 & 使用 + 小程序实时获取视频播放时间

微信小程序如何获得自己当前的定位呢?本文利用逆地址解析uni-app带你实现

小学期 第2天

秒应小程序怎么改定位

uni-app技术分享| uni-app转小程序-实时消息