在 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():
我想在为 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():