news 2026/4/24 23:30:48

uniapp适配H5和Android-apk实现获取当前位置经纬度并调用接口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
uniapp适配H5和Android-apk实现获取当前位置经纬度并调用接口

index.vue:

注意:这里的

return 'https://www.******.com/bus_admin_java'

这里是区分 H5和apk调用接口地址的不同而设置的。之后凡是调用接口的方法就使用封装后的request()

<template> <view class="container"> <view class="title">实时位置追踪器</view> <view class="btn" :class="{ active: tracking }" @click="toggleTracking" > {{ tracking ? '停止追踪' : '点击开始' }} </view> <view v-if="latitude !== null && longitude !== null" class="location-info"> 当前经度: {{ longitude }} <br /> 当前纬度: {{ latitude }} </view> <!-- 雷达扫描效果 --> <view class="radar" v-if="tracking"> <view class="circle circle1"></view> <view class="circle circle2"></view> <view class="circle circle3"></view> <view class="pulse"></view> </view> </view> </template> <script> const BASE_URL = (() => { // #ifdef H5 return '/api' // #endif // #ifdef APP-PLUS return 'https://www.******.com/bus_admin_java' // #endif return '/api' })() function request(options) { return new Promise((resolve, reject) => { uni.request({ url: BASE_URL + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'content-type': 'application/json', ...(options.header || {}) }, timeout: 15000, success: (res) => { resolve(res) }, fail: (err) => { reject(err) } }) }) } export default { data() { return { latitude: null, longitude: null, tracking: false, timer: null } }, methods: { toggleTracking() { if (this.tracking) { this.tracking = false this.stopTracking() } else { this.startTracking() } }, startTracking() { this.stopTracking() // 先尝试获取一次位置 this.getLocation(true) }, stopTracking() { if (this.timer) { clearInterval(this.timer) this.timer = null } }, getLocation(isFirst = false) { uni.getLocation({ type: 'wgs84', success: (res) => { this.latitude = res.latitude this.longitude = res.longitude console.log('当前位置', res) uni.showToast({ title: `经度:${res.longitude.toFixed(4)} 纬度:${res.latitude.toFixed(4)}`, icon: 'none', duration: 3000 }) this.sendPosition(res.longitude, res.latitude) // 第一次成功后再开启轮询 if (isFirst) { this.tracking = true this.timer = setInterval(() => { this.getLocation(false) }, 3000) } }, fail: (err) => { console.error('获取位置失败', err) this.tracking = false this.stopTracking() this.handleLocationFail(err) } }) }, handleLocationFail(err) { let content = '获取位置失败,请检查定位服务是否开启' // #ifdef APP-PLUS content = '请先开启系统定位服务,并允许当前应用使用定位权限,是否前往设置?' // #endif // #ifdef H5 content = 'H5 获取定位失败,请确认浏览器已允许定位,并且当前页面运行在 HTTPS 或 localhost 环境下' // #endif uni.showModal({ title: '定位失败', content, success: (res) => { if (!res.confirm) return // App 端支持打开设置 // #ifdef APP-PLUS uni.openSetting({ success: (settingRes) => { console.log('设置页返回', settingRes) uni.showToast({ title: '请重新点击开始定位', icon: 'none' }) }, fail: (settingErr) => { console.error('打开设置失败', settingErr) uni.showToast({ title: '无法打开设置页', icon: 'none' }) } }) // #endif // H5 没有统一的 openSetting,给提示即可 // #ifdef H5 uni.showToast({ title: '请在浏览器地址栏附近开启定位权限', icon: 'none', duration: 3000 }) // #endif } }) }, sendPosition(longitude, latitude) { request({ url: '/bus/position/save', method: 'POST', data: { longitude: longitude, latitude: latitude }, success: (res) => { console.log('上传成功', res.data) }, fail: (err) => { console.error('上传失败', err) } }) } }, beforeDestroy() { this.stopTracking() }, onUnload() { this.stopTracking() } } </script> <style> .container { display: flex; flex-direction: column; justify-content: flex-start; align-items: center; padding: 40px 20px; background: radial-gradient(circle at center, #0a0a0a, #001010); min-height: 100vh; color: #00ffff; font-family: "Microsoft YaHei", sans-serif; } .title { font-size: 22px; font-weight: bold; margin-bottom: 20px; } .location-info { margin-top: 20px; font-size: 16px; text-align: center; line-height: 1.8; } .btn { margin-top: 20px; padding: 12px 24px; background: #002f2f; color: #00ffff; border: 1px solid #00ffff; border-radius: 8px; font-size: 16px; text-align: center; transition: all 0.3s ease; } .btn.active { background: #00ffff; color: #001010; box-shadow: 0 0 10px #00ffff; } .btn:active { transform: scale(0.96); } /* 雷达扫描效果 */ .radar { position: relative; width: 200px; height: 200px; margin-top: 40px; } .circle { position: absolute; border: 2px solid rgba(0, 255, 255, 0.3); border-radius: 50%; animation: pulseScale 3s linear infinite; } .circle1 { width: 60px; height: 60px; top: 70px; left: 70px; animation-delay: 0s; } .circle2 { width: 120px; height: 120px; top: 40px; left: 40px; animation-delay: 1s; } .circle3 { width: 180px; height: 180px; top: 10px; left: 10px; animation-delay: 2s; } .pulse { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 255, 255, 0.1); border-radius: 50%; animation: rotateRadar 4s linear infinite; } @keyframes pulseScale { 0% { transform: scale(0.2); opacity: 0.5; } 50% { transform: scale(1); opacity: 0.2; } 100% { transform: scale(0.2); opacity: 0.5; } } @keyframes rotateRadar { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style>

main.js:

import App from './App.vue' // #ifndef VUE3 import Vue from 'vue' import './uni.promisify.adaptor' Vue.config.productionTip = false App.mpType = 'app' const app = new Vue({ ...App }) app.$mount() // #endif // #ifdef VUE3 import { createSSRApp } from 'vue' export function createApp() { const app = createSSRApp(App) return { app } } // #endif

mainifest.json:

{ "name" : "bus_uniapp", "appid" : "__UNI__7E751FC", "description" : "", "versionName" : "1.0.0", "versionCode" : "100", "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { "permissions" : { "Location" : { "desc" : "用于获取当前位置" } }, "usingComponents" : true, "nvueStyleCompiler" : "uni-app", "compilerVersion" : 3, "splashscreen" : { "alwaysShowBeforeRender" : true, "waiting" : true, "autoclose" : true, "delay" : 0 }, /* 模块配置 */ "modules" : {}, /* 应用发布信息 */ "distribute" : { /* android打包配置 */ "android" : { "permissions" : [ "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.READ_LOGS\"/>", "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.CAMERA\"/>", "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" ] }, /* ios打包配置 */ "ios" : { "dSYMs" : false }, /* SDK配置 */ "sdkConfigs" : {} } }, /* 快应用特有相关 */ "quickapp" : {}, /* 小程序特有相关 */ "mp-weixin" : { "appid" : "", "setting" : { "urlCheck" : false }, "usingComponents" : true }, "mp-alipay" : { "usingComponents" : true }, "mp-baidu" : { "usingComponents" : true }, "mp-toutiao" : { "usingComponents" : true }, "uniStatistics" : { "enable" : false }, "vueVersion" : "3" }

