You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Google Maps API本地TileOverlay不显示,如何生成Asset有效URL?

解决Android Google Maps TileOverlay加载本地Assets瓦片的问题

这个问题我之前也碰到过!UrlTileProvider确实没法直接识别file:///android_asset的URL,因为这个URL scheme是Android WebView特有的解析规则,Google Maps的TileProvider并不支持。咱们换个思路,直接从Assets里读取瓦片文件的字节流来创建Tile就行,具体步骤如下:

1. 自定义AssetTileProvider类

不用继承UrlTileProvider,直接实现TileProvider接口,通过AssetManager读取assets目录下的瓦片文件:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import com.google.android.gms.maps.model.Tile;
import com.google.android.gms.maps.model.TileProvider;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class AssetTileProvider implements TileProvider {
    private static final int TILE_SIZE = 256;
    private final Context mContext;

    public AssetTileProvider(Context context) {
        mContext = context;
    }

    @Override
    public Tile getTile(int x, int y, int zoom) {
        // 注意:如果你的瓦片是标准TMS坐标系生成的,需要翻转y轴
        // y = (1 << zoom) - 1 - y;
        String tilePath = "tiles/" + x + "-" + y + "-" + zoom + ".png";
        InputStream inputStream = null;
        try {
            inputStream = mContext.getAssets().open(tilePath);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            if (bitmap != null) {
                byte[] tileData = bitmapToByteArray(bitmap);
                return new Tile(TILE_SIZE, TILE_SIZE, tileData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 文件不存在或读取失败时返回空瓦片
        return NO_TILE;
    }

    private byte[] bitmapToByteArray(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        bitmap.recycle();
        return byteArray;
    }
}

2. 在onMapReady中使用自定义TileProvider

替换原来的UrlTileProvider,换成我们的AssetTileProvider:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    TileProvider tileProvider = new AssetTileProvider(this);
    TileOverlay tileOverlay = mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
}

关键注意点

  • 坐标系适配:如果你的瓦片是用标准TMS工具生成的,Google Maps的y轴坐标系是翻转的,需要在getTile方法里添加y = (1 << zoom) - 1 - y的转换,否则瓦片位置会出错。
  • 瓦片尺寸:确保你的PNG瓦片是256x256像素,和代码里的TILE_SIZE保持一致。
  • 异常处理:代码里已经处理了文件不存在的情况,返回NO_TILE会让Google Maps跳过该瓦片,避免应用崩溃。

这样修改后,就能直接从Assets目录加载本地瓦片,完全不需要联网也能正常显示TileOverlay了!

内容的提问来源于stack exchange,提问作者remjln

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:41:25