- 小程序配置了后台地址位置能力,还是无法后台运行,是什么原因?
小程序设置了后台运行,已经配置了requiredBackgroundModes和requiredPrivateInfos,相关的接口也已经申请了权限,超过半个小时后小程序还是会被杀死,推测是退出前台模式后,切换到了挂起状态,然后30分钟后就被销毁了。怎么能长时间保持后台运行。下图是相关配置 [图片]
10-08 - 小程序设置了后台运行的相关配置,还是无法后台运行,是什么原因?
小程序设置了后台运行,已经配置了requiredBackgroundModes和requiredPrivateInfos,相关的接口也已经申请了权限,超过半个小时后小程序还是会被杀死,推测是退出前台模式后,切换到了挂起状态,然后30分钟后就被销毁了。怎么能长时间保持后台运行。下图是相关配置 [图片]
09-25 - 安卓系统微信后台运行时wx.onLocationChange不执行
问题详细描述: 目前公司业务需要可以通过小程序定位到员工的位置,但是员工微信小程序不可能一直前台运行着,大部分情况下还是后台运行,为此申请开通了wx.onLocationChange、wx.startLocationUpdate、wx.startLocationUpdateBackground接口,但是发现ios系统没问题,可以后台运行,安卓手机超过一定时间后,小程序就会重置,以下是代码片段 <template> <view> <custom-tab-bar> <view class="container"> <map id="map" :longitude="longitude" :latitude="latitude" :scale="17" :style="{ width: '100%', height: mapHeight + 'px' }" show-location :polyline="polyline" :markers="markers" @regionchange="regionChange"></map> <view class="toggle-info" @click="toggleInfo"> <image v-if="showInfo" src="@/static/collapse.png" /> <image v-else src="@/static/expand.png" /> </view> <view class="banner"> <view class="info"> <text>轨迹距离: {{ (distance / 1000).toFixed(2) }} 公里</text> <text>海拔高度: {{ altitude }} 米</text> </view> <view class="controls" v-show="showInfo"> <image v-if="!tracking && !paused" src="@/static/start.png" @click="startTracking" /> <image v-if="paused" src="@/static/continue.png" @click="resumeTracking" /> <image v-if="tracking" src="@/static/stop.png" @click="stopTracking" /> <image v-if="paused" src="@/static/pause.png" @click="confirmTerminateTracking" /> </view> <!-- <text v-if="elapsedTime">经过时间: {{ Math.floor(elapsedTime / 60) }} 分 {{ elapsedTime % 60 }} 秒</text> --> </view> </view> </custom-tab-bar> </view> </template> <script> import { startInspection, endInspection } from '@/api/track.js' import { getFormattedDate, } from '@/utils/common.js' import CustomTabBar from '@/pages/components/customTabbar.vue'; export default { components: { CustomTabBar }, data() { return { longitude: 0, latitude: 0, altitude: 0, distance: 0, tracking: false, paused: false, path: [], // 存储移动轨迹 polyline: [], // 生成移动轨迹 lastLocation: null, // 存储上一个有效位置 isStart: false, // 是否满足调用开始接口 isEnd: false, // 是否满足调用结束接口 startId: null, // ID获取 startTime: 0, // 记录开始时间 // elapsedTime: 0, // 添加经过时间字段,以秒为单位 // timerId: null // 定时器ID locationChangeHandler: null, inspectionSortKey: 0, showInfo: true, mapHeight: 520, systemInfo: null, markers: [], }; }, mounted() { this.systemInfo = uni.getSystemInfoSync(); this.mapHeight = this.systemInfo.platform === 'ios' ? 520 : 480; // 根据需要调整高度 }, onLoad() { this.restoreState(); this.requestLocationPermission(); }, onUnload() { // this.saveState(); }, onHide() { this.saveState(); }, methods: { requestLocationPermission() { uni.authorize({ scope: 'scope.userLocationBackground', success: () => { this.getCurrentLocation(); }, fail: () => { uni.showModal({ title: '提示', content: '请授权获取位置信息,否则无法使用该功能', showCancel: false }); } }); }, getCurrentLocation() { uni.getLocation({ type: 'gcj02', altitude: true, success: (res) => { if (res && res.longitude !== undefined && res.latitude !== undefined) { this.longitude = res.longitude; this.latitude = res.latitude; this.altitude = (res.altitude || 0).toFixed(2); this.lastLocation = { longitude: res.longitude, latitude: res.latitude }; } else { console.error("获取位置返回值不正确", res); } }, fail: (err) => { console.error("获取位置失败", err); } }); }, startTracking() { wx.startLocationUpdateBackground({ type: 'wgs84', success: (res) => { // console.log(res, 'startLocationUpdateBackgroundstartLocationUpdateBackground') if (this.tracking) return; this.isStart = true; this.tracking = true; this.paused = false; this.path = []; this.polyline = []; this.getLocationAndUpdate(); // this.timerId = setInterval(() => { // this.elapsedTime++; // }, 1000); }, fail: (err) => { console.error('开始后台定位失败', err); } }); }, getLocationAndUpdate() { this.locationChangeHandler = async (res) => { const { longitude, latitude, altitude, accuracy, } = res; console.log(res, 'resresresres') this.altitude = (altitude || 0).toFixed(2); if (this.isSignificantChange(longitude, latitude) && this.startId !== null && accuracy < 40) { this.inspectionSortKey++ this.path.push({ longitude, latitude, height: (altitude || 0).toFixed(2), inspectionSortKey: this.inspectionSortKey }); this.updatePolyline(); this.calculateDistance(); this.longitude = longitude; this.latitude = latitude; this.lastLocation = { longitude, latitude }; // 更新上一个位置 } else if (this.startId === null) { if (this.isStart) { await this.reverseGeocode(longitude, latitude, res); } } }; wx.onLocationChange(this.locationChangeHandler); }, async stopTracking() { if (!this.tracking) return; this.tracking = false; this.paused = true; // if (this.timerId !== null) { // clearInterval(this.timerId); // this.timerId = null; // } await this.getLocationAndUpdate(); if (this.locationChangeHandler) { wx.offLocationChange(this.locationChangeHandler); this.locationChangeHandler = null; // 清空引用 } }, resumeTracking() { wx.startLocationUpdateBackground({ type: 'wgs84', success: (res) => { if (this.tracking) return; this.tracking = true; this.paused = false; this.getLocationAndUpdate(); }, fail: (err) => { console.error('开始后台定位失败', err); } }); // this.timerId = setInterval(() => { // this.elapsedTime++; // }, 1000); }, confirmTerminateTracking() { uni.showModal({ title: '确认终止', content: '请确认本次轨迹定位是否结束', success: (res) => { if (res.confirm) { this.isEnd = true; this.isStart = false; uni.getLocation({ type: 'gcj02', altitude: true, success: async (res) => { const { longitude, latitude, altitude } = res; await this.reverseGeocode(longitude, latitude, res); this.markers.push({ id: 2, latitude, longitude, iconPath: '/static/road-stop.png', // 开始图标路径 width: 60, height: 60, }); setTimeout(() => { this.markers = []; }, 2000) }, fail: (err) => { console.error("获取位置失败", err) } }); } } }); }, updatePolyline() { this.polyline = [{ points: this.path, color: "#FF0000DD", width: 5, dottedLine: false }]; }, calculateDistance() { if (this.path.length < 2) return; const lastPoint = this.path[this.path.length - 2]; const currentPoint = this.path[this.path.length - 1]; const distance = this.getDistance(lastPoint, currentPoint); this.distance += distance; }, getDistance(point1, point2) { const radLat1 = (point1.latitude * Math.PI) / 180.0; const radLat2 = (point2.latitude * Math.PI) / 180.0; const a = radLat1 - radLat2; const b = (point1.longitude * Math.PI) / 180.0 - (point2.longitude * Math.PI) / 180.0; let s = 2 * Math.asin( Math.sqrt( Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2) ) ); s = s * 6378137.0; // 地球半径 s = Math.round(s * 10000) / 10000.0; return s; }, isSignificantChange(longitude, latitude) { if (!this.lastLocation) return true; const deltaLongitude = Math.abs(longitude - this.lastLocation.longitude); const deltaLatitude = Math.abs(latitude - this.lastLocation.latitude); return deltaLongitude > 0 || deltaLatitude > 0; }, regionChange(e) { // console.log('region change', e); }, async reverseGeocode(longitude, latitude, data) { // const key = '6b7fd0d3e900c4be1279cb705e103953'; const key = '2f2f22f5109d0b452c754da47fd45f6d'; const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${key}`; // const url = `https://restapi.amap.com/v3/geocode/regeo?location=119.146617,33.618107&key=${key}`; try { let params; const res = await new Promise((resolve, reject) => { uni.request({ url: url, success: (res) => { resolve(res); }, fail: (err) => { reject(err); } }); }); if (this.isStart) { const formattedDate = getFormattedDate(); if (!this.startId) this.startTime = formattedDate; const { city, province, district, township } = res.data.regeocode.addressComponent; params = { id: this.startId, longitude, latitude, city: Array.isArray(city) ? null : city, province, district, township, address: res.data.regeocode.formatted_address, height: (data.altitude || 0).toFixed(2), inspectionSortKey: this.inspectionSortKey, inspectionStartTime: formattedDate }; const startRes = await startInspection(params); this.startId = startRes.data; this.markers.push({ id: 1, latitude, longitude, iconPath: '/static/road-start.png', // 开始图标路径 width: 60, height: 60, }); if (this.path.length === 0) { this.inspectionSortKey++; this.path.push({ longitude, latitude, height: (data.altitude || 0).toFixed(2), inspectionSortKey: this.inspectionSortKey }); } this.isStart = false; } if (this.isEnd) { params = { id: this.startId, userInspectionDtoList: this.path, totalDistance: this.distance.toFixed(2), } await endInspection(params); this.paused = false; this.tracking = false; this.isEnd = false; this.distance = 0; this.altitude = 0; this.startId = null; this.path = []; this.polyline = []; this.inspectionSortKey = 0; uni.removeStorageSync('trackingState'); wx.stopLocationUpdate({ success: () => { console.log('成功停止后台定位'); if (this.locationChangeHandler) { wx.offLocationChange(this.locationChangeHandler); this.locationChangeHandler = null; // 清空引用 } }, fail: (err) => { console.error('停止后台定位失败', err); } }); } } catch (e) { console.error("反向地理编码请求失败", e); } }, saveState() { const state = { startId: this.startId, // 开始运动ID startTime: this.startTime, // 开始日期 isStart: this.isStart, // 开始状态 tracking: this.tracking, // 按钮显示状态 paused: this.paused, // 按钮显示状态 isEnd: this.isEnd, // 是否满足结束状态 lastLocation: this.lastLocation, // 存储上一个有效位置 path: this.path, hideTime: getFormattedDate(), inspectionSortKey: this.inspectionSortKey, // distance: this.distance, // polyline: this.polyline, }; uni.setStorageSync('trackingState', state); }, restoreState() { this.constructor(); const state = uni.getStorageSync('trackingState'); if (state) { if (state.startId) { const currentDate = new Date(); const pastDateObj = new Date(state.hideTime); const timeDifference = currentDate - pastDateObj; if (timeDifference > 240000) { uni.showModal({ title: '提示', content: '检测到您上次的跑步还没有结束,是否继续?', success: (res) => { if (res.confirm) { const { startId, startTime, isStart, tracking, paused, isEnd, lastLocation, path, inspectionSortKey } = state; this.startId = startId; // 开始运动ID this.startTime = startTime; // 开始日期 this.isStart = isStart; // 开始状态 this.tracking = tracking; // 按钮显示状态 this.paused = paused; // 按钮显示状态 this.isEnd = isEnd; // 是否满足结束状态 this.lastLocation = lastLocation; // 存储上一个有效位置 this.path = path; this.inspectionSortKey = inspectionSortKey; // if (tracking) { // const pastDate = new Date(startTime); // 过去的日期 // const currentDate = new Date(); // 当前日期 // // 计算时间差(以秒为单位) // this.elapsedTime = Math.floor((currentDate - pastDate) / // 1000); // 转换为秒 // } // this.timerId = setInterval(() => { // this.elapsedTime++; // }, 1000); } else if (res.cancel) { this.confirmTerminateTracking() } } }); } } } }, constructor() { this.longitude = 0; this.latitude = 0; this.altitude = 0; this.distance = 0; this.tracking = false; this.paused = false; this.path = []; // 存储移动轨迹 this.polyline = []; // 生成移动轨迹 this.lastLocation = null; // 存储上一个有效位置 this.isStart = false; // 是否满足调用开始接口 this.isEnd = false; // 是否满足调用结束接口 this.startId = null; // ID获取 this.startTime = 0; // 记录开始时间 this.inspectionSortKey = 0; // this.elapsedTime = 0; // 添加经过时间字段,以秒为单位 // this.timerId = null; // 定时器ID }, toggleInfo() { this.showInfo = !this.showInfo; // 切换信息的显示状态 if (this.showInfo) { this.mapHeight = this.systemInfo.platform === 'ios' ? 520 : 480; // 根据需要调整高度 } else { this.mapHeight = this.systemInfo.platform === 'ios' ? 600 : 550; // 根据需要调整高度 } }, } }; </script> <style> .container { display: flex; flex-direction: column; align-items: center; justify-content: center; } .controls { margin-top: 20px; display: flex; flex-direction: row; justify-content: center; gap: 15px; } .controls image { width: 50px; height: 50px; cursor: pointer; } .toggle-info { width: 100%; padding-bottom: 10px; text-align: center; } .toggle-info image { width: 25px; height: 25px; } .banner { width: 100%; } .info { display: flex; align-items: center; justify-content: center; padding: 0 30px; } .info text { flex: 1 } .info text:last-child { text-align: right; } </style>
09-20 - wx.startLocationUpdateBackground接口每次都审核不通过?
目前涉及到的业务需要开通wx.startLocationUpdateBackground接口,描述了几次场景,每次都审核不通过,是卡到哪里了
09-02