Skip to main content

Migrate to v2

This document is a guide for migrating your application using Mapbox Search SDK for Android from v1 to v2. The guide includes information about new features, deprecated APIs, and breaking changes.

Mapbox Search SDK for Android v2 is a major new version of the SDK. To install the latest version of the SDK, follow the installation instructions and use this guide to update your application from v1 to v2.

Dependencies

Maps SDK

The Search SDK v2 uses the Mapbox Maps SDK v11, as opposed to Maps SDK v10 in the Search SDK v1. Maps SDK v11 offers the new Mapbox Standard style support, new 3D features, improved performance, and more.

Maps SDK v11 is a SEMVER major release with breaking API changes. If the application you are migrating uses a map, read the Maps SDK migration guide before reading the Search-specific content below.

GUIDE
Migrate to v11

Upgrade your application from the Mapbox Maps SDK for Android v10 to v11.

Kotlin

The Search SDK v2 is written in Kotlin, the official language recommended by Google for Android development. It was compiled using Kotlin 1.7.20 and has binary compatibility with Kotlin compiler 1.6 and above.

Java support

While the Search SDK for Android is built with Kotlin, Kotlin is 100% interoperable with Java. Applications with a Java codebase can interact properly with the public APIs exposed by Mapbox SDKs for Android.

For information on Java and Kotlin interoperability, see the official Kotlin docs:

If you experience issues using the Mapbox Search SDK for Android with Java, contact us.

Migration steps

1. Update dependencies

Update your app's dependencies to use the latest version of the Mapbox Maps SDK for Android.

dependencies {
implementation 'com.mapbox.maps:android:11.0.0'
}

2. Replace deprecated APIs

Check your code for deprecated APIs and replace them with the recommended alternatives. Note that deprecated APIs may be removed in future releases.

2.1 Deprecating MapboxMap.loadStyle methods

The following methods have been deprecated and will be removed in the next major version:

fun loadStyleUri(styleUri: String, styleTransitionOptions: TransitionOptions? = null, onStyleLoaded: Style.OnStyleLoaded? = null, onMapLoadErrorListener: OnMapLoadErrorListener? = null)
fun loadStyleUri(styleUri: String, onStyleLoaded: Style.OnStyleLoaded? = null, onMapLoadErrorListener: OnMapLoadErrorListener? = null)
fun loadStyleUri(styleUri: String, onStyleLoaded: Style.OnStyleLoaded? = null)
fun loadStyleUri(styleUri: String)
fun loadStyleJson(styleJson: String, styleTransitionOptions: TransitionOptions? = null, onStyleLoaded: Style.OnStyleLoaded? = null, onMapLoadErrorListener: OnMapLoadErrorListener? = null)
fun loadStyleJson(styleJson: String, onStyleLoaded: Style.OnStyleLoaded? = null, onMapLoadErrorListener: OnMapLoadErrorListener? = null)
fun loadStyleJson(styleJson: String, onStyleLoaded: Style.OnStyleLoaded? = null)
fun loadStyleJson(styleJson: String)
fun loadStyle(styleExtension: StyleContract.StyleExtension, styleTransitionOptions: TransitionOptions? = null, onStyleLoaded: Style.OnStyleLoaded? = null, onMapLoadErrorListener: OnMapLoadErrorListener? = null)
fun loadStyle(styleExtension: StyleContract.StyleExtension, onStyleLoaded: Style.OnStyleLoaded? = null, onMapLoadErrorListener: OnMapLoadErrorListener? = null)

The following functions are introduced to load the style:

// to load the style both from URI or JSON
@JvmOverloads
fun loadStyle(
style: String,
onStyleLoaded: Style.OnStyleLoaded? = null,
)

// to load the style using Style DSL
@JvmOverloads
fun loadStyle(
styleExtension: StyleContract.StyleExtension,
onStyleLoaded: Style.OnStyleLoaded? = null,
)

Important notes:

  1. When using loadStyle(style: String, onStyleLoaded: Style.OnStyleLoaded? = null), the string is first checked to see if it is a valid URI; if not, it will be treated as a JSON.
  2. Parameter onMapLoadErrorListener from loadStyle was removed as it was not covering all the map/style loading errors. If you need to listen to those errors, you have to register a specific listener in advance; for example, OnMapLoadErrorListener should now be registered with MapboxMap.subscribeMapLoadingError; you could also subscribe to other error/warning events like MapboxMap.subscribeStyleImageMissing or MapboxMap.subscribeStyleImageRemoveUnused.
  3. Parameter styleTransitionOptions from loadStyle was removed. To apply styleTransitionOptions, you should use more granular overloaded loadStyle taking StyleContract.StyleExtension and add transition options in the DSL block:
