I am trying to get the location from google map shared location link so I am using Google Shorten URL API to expand the URL but when I shared URL from Google Map application from the android device it gives me https://maps.app.goo.gl/eEhh3
this kind of URL. It does not give me actual expanded URL to provide Location information.
how to expand this:
https://maps.app.goo.gl/eEhh3
In this 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
Here is the API URL which I am using to expand it.
"https://www.googleapis.com/urlshortener/v1/url?shortUrl=https://maps.app.goo.gl/eEhh3&key=(API_KEY)
"
But instead of giving me the above location information URL it returns me this Long 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
Please help me how can I get above-mentioned Location Info URL by Google API to get Location (Lat, Lng) through Google Map shared location Url from any device (IOS, WebAPP, Specifically Android).
Seems now (in 2019) there is no separate API or service for expanding shared location URL from Google Maps, but you can use workaround based on that trick: Google server can do it via Google Maps web interface.
TLDR;
You don't need expand API. For example, if
https://maps.app.goo.gl/eEhh3
URL typed in the web browser on PC (e.g. FireFox) than that URL was expanded and the marker was shown. And during that you can see in address field "partially expanded" URL like:
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
which in 1-2 sec changed (redirected to) by "full expanded" URL with lat/lng coordinates like:
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
.
So you can use WebView
to do the same and get "full expanded" from it (e.g. in public void onPageFinished(WebView view, String url)
of WebViewClient
). NB: it's necessary to skip first "partially expanded" URL.
The other issue: WebView
converts shortened URL like https://maps.app.goo.gl/eEhh3
into Intent for Google Maps Application and "partially expanded" URL
https://www.google.com/maps/place//data=!4m2!3m1!1s0x391904e4af9b1e35:0xee6f3c848c9e5341?utm_source=mstt_1
never be loaded. Actually it's enough if you need just show marker. But if you need coordinates this issue can be solved if you open shortened URL https://maps.app.goo.gl/eEhh3
by HttpUrlConnection
and get redirected "partially expanded" URL via HttpUrlConnection.getURL()
or via Location
Header field after connection opened and HttpUrlConnection.getInputStream()
called. Actually, if you load all response from HttpUrlConnection
input stream as String
- you can find desired lat/lng coordinates within it by https://www.google.com/maps/preview/place
tag. Something like:
...
[[[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,
...
for your shortened URL opened via HttpUrlConnection
. IMHO better (but slightly slower) way is to pass "partially expanded" URL received from HttpUrlConnection.getURL()
into WebView
and get "full expanded" URL from its address line. So, with full source code:
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);
}
}
}
and 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>
you can get something like this:
NB! Described behavior can be changed by Google at any time.