如何从 Google 地图扩展共享位置 URL?
How to expand the shared location URL from Google Maps?
我正在尝试从 google 地图共享位置 link 获取位置,所以我正在使用 Google 缩短 URL API 来扩展 URL 但是当我从 android 设备的 Google 地图应用程序共享 URL 时,它给了我 https://maps.app.goo.gl/eEhh3
这种 URL。它没有给我实际扩展 URL 提供位置信息。
如何展开这个:
https://maps.app.goo.gl/eEhh3
在此link:
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
这是我用来扩展它的 API URL。
"https://www.googleapis.com/urlshortener/v1/url?shortUrl=https://maps.app.goo.gl/eEhh3&key=(API_KEY)
"
但不是给我上面的位置信息URL它returns我这个长URL.
https://maps.app.goo.gl/?link=https://www.google.com/maps/place//data%3D!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source%3Dmstt_1&apn=com.google.android.apps.maps&ibi=com.google.Maps&ius=comgooglemapsurl&isi=585027354
请帮助我如何通过 Google API 获取上述位置信息 URL 以获取位置 (Lat, Lng) 通过 Google 从任何设备映射共享位置 Url (IOS,WebAPP,特别是 Android)。
现在(2019 年)似乎没有单独的 API 或用于从 Google 地图扩展共享位置 URL 的服务,但您可以使用基于该技巧的解决方法:Google 服务器可以通过 Google 地图网络界面完成。
TLDR;
您不需要 expand API。例如,如果
https://maps.app.goo.gl/eEhh3
URL 在 PC 上的网络浏览器(例如 FireFox)中键入比 URL 展开并显示标记。在此期间,您可以在地址字段 "partially expanded" URL 中看到:
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
在 1-2 秒内由 "full expanded" 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
to do the same and get "full expanded" from it (e.g. in public void onPageFinished(WebView view, String url)
of WebViewClient
)。注意:需要先跳过"partially expanded" URL。
另一个问题:WebView
将 https://maps.app.goo.gl/eEhh3
等缩短的 URL 转换为 Google 地图应用程序和 "partially expanded" URL 的 Intent
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
永远不会加载。实际上,如果您只需要显示标记就足够了。但是,如果您需要坐标,则可以通过 HttpUrlConnection
and get redirected "partially expanded" URL via HttpUrlConnection.getURL()
or via Location
Header field after connection opened and HttpUrlConnection.getInputStream()
called 打开缩短的 URL https://maps.app.goo.gl/eEhh3
来解决此问题。实际上,如果您将来自 HttpUrlConnection
输入流的所有响应加载为 String
- 您可以通过 https://www.google.com/maps/preview/place
标记在其中找到所需的 lat/lng 坐标。类似于:
...
[[[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。恕我直言,更好(但稍慢)的方法是将从 HttpUrlConnection.getURL()
收到的 "partially expanded" URL 传递到 WebView
并从其地址行获取 "full expanded" 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);
// configure WebView
System.setProperty("http.agent", ""); // reset default User-Agent
mWebView = (WebView) findViewById(R.id.web_view);
mWebView.setVisibility(View.GONE);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// skip non-"ful expanded" urls
if (isUrlFullExpanded(url)) {
// extract lat/lng coordinates from "full expanded" URL String
LatLng latLng = getLatLngFromExpandedUrl(url);
// just show marker with extracted coordinates for test
onLatLngReceived(latLng);
}
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mMapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mMapFragment.getMapAsync(this);
// start get LatLng from URL coordinates task
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();
// you can analyze response code
//int responseCode = connection.getResponseCode();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder responseStringBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
responseStringBuilder.append(line);
}
// use commented code below if you want to get coordinates directly from HttpURLConnection response
/*
LatLng latLng = null;
String responseString = responseStringBuilder.toString();
String pattern = "\\"https://www.google.com/maps/preview/place";
int ixPlaceStart = responseString.indexOf(pattern);
if (ixPlaceStart > -1) {
int ixCoordsStart = responseString.indexOf("@", ixPlaceStart) + 1;
int ixCoordsEnd = responseString.indexOf("/", ixCoordsStart);
String coordinatesString = responseString.substring(ixCoordsStart, ixCoordsEnd);
String[] coords = coordinatesString.split(",");
// latLng - coordinates from URL
latLng = new LatLng(Float.parseFloat(coords[0]), Float.parseFloat(coords[1]));
}
*/
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);
// pass redirected "partially expandeded" URL to WebView
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>
你可以得到这样的东西:
注意! Google 可以随时更改所描述的行为。
我正在尝试从 google 地图共享位置 link 获取位置,所以我正在使用 Google 缩短 URL API 来扩展 URL 但是当我从 android 设备的 Google 地图应用程序共享 URL 时,它给了我 https://maps.app.goo.gl/eEhh3
这种 URL。它没有给我实际扩展 URL 提供位置信息。
如何展开这个:
https://maps.app.goo.gl/eEhh3
在此link:
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
这是我用来扩展它的 API URL。
"https://www.googleapis.com/urlshortener/v1/url?shortUrl=https://maps.app.goo.gl/eEhh3&key=(API_KEY)
"
但不是给我上面的位置信息URL它returns我这个长URL.
https://maps.app.goo.gl/?link=https://www.google.com/maps/place//data%3D!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source%3Dmstt_1&apn=com.google.android.apps.maps&ibi=com.google.Maps&ius=comgooglemapsurl&isi=585027354
请帮助我如何通过 Google API 获取上述位置信息 URL 以获取位置 (Lat, Lng) 通过 Google 从任何设备映射共享位置 Url (IOS,WebAPP,特别是 Android)。
现在(2019 年)似乎没有单独的 API 或用于从 Google 地图扩展共享位置 URL 的服务,但您可以使用基于该技巧的解决方法:Google 服务器可以通过 Google 地图网络界面完成。
TLDR;
您不需要 expand API。例如,如果
https://maps.app.goo.gl/eEhh3
URL 在 PC 上的网络浏览器(例如 FireFox)中键入比 URL 展开并显示标记。在此期间,您可以在地址字段 "partially expanded" URL 中看到:
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
在 1-2 秒内由 "full expanded" 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
to do the same and get "full expanded" from it (e.g. in public void onPageFinished(WebView view, String url)
of WebViewClient
)。注意:需要先跳过"partially expanded" URL。
另一个问题:WebView
将 https://maps.app.goo.gl/eEhh3
等缩短的 URL 转换为 Google 地图应用程序和 "partially expanded" URL 的 Intent
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
永远不会加载。实际上,如果您只需要显示标记就足够了。但是,如果您需要坐标,则可以通过 HttpUrlConnection
and get redirected "partially expanded" URL via HttpUrlConnection.getURL()
or via Location
Header field after connection opened and HttpUrlConnection.getInputStream()
called 打开缩短的 URL https://maps.app.goo.gl/eEhh3
来解决此问题。实际上,如果您将来自 HttpUrlConnection
输入流的所有响应加载为 String
- 您可以通过 https://www.google.com/maps/preview/place
标记在其中找到所需的 lat/lng 坐标。类似于:
...
[[[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。恕我直言,更好(但稍慢)的方法是将从 HttpUrlConnection.getURL()
收到的 "partially expanded" URL 传递到 WebView
并从其地址行获取 "full expanded" 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);
// configure WebView
System.setProperty("http.agent", ""); // reset default User-Agent
mWebView = (WebView) findViewById(R.id.web_view);
mWebView.setVisibility(View.GONE);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// skip non-"ful expanded" urls
if (isUrlFullExpanded(url)) {
// extract lat/lng coordinates from "full expanded" URL String
LatLng latLng = getLatLngFromExpandedUrl(url);
// just show marker with extracted coordinates for test
onLatLngReceived(latLng);
}
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mMapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mMapFragment.getMapAsync(this);
// start get LatLng from URL coordinates task
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();
// you can analyze response code
//int responseCode = connection.getResponseCode();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder responseStringBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
responseStringBuilder.append(line);
}
// use commented code below if you want to get coordinates directly from HttpURLConnection response
/*
LatLng latLng = null;
String responseString = responseStringBuilder.toString();
String pattern = "\\"https://www.google.com/maps/preview/place";
int ixPlaceStart = responseString.indexOf(pattern);
if (ixPlaceStart > -1) {
int ixCoordsStart = responseString.indexOf("@", ixPlaceStart) + 1;
int ixCoordsEnd = responseString.indexOf("/", ixCoordsStart);
String coordinatesString = responseString.substring(ixCoordsStart, ixCoordsEnd);
String[] coords = coordinatesString.split(",");
// latLng - coordinates from URL
latLng = new LatLng(Float.parseFloat(coords[0]), Float.parseFloat(coords[1]));
}
*/
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);
// pass redirected "partially expandeded" URL to WebView
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>
你可以得到这样的东西:
注意! Google 可以随时更改所描述的行为。