ArcGIS Maps SDK for Kotlin offers a toolkit, ArcGIS Maps SDK for Kotlin Toolkit, that contains composable UI components to help simplify your Android development work. For information on how Android Jetpack Compose works, see Get started with Jetpack Compose.
The GeoView-Compose module has composable components to display maps and scenes. Most apps that use Android Jetpack Compose will need this module.
- GeoView-Compose - Contains the composable components
MapViewandSceneView, which are wrappers for theMapViewandSceneViewclasses in the Kotlin Maps SDK API.
The Toolkit contains other, special-purpose composable components:
- Augmented Reality - FlyoverSceneView - Allows you to explore a scene using your device as a window into the virtual world.
- Augmented Reality - TableTopSceneView - Allows you to anchor scene content to a physical surface, as if it were a 3D-printed model.
- Augmented Reality - WorldScaleSceneView - Allows you to integrate scene content with the real world features like streets and buildings.
- Authenticator - Displays a user interface when network and ArcGIS authentication challenges occur.
- BasemapGallery - Provides a control for selecting basemaps.
- Compass - Shows a compass direction when the map is rotated. Auto-hides when the map points north.
- FeatureForm - Enables users to edit field values of a feature using pre-configured forms.
- FloorFilter - Allows filtering of floor plan data in a GeoView by a site, a facility in the site, or a floor in the facility.
- GeoView-Compose Callout - Draws a callout on the GeoView to display Composable content.
- GeoView-Compose OverviewMap - Displays the visible extent of a GeoView in a small “inset” map.
- Legend - Displays a legend for a map or a scene.
- OfflineMapAreas - Allows you to take a web map offline by downloading map areas.
- Popup - View field values of features in a layer using the Popup API.
- Scalebar - Displays current scale reference.
- UtilityNetworkTrace - Configure, run, and visualize UtilityNetworkTraces on a composable MapView.
The fastest way to get the toolkit into your app is to reference the compiled library (.aar file) from Jfrog, as described below. For instructions on using the toolkit from source code — for example, if you want to customize it — see Developer setup in the toolkit’s repo.
Enhancements in 200.8.0
Authenticator
The Authenticator toolkit component now supports Identity-Aware Proxy (IAP) Sign-in and Sign-out. This works out of the box when there’s an IapConfiguration set on the AuthenticatorState.IapConfigurations property.
As part of adding support for IAP several updates were made to the Toolkit Authenticator which include deprecations and new recommendations:
-
Deprecated: The
Authenticatorcomposable that uses theonPendingOAuthUserSignInlambda.- Recommended: Use the updated
Authenticatorcomposable that accepts aonPendingBrowserAuthenticationChallenge: (BrowserAuthenticationChallenge) -> Unitlambda. BrowserAuthenticationChallengeis a wrapper around sign-in/out objects such asIapSignIn,OAuthUserSignIn, andIapSignOut. This new parameter is similar to the previous lambda and should be used when launching and receiving IAP/OAuth flows from your ownActivity.
- Recommended: Use the updated
-
Deprecated:
OAuthUserSignInActivityin the AndroidManifest, previously used to handle OAuth redirect URIs.- Recommended: Replace it with
AuthenticationActivity, which provides the same functionality and also supports IAP sign-in/sign-out completion.
- Recommended: Replace it with
-
Deprecated:
Activity.launchCustomTabs(pendingSignIn: OAuthUserSignIn?)&AuthenticatorState.completeOAuthSignIn(intent)- Recommended:
Activity.launchCustomTabs(pendingBrowserAuthenticationChallenge)AuthenticatorState.completeBrowserAuthenticationChallenge(intent) - These updated methods support both OAuth and IAP sign-in/sign-out flows.
- Recommended:
-
Deprecated:
AuthenticationManager.signOut()as it does not support IAP sign-out.- Recommended: Use
AuthenticatorState.signOut(). IfIapCredentialsare present in the credential cache, this will launch a browser page to invalidate the IAP session
- Recommended: Use
-
The
AuthenticatorStatenow supports managing multipleOAuthUserConfigurationinstances through the newAuthenticatorState.OAuthUserConfigurationsproperty. This enhancement allows developers to configure multiple OAuth setups more flexibly.
See the Authenticator toolkit component for more details.
Augmented Reality - FlyoverSceneView
The FlyoverSceneView component uses augmented reality to render a scene that is navigated by moving the device, providing a more natural navigation experience than a mouse or touch interface. FlyoverSceneView can be customized to render any location with a variable translationFactor to control the degree to which device movement affects the movement of the scene camera. See the FlyoverSceneView toolkit component for more details.
Augmented Reality - WorldScaleSceneView
WorldScaleSceneViewmay now enter aFailedToInitializestatus inWorldScaleTrackingMode.Worldif the component is unable to access the device sensor data.WorldScaleSceneViewwill now receive a validmapPointin theSingleTapConfirmedEventsupplied by theonSingleTapConfirmedcallback. ThismapPointis calculated using the ARCore Depth API. If the Depth API is not supported on a device, it will test against any horizontal or vertical planes detected at the tapped screen coordinate. If no planes are detected, themapPointwill be null.- When the
WorldScaleSceneViewis running inGeospatialmode, ARCore uses Google VPS when available. User can now make use of two versions of thecheckVpsAvailability()function (with and without location parameters) available onWorldScaleSceneViewProxyto query VPS availability. WorldScaleSceneViewnow has anonTrackingErrorChangedparameter which can be used to track transient errors after theWorldScaleSceneViewhas been initialized.
See the WorldScaleSceneView toolkit component for more details.
Basemap Gallery
The BasemapGallery toolkit component has been enhanced to allow basemaps that come from a portal item to be marked as 3D basemaps. If the new property BasemapGalleryItem.is3D is set true, a “3D” badge is displayed on top of the basemap’s thumbnail in the gallery. See the BasemapGallery toolkit component for more details.
Feature Forms
New Features:
- Utility Network Associations Support:
- Added support for
UtilityAssociationsFormElements in theFeatureForm. This allows users to view a list ofUtilityAssociations, navigate to associated features, and edit them. - Introduced a new
FeatureFormStateclass to support navigation for associations inUtilityAssociationsFormElementand associated features. A new overload acceptingFeatureFormStateas a parameter has been added. - Navigation to other features while viewing
UtilityAssociations can be disabled using theisNavigationEnabled: Booleanparameter, which defaults totrue.
- Added support for
- Close Icon:
- A close icon is now displayed in the form UI. The
onDismissparameter allows handling the tap action, and the icon can be hidden by settingshowCloseIcon: Booleantofalse.
- A close icon is now displayed in the form UI. The
- Action Bar for Edits:
- When edits are present in the
FeatureForm, an action bar is displayed at the top of the form with “Save” and “Discard” buttons. This can be hidden by settingshowFormActions: Booleantofalse. A newonEditingEventcallback of typeFeatureFormEditingEventis introduced to listen for save and discard actions.
- When edits are present in the
- Attachments UI has been redesigned with a modern look. New styling options are introduced with
AttachmentsElementColors.tileContainerColorandAttachmentsElementTypography.tileSupportingTextStyle. - The toolkit now supports downloading large attachments up to 999MB, while uploading remains limited to 50MB.
Deprecations:
- Deprecated the
FeatureForm(featureForm: FeatureForm, ..)composable introduced in version 200.4.0. This overload does not displayUtilityAssociationsFormElements. Use the overload that acceptsFeatureFormStateinstead. - Deprecated
AttachmentsElementColors.outlineColorandtileBorderColoras the element is no longer outlined.
See the FeatureForm toolkit component for more details.
OfflineMapAreas
The OfflineMapAreas composable allows users to take web maps offline. Users can download map areas created ahead-of-time by the web map author, or they can create map areas on-demand by specifying an area of interest and level of detail. Map areas are downloaded to the app’s Documents directory and can be used even when the app is completely offline. Users can get information about a map area such as its size and the geographic region it covers. They can also delete a downloaded map area to free up storage space on the device. See the OfflineMapAreas toolkit component for more details.
OverviewMap
The OverviewMap in the geoview-compose module is a small, secondary MapView that can be superimposed on a MapView or SceneView. Its purpose is to show the current viewpoint of the map or scene in a wider context. The OverviewMap can use a customized Symbol to display the visible area or viewpoint center for the larger MapView or SceneView. See the OverviewMap toolkit component for more details.
Modular toolkit library
The toolkit has library modules that can be deployed independent of each other in an application. Note that an individual library module can contain one or more composable UI components.
Reference the library from Jfrog
-
If you haven’t already, install and set up ArcGIS Maps SDK for Kotlin.
-
Ensure the Esri public Jfrog Maven repository is in your project’s gradle file,
https://esri.jfrog.io/artifactory/arcgissettings.gradle.ktsdependencyResolutionManagement {repositories {...maven { url = uri("https://esri.jfrog.io/artifactory/arcgis") }...}} -
From the Android view, open Gradle Scripts > build.gradle.kts (Module: app) and add a dependency for each component of the ArcGIS Maps SDK for Kotlin Toolkit that you will be using.
From the Project tool window, open Gradle Scripts > libs.versions.toml. In the
[versions]section, verify you’re using the correct version number for ArcGIS Maps SDK for Kotlin. And in the[libraries]section, add the library declarations for the following:- the ArcGIS Maps SDK for Kotlin SDK.
- the ArcGIS Maps SDK for Kotlin Toolkit BOM.
- any Toolkit components needed. For example, to display a simple map or scene, you need only the
geoview-composecomponent, which contains the composable functionsMapViewandSceneView.
Gradle version catalogs are the standard Android approach to declaring dependency versions. They are preferred over specifying versions numbers in the
build.gradle.ktsor listing version numbers in aversion.gradle. In recent releases of Android Studio, the New Project Wizard generatesbuild.gradle.ktsandgradle/libs.versions.tomlfiles that support this standard.Gradle version catalogs can also use BOM files to specify a single version number for all artifacts in the BOM. For more details, see
Using the BOMin theREADMEof the ArcGIS Maps SDK for Kotlin Toolkit.63 collapsed linesplugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android)alias(libs.plugins.kotlin.compose)}android {namespace = "com.example.app"compileSdk = libs.versions.compileSdk.get().toInt()defaultConfig {applicationId = "com.example.app"minSdk = libs.versions.minSdk.get().toInt()targetSdk = libs.versions.targetSdk.get().toInt()versionCode = 1versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"vectorDrawables {useSupportLibrary = true}}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}kotlinOptions {jvmTarget = "17"}buildFeatures {compose = true}packaging {resources {excludes += "/META-INF/{AL2.0,LGPL2.1}"}}}dependencies {implementation(libs.androidx.core.ktx)implementation(libs.androidx.lifecycle.runtime.ktx)implementation(libs.androidx.activity.compose)implementation(platform(libs.androidx.compose.bom))implementation(libs.androidx.ui)implementation(libs.androidx.ui.graphics)implementation(libs.androidx.ui.tooling.preview)implementation(libs.androidx.material3)testImplementation(libs.junit)androidTestImplementation(libs.androidx.junit)androidTestImplementation(libs.androidx.espresso.core)androidTestImplementation(platform(libs.androidx.compose.bom))androidTestImplementation(libs.androidx.ui.test.junit4)debugImplementation(libs.androidx.ui.tooling)debugImplementation(libs.androidx.ui.test.manifest)// ArcGIS Maps for Kotlin - SDK dependencyimplementation(libs.arcgis.maps.kotlin)// Toolkit dependenciesimplementation(platform(libs.arcgis.maps.kotlin.toolkit.bom))implementation(libs.arcgis.maps.kotlin.toolkit.geoview.compose)implementation(libs.arcgis.maps.kotlin.toolkit.authentication)2 collapsed lines}[versions]arcgisMapsKotlin = "200.8.2"# Version numbers added by Android Studio New Project Wizardagp = "8.9.2"kotlin = "2.1.20"coreKtx = "1.16.0"junit = "4.13.2"junitVersion = "1.2.1"espressoCore = "3.6.1"lifecycleRuntimeKtx = "2.8.7"activityCompose = "1.10.1"composeBom = "2025.04.00"# Other version numberscompileSdk = "36"minSdk = "28"targetSdk = "36"[libraries]arcgis-maps-kotlin = { group = "com.esri", name = "arcgis-maps-kotlin", version.ref = "arcgisMapsKotlin" }arcgis-maps-kotlin-toolkit-bom = { group = "com.esri", name = "arcgis-maps-kotlin-toolkit-bom", version.ref = "arcgisMapsKotlin" }arcgis-maps-kotlin-toolkit-geoview-compose = { group = "com.esri", name = "arcgis-maps-kotlin-toolkit-geoview-compose" }arcgis-maps-kotlin-toolkit-authentication = { group = "com.esri", name = "arcgis-maps-kotlin-toolkit-authentication" }androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }junit = { group = "junit", name = "junit", version.ref = "junit" }androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }androidx-ui = { group = "androidx.compose.ui", name = "ui" }androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }androidx-material3 = { group = "androidx.compose.material3", name = "material3" }[plugins]android-application = { id = "com.android.application", version.ref = "agp" }kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
The highlights above indicate lines that we are adding to the default build.gradle.kts (Module: app) and gradle/libs.versions.toml generated by the Android Studio New Project Wizard.
The first time you build a project, the Gradle build script will automatically download the ArcGIS Maps SDK for Kotlin and its resources to your development machine. Your Android Studio project will then access the Kotlin Maps SDK with no further action on your part.
Build from source
Although not required to do so, you can build the Toolkit components and micro-apps from the source code in the Toolkit repo. See the setup instructions for details.
Requirements
The following table shows version compatibility.
| SDK Version | Toolkit Version |
|---|---|
| 200.0.0 | none |
| 200.1.0 | none |
| 200.2.0 | 200.2.0 |
| 200.3.0 | 200.3.0 |
| 200.4.0 | 200.4.0 |
| 200.5.0 | 200.5.0 |
| 200.6.0 | 200.6.0 |
| 200.7.0 | 200.7.0 |
| 200.8.0 | 200.8.0 |
Issues
Find a bug or want to request a new feature enhancement? Please let us know by submitting an issue.