在 Hybrid WebView 中用 AMap.Geolocation 触达系统原生定位
一、为何没有采用高德 Android 原生定位 SDK?
我的项目架构是 Hybrid:Android 外壳 + 内嵌 WebView 跑前端页面。
起初我考虑直接集成 高德 Android 定位 SDK,但这意味着:
- 需要原生开发经验(权限、前台服务、生命周期、功耗策略等);
- 轨迹、UI、上传等逻辑得在原生与 Web 双端同步维护,复杂度高。
因此我转向了高德 JS SDK(AMap.Geolocation):
让 Web 端负责定位与轨迹逻辑,但运行环境放在 Android WebView 内,并且 为 WebView 正确授予系统定位权限。这样 AMap.Geolocation 就会走 系统原生定位通道,而不是传统的 IP/浏览器定位,无需额外集成原生定位 SDK。
二、AMap.Geolocation 的多源融合
要理解 Hybrid 模式下为什么能精确定位,先看一下官方文档中对 AMap.Geolocation 的描述:

简单来说,AMap.Geolocation 内部有三层定位逻辑:
浏览器定位(HTML5 Geolocation)
高精度 IP 定位(PC 默认优先)
Android 原生定位(Hybrid 辅助)
而只要 WebView 本身获得了系统定位权限,高德 JS SDK 就会自动调用原生定位接口返回真实的经纬度数据。
三、项目实战:行迹记录功能中的 Hybrid 定位集成
下面结合我的项目代码,展示整个方案的具体实现。
3.1 Web 前端:调用高德 JS SDK 获取定位与轨迹
Web 端通过 Vue 组件封装了一个“行迹记录”页面,在用户点击“开始记录”后,会启动定时获取定位点,并用 AMap.Polyline 连接成轨迹线。
1 2 3 4 5 6 7 8 9 10
| AMap.plugin('AMap.Geolocation', function () { const geolocation = new AMap.Geolocation({ enableHighAccuracy: true, // 启用高精度模式 timeout: 5000, // 超时时间 zoomToAccuracy: true, // 定位成功后自动调整视野 position: 'RB' // 定位按钮位置 });
map.addControl(geolocation); });
|
通过定时调用 getCurrentPosition(),将所有点保存到数组中,并绘制轨迹:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| getLocation() { mapGeoLocation.getCurrentPosition((status, result) => { // this.toast(status) if (result.status !== 0) { window.$message.error('定位失败:' + result.message) return }
let position = result.position; // [lng, lat] this.paths.push(position)
if (this.paths.length === 1) { this.addStartPointMarker(this.paths[0]) } else { let p1 = this.paths[this.paths.length - 2] let p2 = this.paths[this.paths.length - 1] this.addPolyline(p1, p2) let distance = AMap.GeometryUtil.distance(p1, p2); this.total_length += distance } }); },
|
3.2 Android 原生层:授权 WebView 使用系统定位
Web 页面能否成功定位,关键在于 原生层要先为 WebView 打开定位能力。
1 2 3 4 5
| @Override public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { callback.invoke(origin, true, false); super.onGeolocationPermissionsShowPrompt(origin, callback); }
|
同时需要申请系统级定位权限:
1 2 3 4 5 6 7 8 9
| private void requestLocationPermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, }, 1); } }
|
并在 WebSettings 中开启地理定位支持:
1 2 3 4
| WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setDomStorageEnabled(true); settings.setGeolocationEnabled(true);
|
这样,Web 页面内的高德定位请求就能获得系统级授权。
3.3 JS 与原生的桥接:Hybrid 通信接口
在原生中通过 addJavascriptInterface 暴露接口;
1
| webView.addJavascriptInterface(new WebAppInterface(), "Android");
|
1 2 3 4 5 6 7 8 9 10 11 12
| class WebAppInterface { @JavascriptInterface public void requestLocationPermission() { MainActivity.this.requestLocationPermission(); }
@JavascriptInterface public void keepScreenOn() { runOnUiThread(() -> getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)); } }
|
在前端调用:
1 2 3 4
| if (window.Android) { window.Android.requestLocationPermission() window.Android.keepScreenOn() }
|

参考文档
高德地图JS API文档 —— Geolocation)
Android WebView 官方指南