Skip to main content
Version: 6.0

Release Notes

Mappedin SDK for Android release notes are posted here and this page will be kept up-to-date as updates are released.

v6.3.0 - May 20, 2026

Features

  • Added Navigation.trackCoordinate() for path tethering and travelled-path tracking. Includes TetheredOptions, TravelledOptions, TrackCoordinateOptions, TrackingMode, CoordinateOutsideThresholdMode, and OutsideThresholdPathStyle models for complete control over coordinate tracking behavior along navigation paths.
val handle = mapView.navigation.trackCoordinate(
coordinate,
TrackCoordinateOptions.Tethered(
TetheredOptions(
tetherThresholdDistance = 5.0,
coordinateOutsideThresholdMode = CoordinateOutsideThresholdMode.TETHER_AND_DASH,
outsideThresholdPathStyle = OutsideThresholdPathStyle.DASHED_BOXES,
),
),
) { result -> }
  • Added BlueDotEvents.DotPositionUpdate event, which emits smoothed Coordinate updates suitable for feeding into Navigation.trackCoordinate().

  • Added GetDirectionsOptions.includeNonPublic to allow routing through non-public spaces and connections.

  • Added interactive property to AddImageOptions and corresponding interactive and cursor properties to ImageState and ImageUpdateState. Image3DView is now included in ClickPayload and HoverPayload images and target properties.

  • Added visible property to BlueDotOptions, BlueDotOptions.AccuracyRing, and BlueDotOptions.Heading for independent visibility control of Blue Dot components. When visible is set to false on BlueDotOptions, the dot is hidden but the accuracy ring and heading cone may still render based on their own visible settings.

mapView.blueDot.enable(BlueDotOptions(
visible = false,
accuracyRing = BlueDotOptions.AccuracyRing(visible = true),
heading = BlueDotOptions.Heading(visible = false),
))
  • Added AutoZoomThresholds to DynamicFocusOptions and DynamicFocusState for automatic zoom threshold calculation, replacing manual indoorZoomThreshold and outdoorZoomThreshold configuration.
val options = DynamicFocusOptions(
autoFocus = true,
autoZoomThresholds = AutoZoomThresholds.Enabled(debug = true),
)
mapView.dynamicFocus.enable(options) { }
  • Added FloorStack as a camera FocusTarget via FocusTarget.FloorStackTarget, with convenience focusOn and getFocusOnTransform overloads on Camera.

  • Added Events.CameraScreenOffsetsChange event, emitted when camera screen offsets change.

  • Added pixel-based Width support via Width.Pixels for specifying path widths in pixels (e.g., "20px").

Deprecated

  • Deprecated BlueDot.update(). Use forcePosition() to set an authoritative position that overrides all sensors, or reportPosition() to feed a confidence-weighted position into the fusion engine.

v6.2.0 - April 2, 2026

Features

  • Added forcePosition() and reportPosition() methods to BlueDot for manual positioning. forcePosition() overrides all sensors for a specified duration, while reportPosition() blends with other sensors using confidence weighting.
val target = ForcePositionTarget(
latitude = 43.46106,
longitude = -80.52220,
heading = 90.0
)
mapView.blueDot.forcePosition(target, durationMs = 30_000) { result ->
result.onSuccess { Log.d("Demo", "Position forced for 30s") }
}
  • Added sensor management methods to BlueDot: enableSensor(), disableSensor(), checkSensorPermission(), requestSensorPermission(), and isSensorEnabled() for fine-grained control over individual sensors in the fusion engine.

  • Added AnchorSet and AnchorExpired events to notify when forced position anchors are created and expire.

  • Added EventsManager on MapData.eventsManager for loading and querying CMS events. Includes load(), getEvents(), getById(), and getByLocationId() methods, with EventMetaData, EventVideo, and EventsManagerOptions models.

mapView.mapData.eventsManager.load { loadResult ->
loadResult.onSuccess {
mapView.mapData.eventsManager.getEvents { eventsResult ->
eventsResult.onSuccess { events ->
for (event in events) {
Log.d("Events", "${event.name}: ${event.startDate} - ${event.endDate}")
}
}
}
}
}
  • Added position property to ShapeState and ShapeUpdateState, enabling getting and setting Shape positions.
