Migrate from Google
Overview
This tutorial covers some fundamental use cases to help you switch your Android app from Google’s APIs to TomTom’s as quickly as possible. It starts with basic environment setup, then dives into the code.
Prerequisites
Before you start writing code, prepare your environment:
Install Android Studio.
Install Android Studio if you don’t already have it.
Create a new project or open an existing one. Make sure that the minimum SDK API level is set to at least 21 (Android 5.0 "Lollipop") and that compile SDK API level is set to 31.
Add the
packagingOptions
.1android {2 ...3 packagingOptions {4 pickFirst "lib/**/libc++_shared.so"5 }6}To get access to the TomTom SDK repository, add the following to your
settings.gradle
file1dependencyResolutionManagement {2 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)3 repositories {4 google()5 mavenCentral()6 maven {7 url = uri("https://repositories.tomtom.com/artifactory/maven")8 }9 }10}If you don’t have an API key visit a How to get a TomTom API key site and create one.
Create fields with the API keys in your module’s
build.gradle
, which will be used later in the application:1android {2 ...3 defaultConfig {4 ...5 manifestPlaceholders = ["GoogleApiKey" : "YOUR_GOOGLE_API_KEY"]67 resValue "string", "maps_api_key", "YOUR_API_KEY"8 buildConfigField("String", "ROUTING_API_KEY", ""YOUR_API_KEY"")9 }10 ...11}
Displaying a map
To display the map using the Google Maps SDK for Android, you need to perform a few steps:
- Add dependencies to your module’s
gradle.build
file:implementation 'com.google.android.gms:play-services-maps:18.0.0' - Add a map fragment to the XML layout:1<androidx.fragment.app.FragmentContainerView2 android:id="@+id/map"3 android:name="com.google.android.gms.maps.SupportMapFragment"4 android:layout_width="match_parent"5 android:layout_height="match_parent" />
- Add a Google Android API key inside the application section of the AndroidManifest.xml file:1<meta-data2 android:name="com.google.android.geo.API_KEY"3 android:value="${GoogleApiKey}" />
- Implement the
OnMapReadyCallback
interface in theMainActivity
class and override theOnMapReadyCallback.onMapReady(GoogleMap)
method to assign the ready instance of the map to the property.override fun onMapReady(googleMap: GoogleMap) {this.googleMap = googleMap - In the
onCreate
method of theMainActivity
get the map fragment instance from activity_main.xml. SetMainActivity
as a callback object which will be triggered whenGoogleMap
is ready.val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragmentmapFragment.getMapAsync(this)
TomTom SDK
To do the same thing in the TomTom SDK for Android:
- Add dependency to your module’s
gradle.build
file:implementation "com.tomtom.sdk:maps-display:0.3.34" - Add a
MapFragment
to the main activity layout. Don’t forget to set the API key for the Maps Display module:1<androidx.fragment.app.FragmentContainerView2 xmlns:tomtom="http://schemas.android.com/apk/res-auto"3 android:id="@+id/map_fragment"4 android:name="com.tomtom.sdk.maps.display.ui.MapFragment"5 android:layout_width="match_parent"6 android:layout_height="match_parent"7 tomtom:mapKey="@string/maps_api_key"8 /> - Define a
TomTomMap
property in theMainActivity
class.private lateinit var tomTomMap: TomTomMap - As with Google, you need to implement the
OnMapReadyCallback
interface in theMainActivity
class and override theOnMapReadyCallback.onMapReady(TomTomMap)
method.1 override fun onMapReady(map: TomTomMap) {2 this.tomTomMap = map3} - In the
onCreate
method of theMainActivity
class, get the map fragment from the layout usingFragmentManager
. Set theOnMapReadyCallback
that will be triggered when the map is ready. The map has to be fully initialized before your app can interact with theTomTomMap
object.val mapFragment = supportFragmentManager.findFragmentById(R.id.map_fragment) as? MapFragmentmapFragment?.getMapAsync(this)
Displaying a marker
The next step is to allow your user to interact with the map. For instance, displaying a marker at the location where the user does a long click.
Once the GoogleMap
is initialized set the OnMapLongClickListener
.
1this.googleMap.setOnMapLongClickListener { latLng: LatLng ->2 displayMarkerAt(latLng)3}
Then set the marker at the selected coordinates.
1private fun displayMarkerAt(latLng: LatLng) {2 val markerOptions = MarkerOptions()3 .position(latLng)4 .title("Long clicked location")5 googleMap.addMarker(markerOptions)6}
TomTom SDK
As with Google, any interaction with the map must be done after it is fully initialized. Add the OnMapLongClickListener
to the TomTomMap
object.
1tomTomMap.addOnMapLongClickListener { geoCoordinate: GeoCoordinate ->2 displayMarkerAt(geoCoordinate)3 true4}
Display a Marker
at the location of the long press.
1private fun displayMarkerAt(geoCoordinate: GeoCoordinate) {2 val markerOptions = MarkerOptions(3 geoCoordinate,4 ImageFactory.fromResource(R.drawable.ic_sdk_tt_compass), // No default marker icon5 label = Label("Long clicked location")6 )7 tomTomMap.addMarker(markerOptions)8}
Displaying traffic
Google has only one method for traffic visualization. That method can only display traffic flow tiles. To show the traffic layer:
googleMap.isTrafficEnabled = true
To hide the traffic layer:
googleMap.isTrafficEnabled = false
TomTom SDK
The TomTom SDK provides two kinds of traffic information, traffic flow and traffic incidents.
- Traffic flow shows the difference between current and free flow speed. Green indicates that the speeds are the same, meaning there are no traffic jams. Red indicates that traffic is slower than free flow, meaning that there are traffic jams.tomTomMap.showTrafficFlow()tomTomMap.hideTrafficFlow()
- Traffic incidents shows specific traffic problems such as closed roads, rain, ice on the road, or accidents.tomTomMap.showTrafficIncidents()tomTomMap.hideTrafficIncidents()
Displaying a route/directions
Displaying a route in Google Maps SDK for Android is not straightforward. It boils down to interacting with the Directions API, gathering a list of route positions, then drawing a polyline from that list directly onto the map. This is too verbose and complex to show in this tutorial.
TomTom SDK
The TomTom Routing API allows the app to easily calculate a route between two points, add waypoints, and specify other route properties. The requested Route
can then be drawn on the map in a single step.
To enable the Routing API inside your application, add a dependency to the module’s
gradle.build
file:implementation "com.tomtom.sdk:routing-client-online:0.3.34"Create an instance of the
RoutingApi
object.1val routingApi = OnlineRoutingApi.create(2 context = applicationContext,3 apiKey = BuildConfig.ROUTING_API_KEY4)Construct the
RoutingOptions
object. This contains route request parameters that will be used for Routing API call.1val amsterdam = GeoCoordinate(52.37, 4.90)2val hague = GeoCoordinate(52.07, 4.30)3val routingOptions = RoutingOptions.Builder(4 Itinerary(amsterdam, hague)5)6 .travelMode(TravelMode.CAR)7 .routeType(RouteType.SHORT)8 .build()Provide the created
RoutingOptions
object as a parameter to theRoutingApi.planRoute(RoutingOptions, RoutingCallback
method. The method performs a request for the route using the provided parameters.routingApi.planRoute(routingOptions, routingCallback)The result of request is returned by the
RoutingCallback
that was provided to the method above. If the call was successful it returnsRoutingResult
. Otherwise, it passes the exception that was raised.1private val routingCallback = object : RoutingCallback {2 override fun onError(error: RoutingError) {3 Toast.makeText(this@MainActivity, error.message, Toast.LENGTH_SHORT).show()4 }56 override fun onSuccess(result: RoutingResult) {7 drawRouteOnTheMap(result)8 }9}Get the
Route
from theRoutingResult
and add it to theTomTomMap
.1private fun drawRouteOnTheMap(result: RoutingResult) {2 val route = result.routes.first()3 val routeOptions = RouteOptions(4 geometry = route.geometry,5 departureMarkerVisible = true,6 destinationMarkerVisible = true7 )8 tomTomMap.addRoute(routeOptions)9 tomTomMap.zoomToRoutes()10}
Showing user location
To use the user’s location in Android, the app must request location permissions. These steps have to be performed for both TomTom SDK and Google Maps.
- Add location permissions to the AndroidManifest.xml:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- Register the location permission callback to handle the user’s response to the system permissions dialog.1private val locationPermissionRequest = registerForActivityResult(2 ActivityResultContracts.RequestMultiplePermissions()3) { permissions ->4 if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true &&5 permissions[Manifest.permission.ACCESS_COARSE_LOCATION] == true6 ) {7 showUserLocation()8 } else {9 Toast.makeText(10 this,11 getString(R.string.location_permission_denied),12 Toast.LENGTH_SHORT13 ).show()14 }15}
- Request permission in runtime to let the user decide whether to allow location permissions.1private fun enableUserLocation() {2 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)3 == PackageManager.PERMISSION_GRANTED &&4 ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)5 == PackageManager.PERMISSION_GRANTED6 ) {7 showUserLocation()8 } else {9 locationPermissionRequest.launch(10 arrayOf(11 Manifest.permission.ACCESS_FINE_LOCATION,12 Manifest.permission.ACCESS_COARSE_LOCATION13 )14 )15 }16}
In Google you can enable location and the location button as follows:
1@SuppressLint("MissingPermission")2private fun showUserLocation() {3 googleMap.isMyLocationEnabled = true4 googleMap.uiSettings.isMyLocationButtonEnabled = true5}
TomTom SDK
In the TomTom SDK you can either use a pre-defined location engine, or define your own LocationEngine
to provide location updates to the map. In this tutorial we will focus on the pre-defined AndroidLocationEngine
. This relies on the Android system location services, meaning that it does not require Google services. For more information read Built-in Location Engine guide.
- Add the
AndroidLocationEngine
dependency:implementation "com.tomtom.sdk:location-android:0.3.34" - Create a
LocationEngine
property and initializeAndroidLocationEngine
. - Set
LocationEngine
to the map. - Enable
LocationEngine
to start updating the user’s location. - Show the user location on the map. To do this, enable
LocationMarker
on the map and set its specifications usingLocationMarkerOptions
.
1private fun showUserLocation() {2 locationEngine = AndroidLocationEngine(context = this)3 locationEngine?.let {4 tomTomMap.setLocationEngine(it)5 it.enable()6 tomTomMap.enableLocationMarker(LocationMarkerOptions(LocationMarkerType.POINTER))7 }8}
Summary
This conversion guide has given you the knowledge to move a basic app from Google’s SDKs to TomTom’s. Now you can enrich your app with TomTom’s features and functions. Check out the documentation to see what you can do.