uniapp使用webview调用谷歌地图的完整过程(小程序+app端)

 更新时间:2025年07月09日 10:22:08   作者:蔡一一  
最近在做uni-app的项目,由于是海外市场,所以在APP中需要使用到谷歌地图,这篇文章主要介绍了uniapp使用webview调用谷歌地图(小程序+app端)的相关资料,需要的朋友可以参考下

前言

适用小程序和app端;具体功能可以搜索地址,选中地址返回。

一.前期准备

1.谷歌地图需要科学 上网,否则无法加载。需要的软件自己备好,后续在模拟器测试也可以用到。

2.申请谷歌地图密钥

平台地址:https://developers.google.cn/maps/gmp-get-started

选择Maps JavaScript API

如需使用搜索地址则需开启,启用Places API(原先旧的api,在H5使用可能出现跨域问题,如后端可以解决,可直接使用这个)和Places API(New)(新的api,返回报错403)

二.相关代码

1.uniapp代码

点击选择地址页面

跳转地图显示页面

这里我看别人可以使用放置在本项目的html文件(例如/hybrid/html/map.html),但是我引用本地的没效果,后面就替换成线上的了。

但是这里你可以在本地运行html文件,然后使用本地ip调用可以做调试用

注意:
1.这里的@message="postMessageFun"方法是接收来自html页面的返回值。
2.如果需要在模拟器校验app效果,需要换成线上地址。

2.html文件

这里引入了vue,有些是vue写法的

<!DOCTYPE html>
<html style="width: 100vw;height: 100vh;">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<!-- 引入vue -->
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

		<!-- 引入样式element组件 -->
		<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="external nofollow" >
		<!-- 引入组件库 -->
		<script src="https://unpkg.com/element-ui/lib/index.js"></script>

		<!-- 引入less处理器 -->
		<link rel="stylesheet/less" type="text/css" href="./css/map.less" rel="external nofollow"  />
		<script src="https://cdn.jsdelivr.net/npm/less"></script>

		<!-- 引入axios -->
		<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<div id="app" class="popup">
			<div class="tools">
				<i class="el-icon-circle-close close-icon" @click="close"></i>
				<el-button type="primary" class="tools-btn" @click="confirm">Confirm</el-button>
			</div>
			<div class="map">
				<div id="googleMap"></div>
			</div>
			<div class="box">
				<div class="label">
					<i class="el-icon-search search-icon"></i>
					<input v-model="searchAddress" type="text" placeholder="search place"
						placeholder-style="color:#b8b8b8;" />
				</div>
				<div class="lists">
					<div class="list" v-for="(item, index) in list">
						<div class="radio-box">
							<span class="radio-name">{{ item.name }}</span>
							<span class="radio-text">{{ item.formatted_address }}</span>
						</div>
						<el-radio v-model="current" :label="index.toString()" @input="radioChange"> </el-radio>
					</div>
				</div>
			</div>
		</div>
	</body>

	<!-- 微信 JS-SDK  -->
	<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
	<!-- uni 的 SDK -->
	<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>

	<script>
		// 初始化地图
		var map;

		function initMap() {
			//页面传过来的参数arr
			var mapPointResult = GetUrlParam('arr') ? JSON.parse(decodeURIComponent(GetUrlParam('arr'))) : [{
				lng: 103.53028,
				lat: 10.62592
			}];

			var centerPoint = {
				lat: mapPointResult[0].lat,
				lng: mapPointResult[0].lng,
			};

			map = new google.maps.Map(document.getElementById('googleMap'), {
				center: centerPoint,
				zoom: 16
			});

			var marker = new google.maps.Marker({
				position: centerPoint,
				map: map,
				icon: {
					url: 'https://now.guua.com/attachs/default/location_shop.png',
					scaledSize: new google.maps.Size(30, 30),
					origin: new google.maps.Point(0, 0),
					anchor: new google.maps.Point(0, 0)
				}
			});
		}

		// 处理URL参数
		function GetUrlParam(paraName) {
			var url = window.location.href;
			var arrObj = url.split("?");
			if (arrObj.length > 1) {
				var arrPara = arrObj[1].split("&");
				var arr;
				for (var i = 0; i < arrPara.length; i++) {
					arr = arrPara[i].split("=");
					if (arr != null && arr[0] == paraName) {
						return arr[1];
					}
				}
				return "";
			} else {
				return "";
			}
		}

		// 定位(这里如果需要搜索选中地址后定位到选中位置,可以调用这个方法)
		// function searchAddress() {
		// 	var address = '北京';
		// 	var geocoder = new google.maps.Geocoder();
		// 	geocoder.geocode({
		// 		'address': address
		// 	}, function(results, status) {
		// 		if (status === 'OK') {
		// 			var latlng = results[0].geometry.location;
		// 			var map = new google.maps.Map(document.getElementById('googleMap'), {
		// 				zoom: 15,
		// 				center: latlng
		// 			});
		// 			var marker = new google.maps.Marker({
		// 				position: latlng,
		// 				map: map,
		// 				title: 'Address Location'
		// 			});
		// 		} else {
		// 			alert('Geocode was not successful for the following reason: ' + status);
		// 		}
		// 	});
		// }
	</script>

	<!-- 引入谷歌地图 -->
	<script src="https://maps.googleapis.com/maps/api/js?key=你的秘钥&callback=initMap"
		async defer></script>

	<script>
		new Vue({
			el: '#app',
			data: {
				googleKey: '你的秘钥',
				searchAddress: '',
				current: -1,
				list: [],
				curPlace: false
			},

			watch: {
				searchAddress: {
					handler(newV) {
						if (newV) {
							this.searchFindAddress();
						} else {
							this.list = [];
						}
					},
					deep: true
				}
			},

			methods: {
				// 关闭地图
				close() {
					uni.navigateBack({
						delta: 1
					});
				},

				// 选中地址
				confirm() {
					let thar = this;
					if (this.curPlace) {
						let curPlace = JSON.parse(this.curPlace);
						let latlng = {
							lat: curPlace.geometry.location.lat,
							lng: curPlace.geometry.location.lng
						};

						let url =
							`https://maps.googleapis.com/maps/api/geocode/json?key=${this.googleKey}&latlng=${latlng.lat},${latlng.lng}&language=en`;

						axios.get(url).then(res => {
							console.log('确定选中地址回调', res)
							if (res.status == 200) {
								let resData = res.data;
								let compound_code = resData.plus_code.compound_code;
								compound_code = compound_code.split(' ');
								let obj = {
									compound_code: compound_code[1],
									latlng: latlng,
									// name: curPlace.name
									name: curPlace.formatted_address
								};
								
								//选中返回uniapp的值
								uni.postMessage({
									data: obj
								});
								
								thar.close();
							}
						}).catch(err => {
							console.log(err)
						})
					} else {
						alert('请先选中地址!!!')
					}
				},

				//搜索
				searchFindAddress() {
					let thar = this;
					this.current = -1;
					this.list = [];
					// 原有的接口出现跨域问题(新的api需要注册才可以用)
					// let url =
					// 	`https://maps.googleapis.com/maps/api/place/textsearch/json?key=${this.googleKey}&query=${encodeURIComponent(this.searchAddress)}&language=en`;

					// 可以调用,但是返回的信息不完整(这里没有返回具体的地址)
					let url =
						`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(this.searchAddress)}&key=${this.googleKey}`;

					axios.get(url)
						.then(response => {
							console.log('搜索地址', response);
							if (response.data.status === 'OK') {
								let resData = response.data.results;
								thar.list = resData;
							} else {
								thar.list = [];
							}
						})
						.catch(error => {
							// this.errorMessage = '请求失败,请稍后再试';
							console.error('请求失败', error);
						});
				},

				//列表选中地址
				radioChange(e) {
					this.current = e;
					this.curPlace = JSON.stringify(this.list[this.current]);
				},

			}
		})
	</script>
</html>

注意的点:

1.需要和uniapp页面通信的话,必须引入这两个SDK,并且需要放在body后面,而且微信SDK必须在前面。

2.谷歌搜索api问题

这里后续我让后端给我处理了。

https://maps.googleapis.com/maps/api/place/textsearch/json?key=你的密钥&query=搜索地址&language=en
这个是旧的api,但是在H5页面使用会出现跨域问题,最好是让后端给解决一下,直接给你一个接口。