// Get the position of a shape
mapView.getState(shape) { result ->
result.onSuccess { state ->
Log.d("Shape", "Position: ${state?.position?.latitude}, ${state?.position?.longitude}")
}
}

// Move a shape to a new position
val newPosition = Coordinate(latitude = 43.46, longitude = -80.52)
mapView.updateState(shape, ShapeUpdateState(position = newPosition))
  • Added Models.all() method to load all CMS-defined 3D Models for a venue.

  • Added MultiFloorViewEffectState for configuring visual effects on inactive floors visible through open-to-below spaces, including darken, desaturate, and wash-out effects with depth controls. Configurable at init time via MultiFloorViewOptions or at runtime via GlobalStateUpdate.multiFloorView.

// Configure visual effects at init time
val options = Show3DMapOptions(
multiFloorView = MultiFloorViewOptions(
spacesOpenToBelowEnabled = true,
spacesOpenToBelowVisualEffectEnabled = true,
spacesOpenToBelowVisualEffectDarkenAmount = 0.3,
spacesOpenToBelowVisualEffectDesaturateAmount = 0.7
)
)

// Update visual effects at runtime
mapView.updateGlobalState(GlobalStateUpdate(
multiFloorView = GlobalStateUpdate.MultiFloorViewEffectStateUpdate(
spacesOpenToBelowVisualEffectDarkenAmount = 0.5
)
))
  • Added Events.GlobalStateChange event, emitted when updateGlobalState() is called.

  • Added floorGapMultiplier and floorGapFallback properties to MultiFloorViewOptions for additional control over floor spacing in multi-floor view.

  • Added animated property to AddMarkerOptions to control Marker visibility transitions.

  • Added MaterialSide.AUTO option that automatically chooses front or double-sided rendering based on opacity.

  • Added screenOffsets, pitch, and zoomLevel properties to Show3DMapOptions.

6.2.0-beta.1 - February 13, 2026

  • Upgraded to Mappedin JS v6.14.0

  • Added - Query.at(coordinate) method to find all geometry objects (Spaces, MapObjects, Areas, Floors) at a given coordinate, with typed results returned as QueryAtResult

val coord = Coordinate(latitude = 43.861, longitude = -78.947, floorId = "floor1")
mapData.query.at(coord) { result ->
result.onSuccess { atResults ->
atResults?.forEach { queryResult ->
when (queryResult) {
is QueryAtResult.SpaceResult -> Log.d("Query", "Space: ${queryResult.space.name}")
is QueryAtResult.MapObjectResult -> Log.d("Query", "MapObject: ${queryResult.mapObject.name}")
is QueryAtResult.AreaResult -> Log.d("Query", "Area: ${queryResult.area.name}")
is QueryAtResult.FloorResult -> Log.d("Query", "Floor: ${queryResult.floor.name}")
}
}
}
}
  • Added - DynamicFocus methods for complete control over floor visibility and view state management:
    • preloadFloors() - Preloads initial floors for improved rendering performance
    • setIndoor() and setOutdoor() - Forces indoor or outdoor view state regardless of zoom level
    • setDefaultFloorForStack(floorStack, floor) and resetDefaultFloorForStack(floorStack) - Manages default floors for FloorStacks
    • getDefaultFloorForStack(floorStack) and getCurrentFloorForStack(floorStack) - Gets default and current floors
    • setCurrentFloorForStack(floorStack, floor) - Sets the current visible floor for a FloorStack
    • exclude(floorStack) / exclude(floorStacks) and include(floorStack) / include(floorStacks) - Excludes or includes FloorStacks from Dynamic Focus visibility changes
    • destroy() - Destroys the DynamicFocus instance and cleans up event listeners
// Force indoor view
mapView.dynamicFocus.setIndoor()

// Set current floor for a floor stack
mapView.dynamicFocus.setCurrentFloorForStack(building.floorStack, floor2) { }

