Offline maps

The MapKit SDK downloads maps over the internet so they can be shown on user devices. Using an offline caching process, the MapKit SDK downloads maps in advance so they can be used later when there's no internet connection.

The MapKit SDK's offline mode comes with the following features:

  • Displaying map tiles.
  • Building routes for cars (without traffic data).
  • Geosuggest and search.

Regions

In the MapKit SDK, maps are divided into regions, each of which is associated with a set of data you can download and cache offline.

Regions can be:

  • City regions that include multiple localities (Jizan Region, Najran Region).
  • Countries (Azerbaijan, Israel).

In the MapKit SDK, regions are described by a Region class and provide the following data:

  • id: The region's unique ID.

  • name: The region's name.

  • center: The coordinates of the region center.

  • size: The download size of the region (in bytes).

  • releaseTime: The timestamp for when offline maps for this region were last updated on the server.

  • parentId: The ID of the parent region. For example, Al Baha as the parent region contains Al Bahah Region.

Getting a list of regions

The OfflineCacheManager class is the entry point for the offline cache management API. An instance of this class is stored as a singleton in the MapKit SDK. To get it, use the MapKit.getOfflineCacheManager method.

val offlineCacheManager = MapKitFactory.getInstance().offlineCacheManager

To get the list of all available regions, use the subscription to the region list update event in the RegionListUpdatesListener interface.

val listener = RegionListUpdatesListener {
    val regions = offlineCacheManager.regions()
    // Handle regions update
}

offlineCacheManager.addRegionListUpdatesListener(listener)

You can get a list of updated regions using the OfflineCacheManager.regions method.

Region state

Region states are described by the RegionState list:

  • available: The region's offline maps are available for download.
  • downloading: Offline maps are being downloaded.
  • paused: The download was paused and can be resumed.
  • completed: The data is downloaded.
  • outdated: The server has an updated version of the offline maps for this region.
  • unsupported: The offline maps of the region are downloaded but no longer supported. If they are deleted from the device, the region will no longer be available for download.
  • need_update: Data outdated, download the new version.

To get the current state for a particular region, use the OfflineCacheManager.getState method.

You can use the MapKit SDK to subscribe to region state change events in the RegionListener interface. There are two options:

  1. RegionListener.onRegionStateChanged: A particular region's state change.
  2. RegionListener.onRegionProgress: A state change for a region's offline map.
val regionListener = object : RegionListener {
    override fun onRegionStateChanged(regionId: Int) {
        val state = offlineCacheManager.getState(regionId)
        // Handle region state changes
    }

    override fun onRegionProgress(regionId: Int) {
        val progress = offlineCacheManager.getProgress(regionId)
        // Handle region progress changes
    }
}

offlineCacheManager.addRegionListener(regionListener)

Additional information about regions

You can get additional information about regions using the following methods:

Downloading maps

The MapKit SDK provides the following methods for managing the download state of a region's offline maps.

Tip

Before downloading, use the OfflineCacheManager.mayBeOutOfAvailableSpace method to make sure there's enough free space on the device.

All methods for managing offline map download states take a single argument: the ID of the region the action applies to. The region state may change when a method is executed. For example, if a region is available for download, the download starts after calling the OfflineCacheManager.startDownload method, and the region's state changes to downloading.

Downloading properties

These methods let you configure offline map download properties:

Error handling

Offline map data is downloaded from the server, and offline caches are saved to the device. The OfflineCacheManager.ErrorListener interface is used to handle errors that may appear in the process.

val listener = object : ErrorListener {
    override fun onError(error: Error) {
        when (error) {
            is LocalError -> {
                // Handle local error
            }
            is RemoteError -> {
                // Handle remote error
            }
            else -> { // Undefined error }
        }
    }

    override fun onRegionError(error: Error, regionId: Int) {
        // Handle error for region with regionId id
    }
}

This interface provides methods for handling errors related to downloading particular regions and OfflineCacheManager.

There are two types of errors:

  • LocalError: Errors on the user's device, such as a damaged disk or insufficient space.
  • RemoteError: Errors on the server side.

Storing offline caches

The MapKit SDK saves maps downloaded to the device's disk in a special offline cache format.

To get the path for the offline cache storage in the file system, the OfflineCacheManager.requestPath method is used.

offlineCacheManager.requestPath { path ->
    // Handle requested path
}

This method takes the OfflineCacheManager.PathGetterListener interface used to subscribe to the event where the path is obtained as an argument.

The cache storage on the device may be changed. There are two methods used for that:

  1. OfflineCacheManager.setCachePath: Used to change the location of cached data on the user's device. If there are already caches stored at the path set, they will be used, with new caches initiated otherwise.
  2. OfflineCacheManager.moveData: Moves current caches to a new location on the device.

The OfflineCacheManager.computeCacheSize method calculates how much memory all caches are taking up on the user's device.

The OfflineCacheManager.clear method is used to delete caches.

Source code

As an example of using the offline maps API functionality, see the map-offline app in our GitHub repository.