Gluon Maps不会加载地图并引发异常

时间:2019-05-31 14:44:09

标签: android openstreetmap gluon-mobile

在Android上使用Gluon Maps时,不会加载实际地图。而是显示空白区域,我可以在日志中看到它:

05-31 14:20:34.041 E/CachedOsmTileRetriever(18834): null
05-31 14:20:34.041 E/CachedOsmTileRetriever(18834): java.io.FileNotFoundException: http://tile.openstreetmap.org/16/33497/22228.png
05-31 14:20:34.041 E/CachedOsmTileRetriever(18834):     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:251)
05-31 14:20:34.041 E/CachedOsmTileRetriever(18834):     at com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.doCache(CachedOsmTileRetriever.java:189)
05-31 14:20:34.041 E/CachedOsmTileRetriever(18834):     at com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.run(CachedOsmTileRetriever.java:157)

代码本身很简单:

private void showMap(Double lat, Double lon) {
    mapView = new MapView();
    PoiLayer poiLayer = new PoiLayer();
    MapPoint mapPoint = new MapPoint(lat, lon);
    poiLayer.addPoint(mapPoint, new Circle(7, Color.RED));
    mapView.setZoom(16);
    mapView.addLayer(poiLayer);
    mapView.flyTo(0.1, mapPoint, 0.1);
    tabMap.setContent(mapView);
}

相同的代码在iOS上也能正常工作:地图已按预期加载。

使用

compile 'com.gluonhq:maps:1.0.2'

在build.gradle中(与1.0.3相同)

请注意,如果我在浏览器中输入URL(来自上述例外情况),则会重定向到https:

http://tile.openstreetmap.org/16/33497/22228.pnghttps://tile.openstreetmap.org/16/33497/22228.png

任何想法为何会导致Android异常?

1 个答案:

答案 0 :(得分:1)

OpenStreetMaps服务器最近似乎有所更改。 Gluon Maps也无法在台式机上运行。

我已经用http进行了测试,但收到报告的403错误:

java.io.IOException: Server returned HTTP response code: 403 for URL: http://tile.openstreetmap.org/5/19/10.png
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1913)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
        at com.gluonhq.maps/com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.doCache(CachedOsmTileRetriever.java:190)
        at com.gluonhq.maps/com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.run(CachedOsmTileRetriever.java:157)

以及https,现在我得到了另一个错误:

java.io.IOException: Server returned HTTP response code: 429 for URL: https://tile.openstreetmap.org/6/37/22.png
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1913)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245)
        at com.gluonhq.maps/com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.doCache(CachedOsmTileRetriever.java:190)
        at com.gluonhq.maps/com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.run(CachedOsmTileRetriever.java:157)

在两种情况下(http或https),该URL在浏览器上均能正常工作,这可能表明需要向URLConnection request中添加"User-agent"

最初,这似乎解决了问题,因为不再出现http错误。但是这些瓷砖是空白的。

最后,至少在台式机上,对我来说完全有效的解决方案是:

static {
    System.setProperty("http.agent", "Gluon Mobile/1.0.3");
}

由于这是系统属性,因此可以将其添加到使用Gluon Maps的项目中,因此可以在完成新发行版以解决此issue之前对其进行测试。

Android

在Android上,您似乎需要设置有效的代理。

再次,这不是一个解决方案,但这是一个快速解决方案。

添加到您的项目,然后部署到您的Android设备:

static {
    String userAgent = System.getProperty("http.agent");
    System.out.println("HTTP.AGENT: " + userAgent);
    System.setProperty("http.agent", userAgent);
}

插入设备后,打开终端,转到Android SDK文件夹,然后键入:

cd platform-tools
adb logcat -v threadtime

现在启动应用程序,并查看控制台的输出。

就我而言,我看到:

06-10 09:57:40.784 32630 32656 I System.out: HTTP.AGENT: Dalvik/2.1.0 (Linux; U; Android 9; Pixel XL Build/PQ3A.190505.001)

这意味着Android提供了有效的代理,但是必须以某种方式对其进行显式设置。

现在已下载磁贴。

但是,一旦运行成功,我就可以从我的应用中删除这个静态块,然后重新安装它。磁贴也将下载。看起来只需要执行一次。也许OSM服务器在白名单中包含了该代理程序/设备/应用程序捆绑包/ IP,但这仅仅是一个推测。

iOS

如上所述,即使user.agent返回null,在iOS上也可以正常工作。

编辑

最后,一个适当的解决方案可能是这样:

static {
    String httpAgent = System.getProperty("http.agent");
    if (httpAgent == null) {
        httpAgent = "(" + System.getProperty("os.name") + " / " + System.getProperty("os.version") + " / " + System.getProperty("os.arch") + ")";
    }
    System.setProperty("http.agent", "Gluon Mobile/1.0.3 " + httpAgent);
}