// Exclude a building from dynamic focus visibility changes
mapView.dynamicFocus.exclude(parkingGarage.floorStack) { }

// Clean up when done
mapView.dynamicFocus.destroy()
  • Added - MapData.isEnterpriseMode() method to programmatically determine whether a map uses CMS/Enterprise or Maker data. Runtime warnings are now logged when using data types that don't match the map's data source
mapData.isEnterpriseMode { result ->
result.onSuccess { isEnterprise ->
if (isEnterprise) {
mapData.getByType(MapDataType.ENTERPRISE_LOCATION) { locResult ->
// Handle enterprise locations
}
} else {
mapData.getByType(MapDataType.LOCATION_PROFILE) { locResult ->
// Handle maker locations
}
}
}
}
  • Added - FloorState.Images.collisionsEnabled property to control whether floor images participate in collision detection

  • Added - Footprint properties to FloorState and FloorUpdateState: basementMaskEnabled, ceilingThickness, ceilingVisible, and outline

  • Added - ModelUpdateState.clippingPlaneZOffset property to control model clipping plane. Use Double.POSITIVE_INFINITY to disable clipping

// Disable clipping for a model
val noClipState = ModelUpdateState(clippingPlaneZOffset = Double.POSITIVE_INFINITY)

// Set explicit clipping plane offset
val clipState = ModelUpdateState(clippingPlaneZOffset = 5.0)

6.2.0-beta.0 - February 2, 2026

  • Upgraded to Mappedin JS v6.13.0

  • Added - BlueDot support with BlueDotOptions, BlueDotPositionUpdate and associated events for displaying the user's position on the map

  • Added - MapView.dynamicFocus extension providing enable, disable, getState, updateState, and focus methods for Dynamic Focus functionality. Includes new models DynamicFocusOptions, DynamicFocusState, DynamicFocusMode, and DynamicFocusAnimationOptions

  • Added - Experimental MapView.__EXPERIMENTAL__auto() method for automatic label and marker setup

  • Added - MapView.hydrateMapDataFromURL(url, options) for hydrating map data directly from a URL

  • Added - MapView.getCacheUrl(...) and MapView.getAssetUrl(...) helper methods for building URLs to cached and asset files

  • Added - Support for loading maps from MVF filename for improved offline capabilities

  • Added - LocationProfile.searchTags property for accessing location search tags

  • Added - allFloors option to Query.nearest() to search across all floors instead of just the current floor

  • Added - images3D getter to PointOfInterest, Space, Area, and MapObject classes with new Image3DView model

  • Improved - Map loading performance by optimizing how map data is passed to the WebView

6.2.0-alpha.3 - January 16, 2026

  • Upgraded to Mappedin JS v6.11.0

  • Added - MapData.on method for subscribing to map data events. This enables listening for events such as language changes on the map data object. Use MapData.changeLanguage to change the current language and subscribe to changes using MapDataEvents.LanguageChange

// Change the map language to Spanish
mapView.mapData.changeLanguage("es")

// Listen for language change events
mapView.mapData.on(MapDataEvents.LanguageChange) { payload ->
payload?.let { language ->
Log.d("MapData", "Language changed to ${language.name} (${language.code})")
}
}
  • Added - FloorState.text3d property to access 3D text state for a floor

  • Added - LocationProfile.extra property to access additional profile data

  • Added - enterpriseLocation property to Space and MapObject, providing direct access to enterprise location data when available

  • Added - LocationProfile.logoImage property as a replacement for the deprecated logo property

  • Added - Strongly typed MapData.hydrateMapData options parameter for better type safety when hydrating cached map data

  • Added - Support for caching map data in binary format for improved offline performance

  • Added - Experimental support for Spaces that are open to below in multi-floor view. When enabled, floors will render with cutouts for Spaces like atriums that span multiple levels, creating a more realistic visualization. Enable this feature using MultiFloorViewOptions.spacesOpenToBelowEnabled

  • Added - New MultiFloorViewOptions properties for customizing floor footprints in multi-floor view:

    • footprintColor - Sets the color of the floor footprint
    • footprintOpacity - Controls the opacity of the floor footprint
    • footprintOutline - Configures the outline appearance of the floor footprint
  • Changed - MultiFloorViewOptions.floorGap now supports both a numeric value or an auto setting for automatic gap calculation between floors

  • Fixed - Bridge serialization issue where FloorStack.geoJSON and other complex GeoJSON properties were not being passed correctly over the native bridge. This resolves issues when accessing GeoJSON data from floor stacks and related objects

  • Fixed - Android Studio code assists (autocomplete, quick documentation, and quick fixes) now work correctly with EnterpriseLocation types.

  • Deprecated - LocationProfile.logo has been deprecated in favor of LocationProfile.logoImage