注意开通:

vite.config.js: (解决H5的跨域的问题)

// vite.config.js import { defineConfig } from 'vite' import uni from '@dcloudio/vite-plugin-uni' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ uni(), ], server: { // 1. 配置代理规则 proxy: { // 2. '/api' 是你自定义的请求前缀 '/api': { // 3. target 是你的目标后端接口的真实地址 // target: 'http://localhost:9002', target: 'https://www.*****.com/bus_admin_java', // 4. 改变请求源头,解决大部分跨域问题,必须为 true changeOrigin: true, // 5. (可选) 重写路径,移除 '/api' 前缀 rewrite: (path) => path.replace(/^\/api/, '') } } } })
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 23:26:45

电商广告渠道智能分群实战:基于KMeans聚类的效果评估与优化策略

1. 电商广告渠道分群的业务痛点与解决思路 做电商的朋友们应该都深有体会&#xff1a;每个月几十万的广告预算砸下去&#xff0c;渠道A带来一堆流量就是不转化&#xff0c;渠道B转化率超高但流量少得可怜&#xff0c;渠道C的数据时好时坏完全摸不着规律...更头疼的是&#xff0…

作者头像 李华
网站建设 2026/4/24 23:26:19

赛博朋克2077存档编辑器:5步完全掌控你的游戏数据

赛博朋克2077存档编辑器&#xff1a;5步完全掌控你的游戏数据 【免费下载链接】CyberpunkSaveEditor A tool to edit Cyberpunk 2077 sav.dat files 项目地址: https://gitcode.com/gh_mirrors/cy/CyberpunkSaveEditor 你是否厌倦了《赛博朋克2077》中装备属性不理想、背…

作者头像 李华
网站建设 2026/4/24 23:25:54

Qwen3.5-9B-GGUF在软件测试中的应用:自动化测试用例与报告生成

Qwen3.5-9B-GGUF在软件测试中的应用&#xff1a;自动化测试用例与报告生成 1. 引言&#xff1a;当AI遇上软件测试 想象一下这样的场景&#xff1a;周五下午5点&#xff0c;产品经理突然发来一份紧急需求变更文档&#xff0c;要求下周一上线。测试团队面临巨大压力——如何在有…

作者头像 李华
网站建设 2026/4/24 23:25:54

不止于成像:深度相机的非典型进化与场景渗透

当手机人脸识别瞬间解锁屏幕&#xff0c;当工业机器人精准抓取无序堆放的零件&#xff0c;当AR眼镜将虚拟场景与现实世界无缝融合&#xff0c;当自动驾驶汽车精准识别前方障碍物与行人&#xff0c;背后都离不开同一种核心设备——深度相机。它区别于传统2D相机只能捕捉平面图像…

作者头像 李华
网站建设 2026/4/24 23:25:18

别再死记硬背了!用Python手把手模拟8b/10b编码的完整流程(附代码)

用Python实战8b/10b编码&#xff1a;从原理到实现的深度解析 在高速串行通信领域&#xff0c;8b/10b编码就像一位无声的守护者&#xff0c;确保数据在传输过程中保持稳定可靠。这种编码方案的神奇之处在于&#xff0c;它能将8位数据转换为10位传输&#xff0c;有效解决了信号传…

作者头像 李华