Offline service
Mapbox offline service provides routing functionality from the Navigation SDK in non-connected environments. In areas of no cellular connectivity, or on a device with no SIM card, end users can use turn-by-turn navigation and request new routes. If they go off-route, the system can reroute and keep them headed to their destination without requiring network connectivity. Offline routing moves the routing engine and the routing data from the server onto the end user’s device, so there’s no need to make HTTP API calls for routing information.
Offline maps and offline routing
With Mapbox offline service, you specify geographic bounds, a region, and download an offline pack. Offline packs may include map data, navigation data, or both. You specify which kind of data to include when creating a region using the region configuration object. Offline map data includes all map tiles for the specified region. Offline navigation data will allow you to generate routes that fall within the bounds of the specified region.
Integrate offline service in your app
Offline service allows querying the server for available offline regions, as well as downloading offline packs to a disk. Observers attached to this object get notified when the status of an offline pack changes (including when a new one is downloaded).
Integrating offline service in your app involves a few steps:
Grant permissions to access file storage
You must have permission to save files. For example:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Create a token with offline secret scope
To test the Navigation SDK's offline routing feature, you need a token with offline:read
and offline:write
secret scopes. You can create a new token with these scopes on your Tokens page.
Initialize OfflineService
instance
OfflineService
is a singleton class. To initialize it you need a path to a cache directory where tiles will be stored and a OfflineServiceOptions
object.
To build OfflineServiceOptions
you need to provide a username
and token
. You can also choose to include an optional URL
. If a URL
is not included, it will use the default URL
, https://api.mapbox.com
.
OfflineServiceOptions options = new OfflineServiceOptions("username", "token", "url");
File packsDir = new File(context.getFilesDir(), "OfflineRegions");
OfflineService.getInstance(packsDir.getAbsolutePath(), options);
val options = OfflineServiceOptions("username", "token", "url")
val packsDir = File(androidContext().filesDir, "OfflineRegions")
OfflineService.getInstance(packsDir.absolutePath, options)
Manage offline regions
You will need to use both the Offline Data API and Navigation SDK to manage offline regions used in your mobile application. The Navigation SDK allows read-only access to offline packs meaning you can only list available regions, download regions, and observe changes to the state of the region. To create new regions that are available for download or update existing regions you must use the Offline Data API directly.
Create offline regions
Before fetching offline regions via the Navigation SDK, you need create them for each area by calling the Offline Data API directly. Read more about creating offline regions in the Offline Data API documentation.
Check available regions
You can list all available regions with offlineService.listAvailableRegions(OfflineServiceListAvailableRegionsCallback callback)
.
It will return Expected<List<OfflineDataRegionMetadata>, OfflineDataError>
offlineService.listAvailableRegions(response -> {
if (response.isError()) {
// handle error
} else if (response.isValue()) {
// handle list
}
});
offlineService.listAvailableRegions { result ->
when {
result.isError -> {
// handle error
}
result.isValue -> {
// handle list
}
}
}
Download offline region
Download a region with offlineService.downloadPack(OfflineDataDomain domain, OfflineDataRegionMetadata metadata)
.
If a pack with the same metadata is already being downloaded, nothing will happen. If the metadata is different, that download will be canceled, and a new download will be started. If the downloaded pack with this metadata is already complete, a new download will be started if the revision is different.
Cancel download with offlineService.cancelPackDownload(OfflineDataDomain domain, OfflineDataRegionMetadata metadata)
.
Delete offline region
Delete pack with offlineService.deletePack(OfflineDataDomain domain, OfflineDataRegionMetadata metadata)
.
This cancels active region downloads and deletes existing regions with this id.
Observe region state
You can add an observer that gets events as the state of a region changes with OfflineService.registerObserver(OfflineServiceObserver observer)
.
To stop listening use OfflineService.unregisterObserver(OfflineServiceObserver observer)
OfflineServiceObserver offlineServiceObserver = new OfflineServiceObserver() {
@Override
public void onPending(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onDownloading(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onIncomplete(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onVerifying(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onAvailable(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onExpired(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onErrored(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack) {
}
@Override
public void onDeleting(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata, @NonNull OfflineDataPack pack, @NonNull OfflineDataPackAcknowledgeCallback callback) {
}
@Override
public void onDeleted(@NonNull OfflineDataDomain domain, @NonNull OfflineDataRegionMetadata metadata) {
}
@Override
public void onInitialized() {
}
@Override
public void onIdle() {
}
@Override
public void onLogMessage(@NonNull String message) {
}
};
OfflineService.registerObserver(offlineServiceObserver);
val offlineServiceObserver: OfflineServiceObserver = object : OfflineServiceObserver() {
override fun onPending(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onDownloading(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onIncomplete(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onVerifying(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onAvailable(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onExpired(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onErrored(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack) {
}
override fun onDeleting(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata, pack: OfflineDataPack, callback: OfflineDataPackAcknowledgeCallback) {
}
override fun onDeleted(domain: OfflineDataDomain, metadata: OfflineDataRegionMetadata) {
}
override fun onInitialized() {
}
override fun onIdle() {
}
override fun onLogMessage(message: String) {
}
}
OfflineService.registerObserver(offlineServiceObserver)
OfflineServiceObserver
has the next callbacks:
onPending
: The offline pack is marked for downloading, but it has not yet begun. Check thedownloaded_size
field against the pack metadata'ssize
to compute progress. The file on disk is unusable while pending.onDownloading
: The download is in progress. Check thedownloaded_size
field against the pack metadata'ssize
to compute progress. The file on disk is unusable while downloading.onIncomplete
: The download is incomplete, and not scheduled to be downloaded. Check thedownloaded_size
field against the pack metadata'ssize
to compute progress. The file on disk is unusable.onVerifying
: The download is complete, but not yet usable. Verification of the download is in progress.onAvailable
: The offline pack is complete and the file on disk is usable.onExpired
: The offline pack is expired and can't be used until it is refreshed. The file on disk must not be used.onErrored
: The download failed or is unusable. Check theerror
field for a more detailed status code. The file on disk is unusable.onDeleting
: The download is marked for deleting. Code that is using the file should stop using it as soon as possible and once finished, acknowledge receipt of this status update. Offline packs in this state should no longer be accessible to the user and code shouldn't depend on them.onDeleted
: The download has been deleted.onInitialized
: All offline regions that have been downloaded to disk are initialized.onIdle
: There are no operations in progress.onLogMessage
: There is a new log message.