【问题标题】:Gluon Maps doesn't load the map and throws an exceptionGluon Maps 不加载地图并引发异常
【发布时间】:2019-05-31 14:44:08
【问题描述】:

在 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 上出现异常?

【问题讨论】:

  • 您能否调试您的网络流量以查看来自网络服务器的实际答案? IE。错误代码和错误信息。也许您的请求无效,例如,如果它不包含有效的 HTTP 用户代理。详情请见operations.osmfoundation.org/policies/tiles
  • 另请参阅 OSM 开发人员列表中有关错误代码 403 的当前讨论:lists.openstreetmap.org/pipermail/dev/2019-May/030629.html
  • “我的”请求是什么意思?我自己没有写任何请求,它应该封装在 Gluon Maps 代码中。另请注意,在 iOS 上一切正常。虽然我会看看我是否能得到网络服务器的响应。
  • 我指的是您的应用正在发送的 HTTP 请求,而不管负责创建/发送它的确切代码部分。
  • java.io.IOException:服务器返回 HTTP 响应代码:403 用于 URL:tile.openstreetmap.org/16/39610/20480.png 在 sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894) 在 sun .net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) 在 com.gluonhq.impl.maps.tile.osm.CachedOsmTileRetriever$CacheThread.doCache(CachedOsmTileRetriever.java:189) 在 com.gluonhq.impl .maps.tile.osm.CachedOsmTileRetriever$CacheThread.run(CachedOsmTileRetriever.java:157)

标签: android openstreetmap gluon-mobile


【解决方案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 在浏览器上都可以正常工作,这可能表明需要将 "User-agent" 添加到 URLConnection request

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

最后,至少在桌面上完全适合我的解决方案是这个:

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

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

安卓

在 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

如前所述,在 iOS 上它工作得很好,即使 user.agent 返回 null。

编辑

最后,一个合适的解决方案可以是:

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);
}

【讨论】:

  • 抱歉,伪装用户代理是个坏主意。这个应用程序似乎违反了OSM's tile usage policy。 OSM 服务器完全在捐赠的资源上运行。请更新您的答案并设置一个指向 Gluon Maps 而不是 Mozilla 的有效用户代理。
  • @scai 抱歉,用户代理名称无效,我已经编辑了答案,并进行了适当的修复。希望您能重新考虑否决票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2014-06-01
  • 1970-01-01
  • 2022-01-10
  • 2014-06-13
  • 1970-01-01
相关资源
最近更新 更多