mapboxMap.loadStyle(
style(Style.DARK) {
+transition {
duration(100L)
enablePlacementTransitions(false)
}
// other runtime styling
}
)

Related minor breaking change: renamed StyleContract.StyleExtension.styleUri -> StyleContract.StyleExtension.style as this property now can return both URI and JSON:

mapboxMap.loadStyle(style(styleUri = Style.DARK))
// should be replaced with
mapboxMap.loadStyle(style(style = Style.DARK))

2.2 Deprecating event listener APIs

All Map events have become serializable, which brings type-safety and eliminates deserialization errors. We have deprecated traditional listener-based event API (for example MapboxMap.add<EVENT>Listener() and MapboxMap.remove<EVENT>Listener()) and modified observable event APIs to subscribe dedicated events using MapboxMap.subscribe<EVENT>.

The following methods have been deprecated in favor of subscribe<EVENT> methods and will be removed in the next major version. The full list is:

    fun addOnCameraChangeListener(onCameraChangeListener: OnCameraChangeListener)
fun removeOnCameraChangeListener(onCameraChangeListener: OnCameraChangeListener)
fun addOnMapIdleListener(onMapIdleListener: OnMapIdleListener)
fun removeOnMapIdleListener(onMapIdleListener: OnMapIdleListener)
fun addOnMapLoadErrorListener(onMapLoadErrorListener: OnMapLoadErrorListener)
fun removeOnMapLoadErrorListener(onMapLoadErrorListener: OnMapLoadErrorListener)
fun addOnMapLoadedListener(onMapLoadedListener: OnMapLoadedListener)
fun removeOnMapLoadedListener(onMapLoadedListener: OnMapLoadedListener)
fun addOnRenderFrameStartedListener(onRenderFrameStartedListener: OnRenderFrameStartedListener)
fun removeOnRenderFrameStartedListener(onRenderFrameStartedListener: OnRenderFrameStartedListener)
fun addOnRenderFrameFinishedListener(onRenderFrameFinishedListener: OnRenderFrameFinishedListener)
fun removeOnRenderFrameFinishedListener(onRenderFrameFinishedListener: OnRenderFrameFinishedListener)
fun addOnSourceAddedListener(onSourceAddedListener: OnSourceAddedListener)
fun removeOnSourceAddedListener(onSourceAddedListener: OnSourceAddedListener)
fun addOnSourceDataLoadedListener(onSourceDataLoadedListener: OnSourceDataLoadedListener)
fun removeOnSourceDataLoadedListener(onSourceDataLoadedListener: OnSourceDataLoadedListener)
fun addOnSourceRemovedListener(onSourceRemovedListener: OnSourceRemovedListener)
fun removeOnSourceRemovedListener(onSourceRemovedListener: OnSourceRemovedListener)
fun addOnStyleDataLoadedListener(onStyleDataLoadedListener: OnStyleDataLoadedListener)
fun removeOnStyleDataLoadedListener(onStyleDataLoadedListener: OnStyleDataLoadedListener)
fun addOnStyleLoadedListener(onStyleLoadedListener: OnStyleLoadedListener)
fun removeOnStyleLoadedListener(onStyleLoadedListener: OnStyleLoadedListener)
fun addOnStyleImageMissingListener(onStyleImageMissingListener: OnStyleImageMissingListener)
fun removeOnStyleImageMissingListener(onStyleImageMissingListener: OnStyleImageMissingListener)
fun addOnStyleImageUnusedListener(onStyleImageUnusedListener: OnStyleImageUnusedListener)
fun removeOnStyleImageUnusedListener(onStyleImageUnusedListener: OnStyleImageUnusedListener)

The following APIs are introduced in Maps v11 to subscribe to events:

    fun subscribeCameraChanged(cameraChangedCallback: CameraChangedCallback): Cancelable
fun subscribeMapIdle(mapIdleCallback: MapIdleCallback): Cancelable
fun subscribeMapLoadingError(mapLoadingErrorCallback: MapLoadingErrorCallback): Cancelable
fun subscribeMapLoaded(mapLoadedCallback: MapLoadedCallback): Cancelable
fun subscribeRenderFrameStarted(renderFrameStartedCallback: RenderFrameStartedCallback): Cancelable
fun subscribeRenderFrameFinished(renderFrameFinishedCallback: RenderFrameFinishedCallback): Cancelable
fun subscribeSourceAdded(sourceAddedCallback: SourceAddedCallback): Cancelable
fun subscribeSourceDataLoaded(sourceDataLoadedCallback: SourceDataLoadedCallback): Cancelable
fun subscribeSourceRemoved(sourceRemovedCallback: SourceRemovedCallback): Cancelable
fun subscribeStyleDataLoaded(styleDataLoadedCallback: StyleDataLoadedCallback): Cancelable
fun subscribeStyleLoaded(styleLoadedCallback: StyleLoadedCallback): Cancelable
fun subscribeStyleImageMissing(styleImageMissingCallback: StyleImageMissingCallback): Cancelable
fun subscribeStyleImageRemoveUnused(styleImageRemoveUnusedCallback: StyleImageRemoveUnusedCallback): Cancelable
fun subscribeResourceRequest(resourceRequestCallback: ResourceRequestCallback): Cancelable

Note: To unsubscribe, use the returned Cancelable object.

For convenience, MapboxMap methods returning Flow of events were introduced: cameraChangedEvents, mapIdleEvents, sourceAddedEvents, sourceRemovedEvents, sourceDataLoadedEvents, styleImageMissingEvents, styleImageRemoveUnusedEvents, renderFrameStartedEvents, renderFrameFinishedEvents, resourceRequestEvents.

Event listeners have been deprecated and replaced with callbacks. Callbacks invoke run method that will return data associated with the specific event.

v1 (Maps v10)v2 (Maps v11)
OnCameraChangeListenerCameraChangedCallback
OnMapIdleListenerMapIdleCallback
OnMapLoadErrorListenerMapLoadingErrorCallback
OnMapLoadedListenerMapLoadedCallback
OnRenderFrameStartedListenerRenderFrameStartedCallback
OnRenderFrameFinishedListenerRenderFrameFinishedCallback
OnSourceAddedListenerSourceAddedCallback
OnSourceDataLoadedListenerSourceDataLoadedCallback
OnSourceRemovedListenerSourceRemovedCallback
OnStyleDataLoadedListenerStyleDataLoadedCallback
OnStyleLoadedListenerStyleLoadedCallback
OnStyleImageMissingListenerStyleImageMissingCallback
OnStyleImageUnusedListenerStyleImageRemoveUnusedCallback

3. Check for breaking changes

The following are breaking changes that may affect your app:

3.1 Renaming suggestions for reverse geocoding to reverse

When you're trying to do a lookup by a coordinate in AddressAutofill or PlaceAutocomplete, replace the suggestions method name with reverse.

Also, note that the AddressAutofill.reverse geocoding method returns a list of AddressAutofillResult instead of AddressAutofillSuggestion.

3.2 The coordinate value is not returned in AddressAutofillSuggestion/PlaceAutocompleteSuggestion anymore

A separate call to the retrieve method is now required to get the coordinate value for a specific AddressAutofillSuggestion or PlaceAutocompleteSuggestion object.

3.3 Location API

3.3.1 Using LocationService instead of LocationEngine
  1. LocationEngine has been removed in Maps v11. To get a location provider, you now have to import the com.mapbox.common.location.* packages and use the LocationService and DeviceLocationProvider with a LocationObserver.

First, get a DeviceLocationProvider:

import com.mapbox.common.location.LocationService
import com.mapbox.common.location.LocationServiceFactory
import com.mapbox.common.location.LocationProvider
import com.mapbox.common.location.LocationObserver

val locationService : LocationService = LocationServiceFactory.getOrCreate()
var locationProvider: DeviceLocationProvider? = null
val result = locationService.getDeviceLocationProvider(null)
if (result.isValue) {
locationProvider = result.value!!
} else {
Log.error("Failed to get device location provider")
}

There are also overload versions of getDeviceLocationProvider that allows to specify DeviceLocationProviderType and ExtendedLocationProviderParameters:

LocationService::getDeviceLocationProvider(type: DeviceLocationProviderType,
request: LocationProviderRequest? = null, allowUserDefined: Boolean = true):
Expected<LocationError, DeviceLocationProvider>

LocationService::getDeviceLocationProvider(extendedParameters: ExtendedLocationProviderParameters,
request: LocationProviderRequest? = null):
Expected<LocationError, DeviceLocationProvider>

See the documentation for DeviceLocationProviderType and ExtendedLocationProviderParameters for a detailed description of these types.

To receive location updates, create a LocationObserver and override the onLocationUpdateReceived function to handle the locations:

val locationObserver = object: LocationObserver {
override fun onLocationUpdateReceived(locations: MutableList<Location>) {
Log.e(TAG, "Location update received: " + locations)
}
}
locationProvider.addLocationObserver(locationObserver);

To stop receiving updates, remove your observer:

locationProvider.removeLocationObserver(locationObserver);

You can register for location updates via a PendingIntent on the DeviceLocationProvider:

locationProvider.requestLocationUpdates(myPendingIntent)
locationProvider.removeLocationUpdates(myPendingIntent)

You can also register a LocationObserver with a Looper object, the message queue will then be used to implement the callback mechanism:

addLocationObserver(observer: LocationObserver, looper: Looper)

The location provider automatically starts and stops collecting locations based on the number of subscribers: once the first subscriber is registered, the service starts, and when the last observer is unregistered, the service stops.

If you want to get the last known location, you can do so via the asynchronous LocationProivder.getLastLocation function. The function returns a Cancelable object, which allows cancelling the request if needed:

val lastLocationCancelable = locationProvider.getLastLocation { result ->
result?.let { doSomething(it) }
}

To cancel the request, call

lastLocationCancelable.cancel()
3.3.2 Common location migration
  1. LocationService::getLastLocation() changes.

LocationService::getLastLocation() is replaced by an asynchronous method LocationProvider::getLastLocation()

Maps v10:

LocationService::getLastLocation(): expected<Location, LocationError>

Maps v11:

LocationProvider::getLastLocation(callback: GetLocationCallback): Cancelable
  1. LiveTrackingClient has been replaced by DeviceLocationProvider

Remove lifecycle mode capabilities from LiveTrackingClient/DeviceLocationProvider, LiveTrackingClientSettings::ActivityType, and LiveTrackingClient::flush()

The explicit start() and stop() functions have been removed from the API. DeviceLocationProvider starts as soon as one observer is attached and stops when all observers are removed.

  1. LocationService::getDeviceLocationProvider instead of LocationService::getLiveTrackingClient

Introduce LocationProviderRequest to replace the Value setting and simplify API. Add several overloads for getDeviceLocationProvider to be able to specify custom DeviceLocationProvider parameters.

Maps v10:

LocationService::getLiveTrackingClient(name: String, capabilities: Value): expected<Location, LocationError>

Maps v11:

LocationService::getDeviceLocationProvider(request: optional<LocationProviderRequest>): Expected<DeviceLocationProvider, LocationError>

LocationService::getDeviceLocationProvider(type: DeviceLocationProviderType,
request: LocationProviderRequest? = null, allowUserDefined: Boolean = true):
Expected<LocationError, DeviceLocationProvider>

LocationService::getDeviceLocationProvider(extendedParameters: ExtendedLocationProviderParameters,
request: LocationProviderRequest? = null):
Expected<LocationError, DeviceLocationProvider>

For a detailed description of each type, see the documentation for LocationProviderRequest, DeviceLocationProviderType, and ExtendedLocationProviderParameters.

  1. LiveTrackingClientObserver changes

Rename LiveTrackingClientObserver to LocationObserver. Method onLiveTrackingStateChanged() removed. Method onLocationUpdateReceived() simplified:

Maps v10:

interface LiveTrackingClientObserver {
fun onLiveTrackingStateChanged(state: LiveTrackingState, error: LocationError?)
fun onLocationUpdateReceived(locationUpdate: Expected<LocationError, List<Location>>)
}

Maps v11:

interface LocationObserver {
fun onLocationUpdateReceived(locations: List<Location>)
}

3.4 ResourceOptions and ResourceOptionsManager have been removed

There can only be one global Mapbox access token used by the application.

The ResourceOptions class has been removed. To set options accessToken, baseURL, dataPath, assetPath, tileStore and tileStoreUsageMode at runtime, use MapboxOptions and MapboxMapsOptions objects.

If you were using ResourceOptions to set the access token and other properties as part of the map view MapInitOptions (or MapSnapshotOptions for the Snapshotter), you can now call the following methods before creating the MapView, MapSurface or Snapshotter:

    MapboxOptions.accessToken = "your_mapbox_access_token"
MapboxOptions.mapsOptions.tileStore = yourTileStore
MapboxOptions.mapsOptions.tileStoreUsageMode = yourTileStoreUsageMode

You can find an example at MapViewCustomizationActivity.kt.

The ResourceOptionsManager class has been removed. To set the default token, define a string resource value:

<resources>
<string name="mapbox_access_token" translatable="false">your_mapbox_access_token</string>
</resources>

Or you can use MapboxOptions.accessToken property at runtime.

MapboxOptions.accessToken = "<your_mapbox_access_token>"

3.5 Kotlin-specific changes

The method MapView.getMapboxMap() has been deprecated. Use the property MapView.mapboxMap instead.

The method MapSurface.getMapboxMap() has been deprecated. Use the property MapSurface.mapboxMap instead.

The method MapboxMap.getStyle() has been deprecated. Use the property MapboxMap.style instead.

Was this page helpful?