Android应用程序上的Google Maps离线模式

时间:2018-02-22 23:09:01

标签: android google-maps-android-api-2

如果您在自己的应用中离线,是否有可能显示Google地图?

如果我从离线模式下载区域从谷歌地图应用程序怎么样,如果我没有网络连接,我可以在我开发的应用程序上可视化地图吗? 如果没有,我有什么选择才能实现这一目标?我只是想在我的应用离线时可视化地图...

以下是此帖子提供的代码TileProvider using local tiles

$ perl -l -00 -ape '$_ = join("," => @F)' test

我一直在寻找信息,而我的问题是,我该如何下载瓷砖?

2 个答案:

答案 0 :(得分:1)

我正面临着同样的挑战,我发现的所有示例都没有完整下载瓦片,将其写入文件以及从文件中读取的实现。

这是我的代码,它在本地可用时从文件中读取图块,而在不可用时下载/保存图块。这使用了OpenStreetMap.org磁贴服务器,但是您可以通过更改URL使用任何喜欢的服务器。

<SomeScreen>:
    BoxLayout:
        Image:
            id: img
            size_hint: None, 0.12
            width: 200
            pos_hint: {'center_y':0.5}
            allow_stretch: True
            source: 'image.png'

        ScrollView:
            id: scr
            BoxLayout:
                orientation: 'vertical'
                size_hint: 1, None
                height: self.minimum_height
                Button:
                    size_hint: None, None
                    width: 400
                    height: 200
                    on_press: print(f'image size: {img.size}, image postion {img.pos}')
                Button:
                    size_hint: None, None
                    width: 400
                    height: 200
                    on_press: print(box.size, box.pos)
                Button:
                    size_hint: None, None
                    width: 400
                    height: 200
                    on_press: print(scr.size, scr.pos)

将“ your_tiles_directory”替换为您要存储图块的目录的路径。

要使用TileProvider:

private class OfflineTileProvider implements TileProvider {
    private static final String TILES_DIR = "your_tiles_directory/";
    private static final int TILE_WIDTH = 256;
    private static final int TILE_HEIGHT = 256;

    private static final int BUFFER_SIZE_FILE = 16384;
    private static final int BUFFER_SIZE_NETWORK = 8192;

    private ConnectivityManager connectivityManager;

    @Override
    public Tile getTile(int x, int y, int z) {
        Log.d(TAG, "OfflineTileProvider.getTile(" + x + ", " + y + ", " + z + ")");
        try {
            byte[] data;
            File file = new File(TILES_DIR + z, x + "_" + y + ".png");
            if (file.exists()) {
                data = readTile(new FileInputStream(file), BUFFER_SIZE_FILE);
            } else {
                if (connectivityManager == null) {
                    connectivityManager = (ConnectivityManager) getSystemService(
                            Context.CONNECTIVITY_SERVICE);
                }
                NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
                if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
                    Log.w(TAG, "No network");
                    return NO_TILE;
                }

                Log.d(TAG, "Downloading tile");
                data = readTile(new URL("https://a.tile.openstreetmap.org/" +
                                z + "/" + x + "/" + y + ".png").openStream(),
                        BUFFER_SIZE_NETWORK);

                try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
                    out.write(data);
                }
            }
            return new Tile(TILE_WIDTH, TILE_HEIGHT, data);
        } catch (Exception ex) {
            Log.e(TAG, "Error loading tile", ex);
            return NO_TILE;
        }
    }

    private byte[] readTile(InputStream in, int bufferSize) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try {
            int i;
            byte[] data = new byte[bufferSize];

            while ((i = in.read(data, 0, bufferSize)) != -1) {
                buffer.write(data, 0, i);
            }
            buffer.flush();

            return buffer.toByteArray();
        } finally {
            in.close();
            buffer.close();
        }
    }
}

编辑:您可能想要设置最大缩放级别,默认值为21,但是例如OpenStreetMap似乎最大为19。

map.setMapType(GoogleMap.MAP_TYPE_NONE);
offlineTileOverlay = map.addTileOverlay(new TileOverlayOptions()
                .tileProvider(new OfflineTileProvider()));

答案 1 :(得分:0)

您可以从平铺服务器下载平铺图像并在应用上缓存。检查此link上的某个服务器。或者您可以将图块构建为this demo,然后从中下载图块。

祝你好运