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 and Standard Satellite styles 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.
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:
- 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. - Parameter
onMapLoadErrorListener
fromloadStyle
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 withMapboxMap.subscribeMapLoadingError
; you could also subscribe to other error/warning events likeMapboxMap.subscribeStyleImageMissing
orMapboxMap.subscribeStyleImageRemoveUnused
. - Parameter
styleTransitionOptions
fromloadStyle
was removed. To applystyleTransitionOptions
, you should use more granular overloadedloadStyle
takingStyleContract.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) |
---|---|
OnCameraChangeListener | CameraChangedCallback |
OnMapIdleListener | MapIdleCallback |
OnMapLoadErrorListener | MapLoadingErrorCallback |
OnMapLoadedListener | MapLoadedCallback |
OnRenderFrameStartedListener | RenderFrameStartedCallback |
OnRenderFrameFinishedListener | RenderFrameFinishedCallback |
OnSourceAddedListener | SourceAddedCallback |
OnSourceDataLoadedListener | SourceDataLoadedCallback |
OnSourceRemovedListener | SourceRemovedCallback |
OnStyleDataLoadedListener | StyleDataLoadedCallback |
OnStyleLoadedListener | StyleLoadedCallback |
OnStyleImageMissingListener | StyleImageMissingCallback |
OnStyleImageUnusedListener | StyleImageRemoveUnusedCallback |
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
LocationEngine
has been removed in Maps v11. To get a location provider, you now have to import thecom.mapbox.common.location.*
packages and use theLocationService
andDeviceLocationProvider
with aLocationObserver
.
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
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
LiveTrackingClient
has been replaced byDeviceLocationProvider
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.
LocationService::getDeviceLocationProvider
instead ofLocationService::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
.
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.