Download A Map
In this guide you will learn how to get a list of the available country and region maps on the server and how to download a map for offline use.
Setup
- Get your Magic Lane API key token: if you do not have a token, see the Getting Started guide.
- Download the Maps & Navigation SDK for Android archive file.
- Download the DownloadingOnboardMap project archive file or clone the project with git.
- See the Configure Android Example guide.
Run the example
In Android Studio, from the File
menu, select Sync Project with Gradle Files
.
An android device should be connected via USB cable. Press SHIFT+F10 to compile, install and run the example on the android device.



Displays a list of maps on the server available for download. Automatically downloads a map.
How it works
You can open the MainActivity.kt file to see how the list of maps is obtained from the server and displayed, and then one of the maps is downloaded.
private val progressListener = ProgressListener.create(
onStarted = {
progressBar?.visibility = View.VISIBLE
showStatusMessage("Started content store service.")
},
onCompleted = { errorCode, _ ->
progressBar?.visibility = View.GONE
showStatusMessage("Content store service completed with error code: $errorCode")
when (errorCode)
{
GemError.NoError ->
{
SdkCall.execute {
// No error encountered, we can handle the results.
val models = contentStore.getStoreContentList(EContentType.RoadMap)?.first
if (!models.isNullOrEmpty())
{
// The map items list is not empty or null.
val mapItem = models[0]
val itemName = mapItem.name
// Define a listener to the progress of the map download action.
val downloadProgressListener = ProgressListener.create(onStarted = {
showStatusMessage("Started downloading $itemName.")
},
onProgress = {
listView?.adapter?.notifyItemChanged(0)
},
onCompleted = { _, _ ->
listView?.adapter?.notifyItemChanged(0)
showStatusMessage("$itemName was downloaded.")
})
// Start downloading the first map item.
SdkCall.execute {
mapItem.asyncDownload(downloadProgressListener,
GemSdk.EDataSavePolicy.UseDefault, true)
}
}
displayList(models)
}
}
GemError.Cancel ->
{
// The action was cancelled.
}
else ->
{
// There was a problem at retrieving the content store items.
showDialog("Content store service error: ${GemError.getMessage(errorCode)}")
}
}
}
)
This is the progressListener
used to monitor the progress of obtaining the list of maps available for download from the online content store server.
onStarted
is called when the map list download starts, and onCompleted
is called when the map list download is complete.
Once the map list is downloaded, the array of roadmaps is obtained from the downloaded local copy of the map list:
val models = contentStore.getStoreContentList(EContentType.RoadMap)?.first
If the array is not empty, the first item (at index 0) is obtained:
val mapItem = models[0]
A progress listener is created right here:
val downloadProgressListener = ProgressListener.create(onStarted = {
overriding onProgress
and onCompleted
. Then the download is started, and the progress listener just defined is used to monitor the progress of downloading the map at index 0 in the list of maps.
The downloaded map is stored on the device in a directory such as this: /sdcard/Android/data/com.magiclane.examplename/files/Data/Maps/
.
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
progressBar = findViewById(R.id.progressBar)
statusText = findViewById(R.id.status_text)
listView = findViewById<RecyclerView?>(R.id.list_view).apply {
layoutManager = LinearLayoutManager(this@MainActivity)
val separator = DividerItemDecoration(applicationContext, (layoutManager as LinearLayoutManager).orientation)
addItemDecoration(separator)
val lateralPadding = resources.getDimension(R.dimen.bigPadding).toInt()
setPadding(lateralPadding, 0, lateralPadding, 0)
itemAnimator = null
}
val loadMaps = {
mapsCatalogRequested = true
val loadMapsCatalog = {
SdkCall.execute {
// Call to the content store to asynchronously retrieve the list of maps.
contentStore.asyncGetStoreContentList(EContentType.RoadMap, progressListener)
}
}
val token = GemSdk.getTokenFromManifest(this)
if (!token.isNullOrEmpty() && (token != kDefaultToken))
{
loadMapsCatalog()
}
else
// if token is not present try to avoid content server requests limitation
// by delaying the request
{
progressBar?.visibility = View.VISIBLE
Handler(Looper.getMainLooper()).postDelayed({
loadMapsCatalog()
}, 3000)
}
}
SdkSettings.onMapDataReady = { it ->
mapReady = it
if (connected && mapReady && !mapsCatalogRequested)
{
loadMaps()
}
}
SdkSettings.onConnectionStatusUpdated = { it ->
connected = it
if (connected && mapReady && !mapsCatalogRequested)
{
loadMaps()
}
}
SdkSettings.onApiTokenRejected = {
showDialog("TOKEN REJECTED")
}
// This initialization step is mandatory for using the SDK without a map.
if (!GemSdk.initSdkWithDefaults(this))
{
// The SDK initialization was not completed.
finish()
}
if (!Util.isInternetConnected(this))
{
showDialog("You must be connected to internet!")
}
}
MainActivity
overrides onCreate()
which checks that internet access is available, and explicitly initializes the SDK, which is required for enabling use of the SDK without a map: GemSdk.initSdkWithDefaults(this))
When the internet connection is detected, or when the SDK reports that map data is ready, the loadMaps()
function is called to request the list of maps from the content store server.
contentStore.asyncGetStoreContentList(EContentType.RoadMap, progressListener)
The list of maps is requested, and the progressListener
shown above is passed in, to get notified when the list of maps has finished downloading. At that point, as we have already seen above, the progress listener automatically selects the first map (unless the list is empty) and downloads it automatically.
In a real world use case, the user would select which map to download.
private fun displayList(models: ArrayList<ContentStoreItem>?)
{
if (models != null)
{
val adapter = CustomAdapter(models)
listView?.adapter = adapter
}
}
The progress listener also calls displayList(models)
which uses a CustomAdapter
to display a scrollable list of the maps available on the server. The list displayed is the local copy that was downloaded above.
Android Examples
Maps SDK for Android Examples can be downloaded or cloned with Git.