在MapsTile Android的getTileUrl中添加Authorization标头

时间:2016-01-12 09:30:41

标签: android google-maps url http-headers

我想在为Google Maps API创建TileOverlay时访问一些自定义地图图块。

所以这是我目前的代码:

TileProvider tileProvider = new UrlTileProvider(256, 256) {
        @Override
        public URL getTileUrl(int x, int y, int z) {

            String url = String.format("https://api.mycustommaps.com/v1/%d/%d/%d.jpg", z, x, y);

            if (!checkTileExists(x, y, z)) {
                return null;
            }

            try {
                URL tileUrl = new URL(url);
                tileUrl.openConnection().addRequestProperty("Authorization", LOGIN_TOKEN);
                return tileUrl;
            } catch (MalformedURLException e) {
                e.printStackTrance();
            } catch (IOException e) {
                e.printStackTrance();
            }
            return null;
        }
    };

由于连接返回401 Anauthorized,我无法访问磁贴。我如何通过授权标题让网址知道我有权访问这些图块?

1 个答案:

答案 0 :(得分:1)

你必须实施" TileProvider"接口,而不是URLTileProvider(因为你必须自己检索磁贴,URL是不够的。 Android NDK Download 正如你所看到的,有一个值得注意的注意事项:

  

可以从多个线程调用此接口中的方法,因此此接口的实现必须是线程安全的。

你必须实现一个方法:

  

抽象瓷砖   getTile(int x,int y,int zoom)

现在您的工作下载了磁贴,我已经为本地文件完成了,所以我只是在这里写一些可能需要更多优化和测试的代码:

@Override
public Tile getTile(int x, int y, int zoom) {
  String url = String.format("https://api.mycustommaps.com/v1/%d/%d/%d.jpg", z, x, y);

  if (!checkTileExists(x, y, z)) {
     return null;
  }

  try {
    URL tileUrl = new URL(url);
    //Download the PNG as byte[], I suggest using OkHTTP library or see next code! 
    final byte[] data = downloadData(tileUrl);
    final int height = tileheight;
    final int width =  tilewidth;
    if (data != null) {
        if (BuildConfig.DEBUG)Log.d(TAG, "Cache hit for tile " + key);
           return new Tile(width, height, data);
    }
    //In this case error, maybe return a placeholder tile or TileProvider.NO_TILE

  } catch (MalformedURLException e) {
     e.printStackTrance();
  } catch (IOException e) {
       e.printStackTrance();
  }
}

下载:

byte[] downloadData(URL url){ 
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
  tileUrl.openConnection().addRequestProperty("Authorization", LOGIN_TOKEN);
  is = url.openStream();
  byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time.
  int n;

  while ( (n = is.read(byteChunk)) > 0 ) {
    baos.write(byteChunk, 0, n);
  }
}
catch (IOException e) {
  System.err.printf ("Failed while reading bytes from %s: %s", url.toExternalForm(), e.getMessage());
  e.printStackTrace ();
  // Perform any other exception handling that's appropriate.
}
finally {
  if (is != null) { is.close(); }
}
return baos.toByteArray():