看起来现在(2019年)谷歌地图没有单独的API或服务用于扩展共享位置URL,但您可以使用基于以下技巧的解决方法:通过谷歌地图Web界面,谷歌服务器可以执行此操作。
简而言之:
您不需要扩展API。例如,如果
https://maps.app.goo.gl/eEhh3
在PC上(例如FireFox)输入网页浏览器中的URL,然后该URL会被展开并显示标记。在此过程中,您可以在地址栏中看到“部分展开”的URL:
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
在1-2秒内,它会被“完全展开”的URL重定向,并带有类似于lat/lng坐标的信息:
https://www.google.com/maps/place/Siddique+Trade+Center/@31.5313297,74.3504459,17z/data=!3m1!4b1!4m5!3m4!1s0x391904e4af9b1e35:0xee6f3c848c9e5341!8m2!3d31.5313297!4d74.3526346
.
因此,您可以使用WebView
执行相同操作,并从中获取“完全展开”(例如,在WebViewClient
的public void onPageFinished(WebView view, String url)
中)。注意:需要跳过第一个“部分展开”的URL。
另一个问题是:
WebView
会将类似
https://maps.app.goo.gl/eEhh3
的缩短 URL 转换为 Google Maps 应用程序的 Intent,并且 "部分展开" 的 URL
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
永远不会被加载。实际上,如果你只需要显示标记,这已经足够了。但如果你需要坐标,则可以通过
HttpUrlConnection
打开缩短的 URL
https://maps.app.goo.gl/eEhh3
并在打开连接后通过
HttpUrlConnection.getURL()
或
Location
Header 字段获取重定向的 "部分展开" URL,然后调用
HttpUrlConnection.getInputStream()
。实际上,如果你将从
HttpUrlConnection
输入流中加载的所有响应作为
String
加载,你可以通过
https://www.google.com/maps/preview/place
标签在其中找到所需的纬度/经度坐标。例如:
...
[[[1,42]\n]\n,0,null,0,47]\n]\n,null,\"Suit 706 Siddiq Trade Center, Main Blvd Gulberg, Block H Gulberg III, Lahore, Punjab, Pakistan\",null,null,\"https://www.google.com/maps/preview/place/Siddique+Trade+Center,+Suit+706+Siddiq+Trade+Center,+Main+Blvd+Gulberg,+Block+H+Gulberg+III,+Lahore,+Punjab,+Pakistan/@31.5313297,74.3526346,3401a,13.1y/data\\u003d!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341\",1,null,null,null,null,null,
...
是您通过HttpUrlConnection
打开的缩短URL。在我看来,更好的方法(但稍微慢一些)是将从{{link1:HttpUrlConnection.getURL()
}}接收到的“部分展开”的URL传递到WebView
中,并从其地址行中获取“完全展开”的URL。因此,附带完整源代码:
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mGoogleMap;
private MapFragment mMapFragment;
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.setProperty("http.agent", "");
mWebView = (WebView) findViewById(R.id.web_view);
mWebView.setVisibility(View.GONE);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
if (isUrlFullExpanded(url)) {
LatLng latLng = getLatLngFromExpandedUrl(url);
onLatLngReceived(latLng);
}
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mMapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mMapFragment.getMapAsync(this);
new GetLocationURL().execute(new String[] {"https://maps.app.goo.gl/eEhh3"});
}
private LatLng getLatLngFromExpandedUrl(String url) {
final String beginMarker = "/@";
final String endMarker = "/";
final int ixCoordsStart = url.indexOf(beginMarker) + beginMarker.length();
final int ixCoordsEnd = url.indexOf(endMarker, ixCoordsStart);
String coordinatesString = url.substring(ixCoordsStart, ixCoordsEnd);
LatLng latLng = null;
if (!TextUtils.isEmpty(coordinatesString)) {
String[] coords = coordinatesString.split(",");
if (coords.length >= 2) {
latLng = new LatLng(Float.parseFloat(coords[0]), Float.parseFloat(coords[1]));
}
}
return latLng;
}
private boolean isUrlFullExpanded(String url) {
return url.indexOf("place/") > -1 && url.indexOf("place//") == -1 && url.indexOf("/@") > -1;
}
private void onLatLngReceived(LatLng latLng) {
if (mGoogleMap != null && latLng != null) {
mGoogleMap.addMarker(new MarkerOptions().position(latLng));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
}
private class GetLocationURL extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
String locationUrl = null;
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder responseStringBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
responseStringBuilder.append(line);
}
locationUrl = connection.getURL().toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return locationUrl;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
mWebView.loadUrl(result);
}
}
}
和 activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="<YOUR_PACKAGE>.MainActivity">
<fragment
android:id="@+id/map_fragment"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
你可以得到类似这样的东西:
![Marker from expanded URL](https://istack.dev59.com/ChtU6.webp)
注意!Google 可能随时更改所述行为。