https://places.googleapis.com/v1/places:searchText是新的api,这里调用会出现403报错。这里确定配置平台已启用了Places API(New),不晓得是哪里不行,求知道的大佬告知。
以下为调用的代码片段和报错信息

let url = `https://places.googleapis.com/v1/places:searchText`;
axios.post(url, {
	textQuery: this.searchAddress,
	'X-Goog-FieldMask': '*',
	'X-Goog-Api-Key': '你的密钥'
}).then(response => {
	console.log('搜索地址', response);
	if (response.data.status === 'OK') {
		let resData = response.data.results;
		thar.list = resData;
	} else {
		thar.list = [];
	}}).catch(error => {
		// this.errorMessage = '请求失败,请稍后再试';
		console.error('请求失败', error);
	});

三.效果图

网页端

小程序

app

四.其他

这里如果想在模拟器测试,需要在模拟器安装跨域工具(和在真机安装配置一样)。

这里配置自己搜索下进行配置就好。

开启后,就能进去app校验地图效果了。

到此这篇关于uniapp使用webview调用谷歌地图(小程序+app端)的文章就介绍到这了,更多相关uniapp webview调用谷歌地图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js事件流、事件委托与事件阶段实例详解

    js事件流、事件委托与事件阶段实例详解

    事件委托应用在很多开发场景之中,但是很多同学对委托的原理、特别是对JS原生实现委托不太了解,下面这篇文章主要给大家介绍了关于js事件流、事件委托与事件阶段的相关资料,需要的朋友可以参考下
    2022-02-02
  • js 字符串转换成数字的三种方法

    js 字符串转换成数字的三种方法

    在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形式的.在网上找了一下js字符串转数字的文章,这个比较全
    2013-03-03
  • JavaScript实现俄罗斯方块游戏过程分析及源码分享

    JavaScript实现俄罗斯方块游戏过程分析及源码分享

    这篇文章主要介绍了JavaScript实现俄罗斯方块游戏过程分析及源码分享,本文分解了游戏规则、实现过程、难点分析及实现源码,需要的朋友可以参考下
    2015-03-03
  • webpack4之SplitChunksPlugin使用指南

    webpack4之SplitChunksPlugin使用指南

    这篇文章主要介绍了webpack4之SplitChunksPlugin使用指南,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • ckeditor一键排版功能实现方法分析

    ckeditor一键排版功能实现方法分析

    这篇文章主要介绍了ckeditor一键排版功能实现方法,结合实例形式分析了ckeditor一键排版相关扩展插件定义、配置与使用方法,需要的朋友可以参考下
    2020-02-02
  • LayUI数据接口返回实体封装的例子

    LayUI数据接口返回实体封装的例子

    今天小编就为大家分享一篇LayUI数据接口返回实体封装的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • Javascript Web Slider 焦点图示例源码

    Javascript Web Slider 焦点图示例源码

    Slider 焦点图会在很多的网站上见到,在本文为大家详细介绍下具体的实现过程,下面的源码大家可以运行下
    2013-10-10
  • 如何利用Three.js实现web端显示点云数据

    如何利用Three.js实现web端显示点云数据

    这篇文章主要给大家介绍了关于如何利用Three.js实现web端显示点云数据的相关资料,最近在项目中遇到需求,需要在web端显示点云数据,将我的实现步骤介绍在这里供大家参考,需要的朋友可以参考下
    2023-11-11
  • JavaScript 判断数据类型的4种方法

    JavaScript 判断数据类型的4种方法

    这篇文章主要介绍了JavaScript 判断数据类型的4种方法,帮助大家更好的理解和学习JavaScript,感兴趣的朋友可以了解下
    2020-09-09
  • javascript中先加加和后加加区别 ++a和a++区别解析

    javascript中先加加和后加加区别 ++a和a++区别解析

    从学习 javascript 开始,就对 先加加 和 后加加 模糊不清,时至今日,再来学习一下,这篇文章主要介绍了javascript中先加加和后加加区别++a和a++区别解析,需要的朋友可以参考下
    2023-09-09

最新评论