如何从谷歌地图扩展共享位置 URL?

Posted

技术标签:

【中文标题】如何从谷歌地图扩展共享位置 URL?【英文标题】:How to expand the shared location URL from Google Maps? 【发布时间】:2019-06-02 21:34:45 【问题描述】:

我正在尝试从谷歌地图共享位置链接获取位置,因此我使用 Google Shorten URL API 来扩展 URL,但是当我从 android 设备上的谷歌地图应用程序共享 URL 时,它给了我https://maps.app.goo.gl/eEhh3 这种网址。它没有给我提供位置信息的实际扩展 URL。

如何展开:

https://maps.app.goo.gl/eEhh3

在此链接中:

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,而是返回给我这个 长 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,以通过 Google Map 共享位置 URL 从任何设备 ios,WebAPP)获取位置 (Lat,Lng) ,特别是 Android)。

【问题讨论】:

这段代码还能用吗?我研究了 webview 行为,谷歌已经通过参数添加了重定向到 https://consent.google.com/mcontinue=google.com/maps/place... @ReijoKorhonen 不知道兄弟,但它是最通用的,所以我认为它应该可以工作 【参考方案1】:

现在(2019 年)似乎没有单独的 API 或服务用于从 Google 地图扩展共享位置 URL,但您可以使用基于该技巧的解决方法:Google 服务器可以通过 Google 地图 Web 界面执行此操作。

TLDR;

您不需要expand 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 秒内通过带有 lat/lng 坐标的“完全扩展”URL 更改(重定向到),例如:

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 执行相同操作并从中获得“完全扩展”(例如,在 WebViewClientpublic void onPageFinished(WebView view, String url) 中)。注意:有必要跳过第一个“部分扩展”的 URL。

另一个问题:WebView 将缩短的 URL(如 https://maps.app.goo.gl/eEhh3)转换为 Intent for Google Maps Application 和“部分扩展”的 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 连接打开后的标题字段和HttpUrlConnection.getInputStream() called 重定向“部分扩展” URL。实际上,如果您将来自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。恕我直言,更好(但稍慢)的方法是将接收自 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);

        // 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_
    android:layout_
    tools:context="<YOUR_PACKAGE>.MainActivity">

    <fragment
        android:id="@+id/map_fragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_
        android:layout_/>

    <WebView
        android:id="@+id/web_view"
        android:layout_
        android:layout_/>
</RelativeLayout>

你可以得到这样的东西:

注意! Google 可以随时更改所描述的行为。

【讨论】:

谢谢,我会调查你的回答。 @不客气,但请记住 - Google 可以随时更改内容。 我通过 'HttpUrlConnection' 收到此 URL https://play.google.com/store/apps/details?id=com.google.android.apps.maps&amp;pcampaignid=fdl_short&amp;url=https://www.google.com/maps/place//data%3D!4m2!3m1!1s0x15c3d01fb1137e59:0xe059579737b118db?utm_source%3Dmstt_1 而不是位置 URL 我认为谷歌方案已更改 当我在 webView 中点击此 URL 时,它总是返回相同的 URL。 @TanveerMunir 请检查WebViewhttp.agent (System.setProperty("http.agent", "");) 设置。你的网址在我这边转换为https://www.google.com/maps/place/Jeddah+Saudi+Arabia/@21.4498898,38.9309561,10z/data=!3m1!4b1!4m5!3m4!1s0x15c3d01fb1137e59:0xe059579737b118db!8m2!3d21.485811!4d39.1925048

以上是关于如何从谷歌地图扩展共享位置 URL?的主要内容,如果未能解决你的问题,请参考以下文章

如何从谷歌地图位置标记(iOS)中删除箭头?

给定两个位置,如何从谷歌地图获取所有纬度和经度

我们如何在颤振应用程序中从谷歌地图获取特定位置的照片[关闭]

如何在颤振中从谷歌地图获取位置的经纬度坐标?

如何从谷歌地图中的经纬度获取地址位置。? [关闭]

如何从谷歌地图地理编码返回地址类型?