Getting Started with Offline Pack API - Kotlin SDK

The MapTiler SDK for Kotlin provides a powerful Offline Pack API that enables downloading map regions for offline usage. This is a critical feature for navigation, hiking apps, or any scenario where internet access is unreliable.

Before you begin, ensure you have followed the Android SDK Getting Started guide to configure your project and set your API key.

Installation

Add the MapTiler SDK dependency to your build.gradle.kts file:


dependencies {
    implementation("com.maptiler.sdk:maptiler-sdk-kotlin:2.0.0")
}

View Installation Instructions

Basic usage

Implementing offline maps involves defining a region, creating an offline pack via the manager, and tracking the download progress.

Step 1: define the region

Specify the geometry (area), zoom range, and the MapTiler style you want to make available offline.


import com.maptiler.maptilersdk.offline.*
import com.maptiler.maptilersdk.map.style.MTMapReferenceStyle

// Define a bounding box (e.g., Zurich)
val bbox = MTBoundingBox(
    minLon = 8.52, minLat = 47.36,
    maxLon = 8.56, maxLat = 47.39
)

// Create the definition
val definition = MTOfflineRegionDefinition(
    geometry = MTOfflineRegionGeometry.BoundingBox(bbox),
    minZoom = 1,
    maxZoom = 12,
    referenceStyle = MTMapReferenceStyle.STREETS
)

Step 2: create the offline pack

Use the MTOfflineManager to initialize a new pack on the device.


/ In a coroutine scope
val pack = MTOfflineManager.createPack(context, definition)

Step 3: observe download progress

Set up observers in a coroutine scope.


launch {
  pack.progressFlow.collect { progress ->
    val percent = (progress.percentage * 100).toInt()
    println("Progress: $percent% (${progress.downloadedResources}/${progress.totalResources} resources)")
              
    // You can also access:
    // progress.downloadSpeed (resources/sec)
    // progress.estimatedTimeRemaining (seconds)
  }
}

// Observe state changes (DOWNLOADING, COMPLETED, FAILED, etc.)
launch {
  pack.stateFlow.collect { state ->
    when (state) {
      MTOfflinePackState.DOWNLOADING -> println("Download started...")
      MTOfflinePackState.COMPLETED -> println("Download finished successfully!")
      MTOfflinePackState.FAILED -> println("Download failed.")
      else -> println("Current state: ${state.name}")
    }
  }
}

Step 4: start the download

Trigger the download process. Using useBackground = true will offload the work to Android’s WorkManager.


pack.download(useBackground = true)

Features

Flexible Geometries

Offline regions aren’t limited to rectangles. You can define regions based on:

  • Bounding Box: A simple rectangular area.
  • Route: Download tiles along a GeoJSON route with a specific buffer.
  • Polygon: Download tiles within a custom polygon boundary.

Background Downloading

With useBackground = true, the SDK uses WorkManager to handle downloads. It automatically manages battery optimization, network changes, and device reboots.

Pack Management

Easily manage your stored maps:

  • List Packs: await MTOfflinePack.packs()
  • Resume/Pause: await pack.resume() or await pack.pause()
  • Remove: await pack.remove()

Permissons

The MapTiler SDK serves offline tiles via an internal server. To access these tiles, Android requires you to explicitly permit cleartext traffic to 127.0.0.1 and localhost. We recommend creating a dedicated Network Security Configuration to scope this permission securely.

Create res/xml/network_security_config.xml:


<?xml version="1.0" encoding="utf-8"?>
  <network-security-config>
     <domain-config cleartextTrafficPermitted="true">
         <domain includeSubdomains="false">127.0.0.1</domain>
         <domain includeSubdomains="false">localhost</domain>
     </domain-config>
 </network-security-config>

Reference it in your AndroidManifest.xml:


<application
    android:networkSecurityConfig="@xml/network_security_config"
    ... >
</application>

What to Expect

Storage: Map tiles are stored in a dedicated folder. A typical city-sized area at zoom level 12 might take 50-100MB depending on the style complexity.

Expiration: Packs have an expiration date (default is 30 days). You can use pack.refresh() to update the resources and reset the timer.

Network: The SDK automatically handles intermittent connectivity, pausing and resuming downloads as the network becomes available.

Learn more

To learn about more advanced functionalities of the SDK, refer to the API Reference.

Check out our SDK Kotlin Examples. In addition to the documentation examples take a look at the plug and play examples provided in the SDK GitHub repository, as well as pre-made demo app: maptiler-sdk-kotlin/Examples

Was this helpful?
Mobile SDK
Android
Getting Started with Offline Pack API - Kotlin SDK
Offline getting started