Android应用中如何从Google Maps分享链接获取经纬度
解决Google Maps分享短链提取经纬度的问题
为什么你的方法无效?
Geocoder.getFromLocationName()是用来通过地名/地址文本反向解析坐标的,它无法识别URL链接,所以传入短链自然返回空列表。
最佳解决方案(按优先级排序)
1. 直接接收Google Maps的原生位置数据(无需网络)
Google Maps分享位置时,除了文本短链,通常还会携带geo:格式的URI数据,你可以调整Intent过滤器来捕获这类数据,直接解析经纬度:
步骤1:更新AndroidManifest的Intent过滤器
在目标Activity中添加额外的过滤器,支持geo协议和相关MIME类型:
<activity android:name=".activities.MainActivity" android:exported="true" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"> <!-- 原有的text/plain过滤器 --> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <!-- 新增的位置数据过滤器 --> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="geo" /> <data android:mimeType="application/vnd.google-earth.kml+xml" /> </intent-filter> <!-- 支持直接打开geo链接的过滤器 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="geo" /> </intent-filter> </activity>
步骤2:在Activity中解析位置数据
除了处理文本短链,同时检查Intent的data字段,直接提取经纬度:
Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); // 先检查是否有原生位置数据(优先处理) Uri data = intent.getData(); if (data != null && "geo".equals(data.getScheme())) { String geoContent = data.getSchemeSpecificPart(); // 格式示例:geo:37.7749,-122.4194 或 geo:37.7749,-122.4194?z=12&q=San+Francisco String[] latLngSplit = geoContent.split(","); if (latLngSplit.length >= 2) { try { double latitude = Double.parseDouble(latLngSplit[0]); // 去掉可能的参数部分(比如?z=12) double longitude = Double.parseDouble(latLngSplit[1].split("\\?")[0]); // 成功获取经纬度,后续处理 } catch (NumberFormatException e) { e.printStackTrace(); } } } // 再处理文本短链的情况 if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); if (sharedText != null && sharedText.startsWith("https://maps.app.goo.gl/")) { // 处理短链,见方法2 resolveShortLink(sharedText); } } }
2. 解析短链的重定向目标(需要网络)
如果只能拿到短链,需要先发起HTTP HEAD请求获取重定向后的完整Google Maps链接,再从中提取经纬度:
代码示例(用OkHttp实现,需添加依赖)
首先在build.gradle添加OkHttp依赖:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
然后编写解析方法(必须在子线程执行,这里用OkHttp异步回调为例):
private void resolveShortLink(String shortLink) { OkHttpClient client = new OkHttpClient.Builder() .followRedirects(true) .followSslRedirects(true) .build(); Request request = new Request.Builder() .url(shortLink) .head() // 用HEAD请求,只获取响应头,节省带宽 .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { e.printStackTrace(); } @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { if (response.isRedirect()) { String fullUrl = response.header("Location"); if (fullUrl != null) { // 从完整链接提取经纬度 extractLatLngFromFullUrl(fullUrl); } } response.close(); } }); } private void extractLatLngFromFullUrl(String fullUrl) { // 匹配完整链接中的@lat,lng部分,示例:@37.7749,-122.4194,12z Pattern pattern = Pattern.compile("@(-?\\d+\\.\\d+),(-?\\d+\\.\\d+)"); Matcher matcher = pattern.matcher(fullUrl); if (matcher.find()) { try { double latitude = Double.parseDouble(matcher.group(1)); double longitude = Double.parseDouble(matcher.group(2)); // 回到主线程更新UI或处理数据 runOnUiThread(() -> { // 后续操作 }); } catch (NumberFormatException e) { e.printStackTrace(); } } }
3. 使用Google Maps Geocoding API(可选,需API Key)
如果上述方法无法提取,也可以将短链对应的地点名称传入Geocoding API,但需要申请Google Cloud API Key并启用Geocoding API,成本较高,不推荐作为首选。
内容的提问来源于stack exchange,提问作者Andrés
相关产品推荐
相关产品推荐

