简体   繁体   中英

Google Maps offline Mode on Android Application

Is there any posibility to show Google Maps if you are offline in your own App?

What about if I download an Area FROM Google Maps application for offline mode, could i visualize the map on the app that i develop if i don't have internet connection? if not, What options do i have to make this possible? I just want to visualize the map when my app is offline...

The following its the code that this post provided TileProvider using local tiles

@Override
public Tile getTile(int x, int y, int zoom) {
        byte[] image = readTileImage(x, y, zoom);
        return image == null ? null : new Tile(TILE_WIDTH, TILE_HEIGHT,image);
}
private byte[] readTileImage(int x,int y, int zoom){
    InputStream is= null;
    ByteArrayOutputStream buffer= null;

    try{
        is= mAssets.open(getTileFileName(x,y,zoom));
        buffer= new ByteArrayOutputStream();

        int nRead;
        byte[] data= new byte[BUFFER_SIZE];

        while ((nRead= is.read(data,0,BUFFER_SIZE)) !=-1){
            buffer.write(data,0,nRead);
        }
        buffer.flush();

        return buffer.toByteArray();
    }
    catch(IOException ex){
        Log.e("LINE 60 CustomMap", ex.getMessage());
        return null;
    }catch(OutOfMemoryError e){
        Log.e("LINE 64 CustomMap", e.getMessage());
        return null;
    }finally{
        if(is!=null){
            try{
                is.close();
            } catch (IOException e) {}
        }
        if(buffer !=null){
            try{
                buffer.close();
            }catch (Exception e){}
        }
    }
}

private String getTileFileName(int x, int y, int zoom){
    return "map/"+ zoom +'/' +x+ '/'+y+".png";
}

I was looking for information, and My questions is, how can i download the tiles?

I was facing the same challenge, and none of the examples I found included a complete implementation of downloading the tiles, writing them to file and reading them from file.

This is my code, which reads the tile from file when it's available locally and downloads/saves the tile when not. This uses the OpenStreetMap.org tile server, but you could use any server you like by changing the URL.

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();
        }
    }
}

Replace "your_tiles_directory" with the path to the directory where you want to store your tiles.

To use the TileProvider:

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

Edit: You may want to set the max zoom level, the default is 21 but OpenStreetMap for example seems to have a maximum of 19.

map.setMaxZoomPreference(19);

You can download tile image from a tile server and cache on your app. Check some server on this link . Or you can build a tile as this demo , then download tile image from it.

Good luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM