Download maps for offline use
An offline pack holds the resources needed to show a region without a network:
map tiles, the style, and other assets. The OfflineManager
creates, tracks, and deletes packs.
Get the manager inside a composition:
val offlineManager = rememberOfflineManager()Download a region
Section titled “Download a region”A pack is defined by a style URL, a bounding box, and a zoom range.
OfflineManager.create registers the pack in a paused state; call
OfflineManager.resume to start the download:
Button( onClick = { scope.launch { val pack = offlineManager.create( definition = OfflinePackDefinition.TilePyramid( styleUrl = "https://tiles.openfreemap.org/styles/liberty", bounds = BoundingBox(west = -123.0, south = 47.0, east = -122.0, north = 48.0), minZoom = 10, maxZoom = 14, ), metadata = "Seattle".encodeToByteArray(), ) offlineManager.resume(pack) } }) { Text("Download Seattle")}The library does not interpret the metadata bytes. Use them to identify the
pack later, for example with a display name.
OfflinePackDefinition.Shape downloads the region that covers a
GeoJSON geometry instead of a bounding box.
Track download progress
Section titled “Track download progress”OfflineManager.packs and OfflinePack.downloadProgress
are backed by Compose state, so a composition that reads them recomposes as
the download proceeds:
for (pack in offlineManager.packs) { val name = pack.metadata?.decodeToString() ?: "Unnamed" when (val progress = pack.downloadProgress) { is DownloadProgress.Healthy -> Text("$name: ${progress.completedResourceCount} resources, ${progress.status}") is DownloadProgress.Error -> Text("$name: ${progress.message}") is DownloadProgress.TileLimitExceeded -> Text("$name: tile limit ${progress.limit}") is DownloadProgress.Unknown -> Text("$name: waiting for status") }}pause and resume switch a pack between the Paused and Downloading
states. OfflineManager.invalidate re-checks a pack’s tiles
against the server and updates the ones that changed.
Delete a pack
Section titled “Delete a pack”OfflineManager.delete unregisters the pack and frees the
resources that no remaining pack requires:
for (pack in offlineManager.packs) { Button(onClick = { scope.launch { offlineManager.delete(pack) } }) { Text("Delete ${pack.metadata?.decodeToString()}") }}Once a pack is downloaded, the map uses its resources automatically when the device has no network. No map configuration is required.