6.2.0-alpha.2 - January 8, 2026

  • Upgraded to Mappedin JS v6.10.0
  • Added - getDirections must also accept an array of NavigationTarget
  • Added - Coordinate.geoJSON
  • Fixed - mapView.updateState is not working on walls or doors
  • Fixed - getDirectionsMultiDestination's to method should use NavigationTarget not Any
  • Removed - Duplicated unused standalone classes of Point, LineString and MultiPolygon that are defined in Geometry

⚠️ Breaking Changes

  • Changed - Clean up remaining generic types
  • Changed - Strongly type .geoJSON properties
  • Changed - Shapes.add should be strongly typed
// ❌ Before
// Create a FeatureCollection containing the Feature of the Area
val shapeFeatureCollection =
JSONObject().apply {
put("type", "FeatureCollection")
put(
"features",
JSONArray().apply {
put(
JSONObject().apply {
put("type", areaGeoJSON.optString("type"))
areaGeoJSON.optJSONObject("properties")?.let {
put("properties", it)
}
areaGeoJSON.optJSONObject("geometry")?.let {
put("geometry", it)
}
},
)
},
)
}

// Draw the shape
mapView.shapes.add(
shapeFeatureCollection,
PaintStyle(color = color, opacity = opacity, altitude = altitude, height = height),
) {}

// ✅ After
// Get the GeoJSON Feature from the area
val feature = area.geoJSON ?: return

// Create a FeatureCollection containing the single Feature
val featureCollection = FeatureCollection(features = listOf(feature))

// Draw the shape using the strongly-typed API
mapView.shapes.add(
featureCollection,
PaintStyle(color = color, opacity = opacity, altitude = altitude, height = height),
) {}

6.2.0-alpha.1 - December 30, 2025

  • Upgraded to Mappedin JS v6.9.1.
  • Added - Show3DMapOptions.preloadFloors option to preload floors.
  • Added -MultiFloorViewOptions.floorGap option to set the gap between floors.
  • Fixed - Show3DMapOptions.initialFloor should accept only a string.

⚠️ Breaking Changes

  • Changed - Strongly type MapView.on parameters and return values
// ❌ Before
mapView.on("click") { payload ->
val clickPayload = payload as? ClickPayload
}

// ❌ Before
mapView.on(Events.CLICK) { payload ->
val clickPayload = payload as? ClickPayload
}

// ✅ After
mapView.on(Events.Click) { clickPayload ->
}

6.1.0-alpha.1 - December 19, 2025

  • Added - LabelAppearance.iconScale property to control the scale of the icon.
  • Fixed - MapData.getById not returning the correct type.

⚠️ Breaking Changes

  • Fixed - Removed duplicate inline implementation of Interpolation and Width.
// ❌ Before
AddPathOptions(
width = AddPathOptions.Width.Fixed(1.0),
)

// ✅ After
AddPathOptions(
width = Width.Value(1.0),
)
  • Fixed - MapView.getState and MapView.updateState should use data classes and not plain objects.
// ❌ Before
mapView.updateState(space, mapOf("interactive" to true)) { }

// ✅ After
mapView.updateState(space, GeometryUpdateState(interactive = true)) { }

6.0.0-alpha.1 - December 4, 2025

  • Upgraded to Mappedin JS v6.7.0.

6.0.0-alpha.0 - December 3, 2025

  • Initial release of Mappedin SDK for Android v6.