Learn how to display a map from a mobile map package (MMPK).
In this tutorial you will display a fully interactive map from a mobile map package (MMPK). The map contains a basemap layer and data layers and does not require a network connection.
Prerequisites
Before starting this tutorial:
-
You need an ArcGIS Location Platform or ArcGIS Online account.
-
A development and deployment environment that meets the system requirements.
-
An IDE for Android development in Kotlin.
Steps
In this tutorial, you will first code, build, and install the app on a device, and then add the Mahou
.
Open an Android Studio project
-
To start this tutorial, complete the Display a map tutorial. Or download and unzip the Display a map solution in a new folder.
-
Modify the old project for use in this new tutorial. Expand More info for instructions.
-
On your file system, delete the .idea folder, if present, at the top level of your project.
-
In the Android tool window, open app > res > values > strings.xml.
In the
<string name="app
element, change the text content to Display a map from a mobile map package._name" > strings.xmlUse dark colors for code blocks <resources> <string name="app_name">Display a map from a mobile map package</string> </resources>
-
In the Android tool window, open Gradle Scripts > settings.gradle.kts.
Change the value of
root
to "Display a map from a mobile map package".Project.name settings.gradle.ktsUse dark colors for code blocks dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() maven { url = uri("https://esri.jfrog.io/artifactory/arcgis") } } } rootProject.name = "Display a map from a mobile map package" include(":app")
-
The UI theme composable in Display a map tutorial was
Display
. Rename the theme composable throughout the tutorial by refactoringA Map Theme Display
.A Map Theme In the Android tool window, open app > kotlin+java > com.exmple.app > ui.theme > Theme.kt.
Right-click the function name
Display
and select Refactor -> Rename. Replace the name withA Map Theme Display
.A Map From A Mobile Map Package Theme Theme.ktUse dark colors for code blocks Copy @Composable fun DisplayAMapTheme( darkTheme: Boolean = isSystemInDarkTheme(), // Dynamic color is available on Android 12+ dynamicColor: Boolean = true, content: @Composable () -> Unit ) { val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } darkTheme -> DarkColorScheme else -> LightColorScheme }
-
Click File > Sync Project with Gradle files. Android Studio will recognize your changes and create a new .idea folder.
-
Add import statements
-
In the Android tool window, open app > kotlin+java > com.example.app > MainScreen.kt. Replace the import statements with the imports needed for this tutorial.
MainScreen.ktUse dark colors for code blocks @file:OptIn(ExperimentalMaterial3Api::class) package com.example.app.screens import android.content.Context import android.widget.Toast import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.arcgismaps.mapping.ArcGISMap import com.arcgismaps.mapping.BasemapStyle import com.arcgismaps.mapping.MobileMapPackage import com.arcgismaps.toolkit.geoviewcompose.MapView import com.example.app.R import java.io.File
Loading mobile map package and displaying a map
Code the app to select a map from the maps contained in a mobile map package and display the map in a map view. Use the MobileMapPackage
class to access the mobile map package and load it to read its contents.
-
In the Android tool window, open app > res > values > strings.xml. Add a string resource that specifies the file name of the mobile map package.
strings.xmlUse dark colors for code blocks <resources> <string name="app_name">Display a map from a mobile map package</string> <string name="mahourivieratrails_mmpk">MahouRivieraTrails.mmpk</string> </resources>
-
In the Android tool window, open app > kotlin+java > com.example.app > screens > MainScreen.kt. Find the
create
function and delete it.Map() MainScreen.ktUse dark colors for code blocks fun createMap(): ArcGISMap { return ArcGISMap(BasemapStyle.ArcGISTopographic).apply { initialViewpoint = Viewpoint( latitude = 34.0270, longitude = -118.8050, scale = 72000.0 ) } }
-
Get the local
Context
and assign it to a variable namedcontext
. Then specify the file path where the mobile map package will be stored, and assign it to a variable namedmmpk
, which is a string.File Path MainScreen.ktUse dark colors for code blocks @Composable fun MainScreen() { val context = LocalContext.current // Get the path of the mobile map package val mmpkFilePath = context.getExternalFilesDir(null)?.path + File.separator + stringResource(id = R.string.mahourivieratrails_mmpk) // Create the ArcGIS Map which would use the map provided by the map package val map = remember { mutableStateOf(ArcGISMap(BasemapStyle.ArcGISTopographic)) } Scaffold( topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) } ) { // Display map when the mobile map package is loaded MapView( modifier = Modifier.fillMaxSize().padding(it), arcGISMap = map.value ) } }
-
Inside the
remember
block, replace thecreate
call with a mutable state holding a nullableMap() ArcGISMap
object. Then, inMapView
, assign themap
state value to thearc
property.GIS Map MainScreen.ktUse dark colors for code blocks @Composable fun MainScreen() { val context = LocalContext.current // Get the path of the mobile map package val mmpkFilePath = context.getExternalFilesDir(null)?.path + File.separator + stringResource(id = R.string.mahourivieratrails_mmpk) // Create the ArcGIS Map which would use the map provided by the map package val map = remember { mutableStateOf(ArcGISMap(BasemapStyle.ArcGISTopographic)) } Scaffold( topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) } ) { // Display map when the mobile map package is loaded MapView( modifier = Modifier.fillMaxSize().padding(it), arcGISMap = map.value ) } }
-
Call the
Launched
composable. In theEffect Launched
block, load the mobile map package.Effect If the mobile map package loaded successfully, get the first map stored in the mobile map package and assign it to the map state value. If the mobile map package failed to load, create a top-level
show
function and call it.Error() MainScreen.ktUse dark colors for code blocks @Composable fun MainScreen() { val context = LocalContext.current // Get the path of the mobile map package val mmpkFilePath = context.getExternalFilesDir(null)?.path + File.separator + stringResource(id = R.string.mahourivieratrails_mmpk) // Create the ArcGIS Map which would use the map provided by the map package val map = remember { mutableStateOf(ArcGISMap(BasemapStyle.ArcGISTopographic)) } LaunchedEffect(Unit) { // Load the mobile map package val mapPackage = MobileMapPackage(mmpkFilePath) mapPackage.load().onSuccess { map.value = mapPackage.maps.first() }.onFailure { error -> showError(context, "Failed to load mobile map package: ${error.message}") } } Scaffold( topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) } ) { // Display map when the mobile map package is loaded MapView( modifier = Modifier.fillMaxSize().padding(it), arcGISMap = map.value ) } } fun showError(context: Context, message: String) { Toast.makeText(context, message, Toast.LENGTH_LONG).show() }
Build and install your app
This is a necessary step, because the app install process creates the path (sdcard > Android > data > com.example.app > files) where you will upload your mobile map package to the device. Do not try to create the path manually in Device Explorer, as you will get a Operation not permitted error.
-
Click Run > Run > app to run the app.
In Android Studio, you have two choices for running your app: an actual Android device or the Android Emulator.
Android device
Connect your computer to your Android device, using USB or Wi-Fi. For more details, see How to connect your Android device.
Android Emulator
Create an AVD (Android Virtual Device) to run in the Android Emulator. For details, see Run apps on the Android Emulator.
Selecting a device
When you build and run an app in Android Studio, you must first select a device. From the Android Studio toolbar, you can access the drop-down list of your currently available devices, both virtual and physical.
.
If you cannot access the list on the toolbar, click Tools > Device Manager.
Your app will be built and installed on the Android Virtual Device (AVD) that is currently selected in the Android Studio toolbar. On the AVD, you should see an
ArcGISTopographic
map with initial extent of the whole world. You should also see the app name Display a map from a mobile map package at the top of the screen, and the message Failed to load mobile map package: File not found. briefly displayed at the bottom. This is expected.Next you will add the mobile map package.
Add a mobile map package using Device Explorer
Add a mobile map package (.mmpk) to the device file system for use by your app.
-
On your development computer, create or download the
Mahou
mobile map package. Either complete the Create a mobile map package tutorial to create the package yourself, or download theRiviera Trails.mmpk Mahou
mobile map package from ArcGIS Online.Riviera Trails.mmpk -
In Android Studio, verify that your Android Virtual Device (AVD) is still connected. If it is not, expand More info below.
If you already closed the AVD on which you installed your app, then launch the Android Emulator manually.
- Click Tools > Device Manager. In the Device Manager, click the triangle icon (Start button) on the AVD you used before.
-
Display the Device Explorer tool window, which shows the file system on your AVD. Click View > Tool Windows > Device Explorer and wait until Device Manager connects to your AVD and shows the file system tree.
-
Upload the MahouRivieraTrails.mmpk file from your development computer.
-
In Device Explorer, right-click on the sdcard > Android > data directory and click Synchronize.
-
Right-click on sdcard > Android > data > com.example.app > files and click Upload. Navigate to the MahouRivieraTrails.mmpk file on your development computer. Then click OK.
You should see a Device Explorer Toast in the lower corner confirming success.
-
Restart the app on your AVD
-
Shut down the app running on your AVD. Clicking Run > Stop 'app' in Android Studio is the quickest way to stop the app.
-
Run the app a second time by clicking Run > Run > app.
You will see a map of trailheads, trails, and parks for the area south of the Santa Monica mountains. You can pinch (to zoom and rotate), drag, and double-tap the map view to explore the map.
What's next?
Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: