在 getTileUrl 中为 Maps Tile Android 添加授权 header

Adding an Authorization header in getTileUrl for Maps Tile Android

我想在为 Google 地图 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;
        }
    };

由于连接returns 401 已授权,我无法访问磁贴。我如何通过授权 header 让 url 知道我有权访问这些磁贴?

你必须实现 "TileProvider" 接口,而不是 URLTileProvider(因为你必须自己检索图块,URL 是不够的。 https://developers.google.com/android/reference/com/google/android/gms/maps/model/TileProvider 如您所见,有一个注意事项:

Calls to methods in this interface might be made from multiple threads so implementations of this interface must be threadsafe.

并且您必须实现一个方法:

abstract Tile 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():