如何从 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。

另一个问题:WebViewhttps://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 可以随时更改所描述的行为。