All tutorials

Using the Android Map Component

intermediate

Introduction

The easiest way to add what3words to your technology is to use one of our components. We have several components available for JavaScript, iOS, and Android which require minimal development to integrate.

The what3words Android Map Component provides a straightforward way to add a what3words grid on top of Google Maps or Mapbox map, displaying the what3words address and marker on the map for a selected 3 word address.

This tutorial steps through how our Android Map Component can be added to a new project that requires creating a map from scratch or to an existing map:

  • If you are creating a new map from scratch using our Map component then we recommend using our map fragments: W3WGoogleMapFragment or W3WMapboxMapFragment if the map provider is respectively Google Maps or MapBox;
  • If you want to add what3words to an existing map then we recommend using our map wrappers: W3WGoogleMapsWrapper or W3WMapBoxWrapper if the map provider is respectively Google Maps or MapBox.

Follow the steps below to select your chosen way to integrate our what3words map component into your project.

GitHub repo: https://github.com/what3words/w3w-android-map-components

Quickstart

The Android Map Component requires just a few lines of code to be added to an android application to create a map with what3words functionality.

  • Replace YOUR-API-KEY with your what3words API key and any map provider API key that you would like to use on your project, e.g. GOOGLE MAPS or MAPBOX API keys.
  • It is compatible with applications that are built using Android SDK 23 or higher.

Here are listed some sample apps that can be used:

android_map_component_final_result

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)

        // add AutoSuggest Component to the Map Component
        binding.autosuggest.apiKey("YOUR_API_KEY_HERE")
        .returnCoordinates(true)
        .onSuggestionSelected { square ->
            if (square != null) {
                map.selectAtSquare(square)
            } else {
                map.unselect()
            }
        }
    }

    override fun onMapReady(map: W3WMap) {
        // add this to integrate the AutoSuggest Component
        this.map = map

        map.addMarkerAtCoordinates(lat: 51.5209894, lng: -0.1956749, markerColor = W3WMarkerColor.YELLOW)

        map.onSquareSelected(
            onSuccess = { square, _, _ ->
                // add this to bind the AutoSuggest Component to the Map Component            
                binding.autosuggest.display(square)

                Snackbar.make(binding.root, square.words, Snackbar.LENGTH_INDEFINITE).show()
            }
        )
    }
}
Copied

Step by Step

1Get API key
2Get Google API key

You also will need to get a Google API key or Mapbox API key for your chosen map provider.

3Add the dependency

Open your project in Android Studio
Open up your module-level build.gradle file.
Make sure that your project’s minSdkVersion is at API 23 or higher.

 android {
...
    defaultConfig {
            minSdkVersion 23
    }
}
Copied

Under dependencies, add a new build rule for the latest what3words Android Map Component.

dependencies {
    implementation 'com.what3words:w3w-android-map-components:1.0.1'
}
Copied

Add this snippet to the build.gradle file (app level)

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
Copied

Add also the following proguard rules

-keep class com.what3words.javawrapper.request.* { *; }
-keep class com.what3words.javawrapper.response.* { *; }
Copied

Because you’ve edited your Gradle files, Android Studio will ask you whether you want to sync the Gradle files. You can sync now.

To perform network operations in your application, your manifest AndroidManifest.xml file must include the following permissions:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yourpackage.yourapp">

    <uses-permission android:name="android.permission.INTERNET" />
    ...
Copied
4New app with Google Maps

If you are starting a new project and you are creating a new app from scratch, we recommend using our W3WGoogleMapFragment. The main advantage is that all the required events to draw the grid are done under the hood, resulting in less boilerplate code and still having access to Google Maps to apply standard customisation (i.e. map types, etc.).
To use the what3words Google Maps Fragment in your app, first, follow the quick start tutorial on the Google developer portal here. This ensures that Google Maps can be used with the what3words Map Fragment.

After a successful Google Maps run, you can start using our W3WGoogleMapFragment following these steps.

Add the following line of code to your activity_main.xml file within the res folder of your application:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/map"
    android:name="com.what3words.components.maps.views.W3WGoogleMapFragment"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    tools:context=".MapActivity"
/>
Copied

Add what3words Google Maps Fragment to your MapsActivity.kt file. You will need to add your what3words API key here to display the Map Fragment.

Note: After adding this snippet run your application and you will display Google Maps with the what3words grid on top of it.

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }

    override fun onMapReady(map: W3WMap) {
    }
}
Copied

Customise the Map Component

The Map Component can be customised using some what3words properties. Here is shown an example where you can add a simple market to your Map with a specified what3words address

customise_map_component

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }


    override fun onMapReady(map: W3WMap) {
        // set a marker with a specified what3words address
        map.addMarkerAtWords("filled.count.soap")
    }
}
Copied

You can set a language to get all the 3wa in the desired language (default English) by adding this line of code within the onMapReady function:

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }

    override fun onMapReady(map: W3WMap) {
        //set language to get all the what3words addresses in the desired language (default english)
            map.setLanguage("en")
        map.addMarkerAtWords("filled.count.soap")
    }
} 
Copied

You can make the map marker change color or their zoom level or add a list of specified what3words addresses.

Note: the default colour of the marker is the brand’s red.

multiple_markers

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }

    override fun onMapReady(map: W3WMap) {
        map.setLanguage("en")

    // an example on how to add a blue marker on a valid 3 word address and move the map view(camera) to the added marker
        map.addMarkerAtWords(
            listOf("filled.count.soap","stop.vibrates.looked"),
            markerColor = W3WMarkerColor.TURQUOISE,
            zoomOption = W3WZoomOption.CENTER_AND_ZOOM
        )   
    }
}
Copied

You can add a map marker using coordinates instead of the what3words address.

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }

    override fun onMapReady(map: W3WMap) {
        // set a marker using coordinates
        map.addMarkerAtCoordinates(51.5209894, -0.1956749, markerColor = W3WMarkerColor.YELLOW)
    }
}
Copied

Access the map instance

To access the Google map instance inside the Google Map Fragment you will need to add this line of code to your application:

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }

    override fun onMapReady(map: W3WMap) {
        map.addMarkerAtCoordinates(51.5209894, -0.1956749, markerColor = W3WMarkerColor.YELLOW)

        //if you want to access the google map instance inside W3WGoogleMapFragment do the following
        (map as? W3WGoogleMapFragment.Map)?.googleMap()?.let { googleMap ->
            googleMap.mapType = GoogleMap.MAP_TYPE_NORMAL
        }
    }
}
Copied

Here is what your application should look like:

marker_with_coordinates

Listening for events

Now when you click on the map marker you can display the what3words address if you trigger the onSquareSelected event.

Note: Only one square can be selected at the same time, just like our core apps.

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)
    }

    override fun onMapReady(map: W3WMap) {
        map.addMarkerAtCoordinates(51.5209894, -0.1956749, markerColor = W3WMarkerColor.YELLOW)

        // set up a a callback for when an square in the map is selected
        map.onSquareSelected(
            onSuccess = { square, _, _ ->
                Snackbar.make(binding.root, square.words, Snackbar.LENGTH_INDEFINITE).show()
            }
        )
    }
}
Copied

Use AutoSuggest Component in the Search field

If you want to add the AutoSuggest Component to the search box on top of the Map Fragment, you need to update the activity_maps.xml to both have the what3words components, the W3WAutosuggestEditText (for the AutoSuggest Component) and W3WGoogleMapFragment (for the Map Component).

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/map"
    android:name="com.what3words.components.maps.views.W3WGoogleMapFragment"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    tools:context=".MapActivity"
/>

<com.what3words.components.text.W3WAutoSuggestEditText
    android:id="@+id/autosuggest"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" 
/>
Copied

Now you need to set up the what3words AutoSuggest component with your API KEY to return coordinates so you can integrate it into the Map component without extra API calls.

Note: As it is set up on our core app, you will be able to set that up when a suggestion is selected from the AutoSuggest Component it will select a what3words address on the map.

class MainActivity : AppCompatActivity(), W3WGoogleMapFragment.OnMapReadyCallback {
    private lateinit var binding: ActivityMapsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMapsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as W3WGoogleMapFragment
        mapFragment.apiKey("YOUR_API_KEY_HERE", this)

        // add AutoSuggest Component to the Map Component
        binding.autosuggest.apiKey("YOUR_API_KEY_HERE")
        .returnCoordinates(true)
        .onSuggestionSelected { square ->
            if (square != null) {
                map.selectAtSquare(square)
            } else {
                map.unselect()
            }
        }
    }

    override fun onMapReady(map: W3WMap) {
        // add this to integrate the AutoSuggest Component
        this.map = map

        map.addMarkerAtCoordinates(lat: 51.5209894, lng: -0.1956749, markerColor = W3WMarkerColor.YELLOW)

        map.onSquareSelected(
            onSuccess = { square, _, _ ->
                // add this to bind the AutoSuggest Component to the Map Component            
                binding.autosuggest.display(square)

                Snackbar.make(binding.root, square.words, Snackbar.LENGTH_INDEFINITE).show()
            }
        )
    }
}
Copied

Here is what your application should look like:

android_map_component_final_result

Select Map Provider

Our Map Component can support different map service providers, such as Google Maps and Mapbox. By simply replacing the Google Map fragment used in the examples above W3WGoogleMapFragment with the Mapbox Map Fragment W3WMapboxMapFragment in your activity_main.xml and MapsActivity.kt files.

Note: To use the what3words Mapbox Maps Fragment in your app, first follow the quick start tutorial on the Mapbox developer portal here. This ensures that Mapbox Maps can be used with the what3words Fragment.

5Existing app with Google Maps

If you already have an application we recommend using our what3words Google Map Wrapper in your app.
To get started first follow the quick start tutorial on the Google developer portal here. This ensures that Google Maps can be used with the what3words Map Wrapper.
After a successful Google Maps run, you can start using our W3WGoogleMapWrapper following these steps:
Add the following line of code to your activity_main.xml file within the res folder of your application:

<?xml version="1.0" encoding="utf-8"?>
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
/>
Copied

Add what3words Google Maps Wrapper to your MapsActivity.kt file. You will need to add your what3words API key here to display the Map Wrapper.

class MainActivity : AppCompatActivity(), OnMapReadyCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    }

    override fun onMapReady(map: GoogleMap) {
        val apiWrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val googleMapsWrapper = W3WGoogleMapsWrapper(
            this,
            map,
            apiWrapper
        )
    }
}
Copied

After adding this snippet run your application and you will display Google Maps with the what3words grid on top of it.

Customise the Map Component

The Map Component can be customised using some what3words properties. Here is shown an example where you can

  • add a simple market to your Map with a specified what3words address;
  • set your own zoom level;
  • set the language of the what3words addresses;
class MainActivity : AppCompatActivity(), OnMapReadyCallback {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    override fun onMapReady(map: GoogleMap) {
        val apiWrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val googleMapsWrapper = W3WGoogleMapsWrapper(
            this,
            map,
            apiWrapper
        ).setLanguage("en") // set the language of the what3words addresses

        //show an example on how to add a blue marker 
        //on a valid 3 word address and move the camera to the added marker.
        googleMapsWrapper.addMarkerAtWords(
            "filled.count.soap",
            markerColor.BLUE,
            { marker ->
                val cameraPosition = CameraPosition.Builder()
                    .target(LatLng(marker.coordinates.lat, marker.coordinates.lng))
                    .zoom(19f)
                    .build()
                p0.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
            }, { error ->
                Log.e("MainActivity", "${error.message}")
            }
        )
    }
}
Copied

Listening for events

Using an event listener, it is possible to fire other functionality in an app when something changes in the Map Component. For example, it is possible to listen for when a square on the grid map has been selected by the users or to listen for when new coordinates have been returned and pan/zoom a map to the location.

class MainActivity : AppCompatActivity(), OnMapReadyCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    }

    override fun onMapReady(map: GoogleMap) {
        val apiWrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val googleMapsWrapper = W3WGoogleMapsWrapper(
            this,
            map,
            apiWrapper
        )

        //example how to add a blue marker on a valid 3 word address and move camera to the added marker.
        googleMapsWrapper.addMarkerAtWords(
            "filled.count.soap",
            markerColor.BLUE,
            { marker ->
                val cameraPosition = CameraPosition.Builder()
                    .target(LatLng(marker.coordinates.lat, marker.coordinates.lng))
                    .zoom(19f)
                    .build()
                p0.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
            }, { error ->
                Log.e("MainActivity", "${error.message}")
            }
        )

        //Using an event listener → click on existing what3words markers on the map.
        w3wMapsWrapper.onMarkerClicked { marker ->
            Log.i("MainActivity", "clicked: ${marker.words}")
        }

        //REQUIRED
        map.setOnCameraIdleListener {
            //existing code here...

            //needed to draw the 3x3m grid on the map
            googleMapsWrapper.updateMap()
        }

        //REQUIRED
        map.setOnCameraMoveListener {
            //existing code here...

            //needed to draw the 3x3m grid on the map
            googleMapsWrapper.updateMove()
        }
    }
}
Copied

Set coordinates per selected marker

Here is an example of how to select a 3x3m what3words square using coordinates:

class MainActivity : AppCompatActivity(), OnMapReadyCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)

    }

    override fun onMapReady(map: GoogleMap) {
        val apiWrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val googleMapsWrapper = W3WGoogleMapsWrapper(
            this,
            map,
            apiWrapper
        )

        … 
        map.setOnMapClickListener { latLng ->
            //existing code here...

            //example of how to select a 3x3m what3words square using lat/lng
            googleMapsWrapper.selectAtCoordinates(latLng.latitude, latLng.longitude)
        }
    }
}
Copied
6Existing app with Mapbox

If you already have an application we recommend using our what3words Mapbox Wrapper in your app.
To get started first follow the quick start tutorial on the Mapbox developer portal here. This ensures that Mapbox can be used with the what3words Map Wrapper.

After a successful Google Maps run, you can start using our W3WMapboxWrapper following these steps.

Add the following line of code to your activity_main.xml file within the res folder of your application:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.mapbox.maps.MapView android:id="@+id/mapView" android:layout_width="0dp"
        android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Copied

Add what3words Mapbox Wrapper to your MapsActivity.kt file. You will need to add your what3words API key here to display the Map Wrapper.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.mapView.getMapboxMap().loadStyleUri(Style.MAPBOX_STREETS)
        setContentView(binding.root)

        val wrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val mapboxWrapper = W3WMapBoxWrapper(
            this,
            binding.mapView.getMapboxMap(),
            wrapper,
        )
    }
}
Copied

After adding this snippet run your application and you will display the Mapbox with the what3words grid on top of it.

Customise the Map Component

The Map Component can be customised using some what3words properties. Here is shown an example where you can

  • add a simple market to your Map with a specified what3words address;
  • set your own zoom level;
  • set the language of the what3words addresses;
class MainActivity: AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.mapView.getMapboxMap().loadStyleUri(Style.MAPBOX_STREETS)
        setContentView(binding.root)

        val wrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val mapboxWrapper = W3WMapBoxWrapper(
            this,
            binding.mapView.getMapboxMap(),
            wrapper,
        ).setLanguage("en") // set the language of the what3words addresses

        //show an example on how to add a blue marker 
        //on a valid 3 word address and move the camera to the added marker.
        mapboxWrapper.addMarkerAtWords(
            "filled.count.soap",
            markerColor.BLUE,
            { marker ->

            }, { error ->
                Log.e("MainActivity", "${error.message}")
            }
        )
    }
}
Copied

Listening for events

Using an event listener, it is possible to fire other functionality in an app when something changes in the Map Component. For example, it is possible to listen for when a square on the grid map has been selected by the users or to listen for when new coordinates have been returned and pan/zoom a map to the location.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.mapView.getMapboxMap().loadStyleUri(Style.MAPBOX_STREETS)
        setContentView(binding.root)

        val wrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val mapboxWrapper = W3WMapBoxWrapper(
            this,
            binding.mapView.getMapboxMap(),
            wrapper,
        ).setLanguage("en") // set the language of the what3words addresses

        //show an example on how to add a blue marker 
        //on a valid 3 word address and move the camera to the added marker.
        mapboxWrapper.addMarkerAtWords(
            "filled.count.soap",
            markerColor.BLUE,
            { marker ->

            }, { error ->
                Log.e("MainActivity", "${error.message}")
            }
        )

        //Using an event listener → click on existing what3words markers on the map.
        mapboxWrapper.onMarkerClicked {
            Log.i("MainActivity", "clicked: ${it.words}")
        }

        //REQUIRED
        binding.mapView.getMapboxMap().addOnMapIdleListener {
            //existing code here...

            //needed to draw the 3x3m grid on the map
            mapboxWrapper.updateMap()
        }

        //REQUIRED
        binding.mapView.getMapboxMap().addOnCameraChangeListener {
            //existing code here...

            //needed to draw the 3x3m grid on the map
            mapboxWrapper.updateMove()
        }
    }
}
Copied

Set coordinates per selected marker

Here is an example of how to select a 3x3m what3words square using coordinates:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.mapView.getMapboxMap().loadStyleUri(Style.MAPBOX_STREETS)
        setContentView(binding.root)

        val wrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val mapboxWrapper = W3WMapBoxWrapper(
            this,
            binding.mapView.getMapboxMap(),
            wrapper,
        ).setLanguage("en") // set the language of the what3words addresses

        //show an example on how to add a blue marker 
        //on a valid 3 word address and move the camera to the added marker.
        mapboxWrapper.addMarkerAtWords(
            "filled.count.soap",
            markerColor.BLUE,
            { marker ->

            }, { error ->
                Log.e("MainActivity", "${error.message}")
            }
        )

        ... 
        binding.mapView.getMapboxMap().addOnMapClickListener { latLng ->
            //existing code here...

            //example of how to select a 3x3m what3words square using lat/lng
            mapboxWrapper.selectAtCoordinates(latLng.latitude(), latLng.longitude())
            true
        }
    }
}
Copied
7Configuring for use with API server

If you run our Enterprise Suite API Server yourself, you may specify the URL to your own server by adding this line of code to the Map Component:

val wrapper = What3WordsV3("YOUR_API_KEY_HERE", "https://api.yourserver.com", this)
Copied
8Use library with Jetpack Compose

Both Google Maps and Mapbox Wrapper and Fragment work with Jetpack Compose using AndroidView and AndroidViewBinding, these modules are all available in our GitHub repository as examples of usage of our w3w-android-map-components library in a Jetpack Compose app.

9Map Component Functions
Method NameDescriptionExample
addMarkerAtCoordinatesThis method allow you to add a marker/square to the map defined by the latitude and longitude provided.addMarkerAtCoordinates(49.180803, -8.001330, { marker }, { error }) or add multiple Coordinates to the map: addMarkerAtCoordinates(listOf(Pair(49.180803, -8.001330), Pair(50.180803, -8.001330)), { markers }, { error }) Example: key=Your-API-Key
addMarkerAtSuggestionThis method allow you to add a marker/square to the map after getting the what3words suggestion from our W3WAutosuggestEditText allowing easy integration between both components autosuggest and maps.addMarkerAtSuggestion(suggestion, markerColor.RED, { marker }, { error }) or add multiple suggestions to the map: addMarkerAtSuggestion(suggestions, markerColor.RED, { markers }, { error })
addMarkerAtWordsThis method allow you to add a marker/square to the map if the parameter is valid what3words address, e.g. filled.count.soap. If it's not valid, onError will be called returning APIResponse.What3WordsError.BAD_WORDS.addMarkerAtWords("filled.count.soap"), markerColor.RED, { marker }, { error }) or add multiple 3 word addresses to the map: addMarkerAtWords(listOf("filled.count.soap", "index.home.raft"), markerColor.RED, { markers }, { error })
findMarkerByCoordinatesfindMarkerByCoordinates This method allow you to find a marker added to the map (returns null if no marker is added on the specified coordinates).val marker = findMarkerByCoordinates(50.180803, -8.001330)
getAllMarkersThis method allow you to get all added markers from the map.val markers = getAllMarkers()
getSelectedMarkerThis method allow you to return a selected marker from the map.val selected_markers = getSelectedMarker()
gridEnabledThis method allow you to enalbe the grid overlay over the map with all 3mx3m squares on the visible map bounds, enabled by default.gridEnabled(true)
handleZoomOption| handleZoomOption | This method allow you to define the zoom options. | handleZoomOption(latLng: LatLng, zoomOption: W3WZoomOption) | handleZoomOption(latLng: LatLng, zoomOption: W3WZoomOption)
removeAllMarkersThis method allow you to remove all markers added to the map.removeAllMarkers()
removeMarkerAtCoordinates This method allow you to remove a marker defined by coordinates from the map.removeMarkerAtCoordinates(50.180803, -8.001330) or remove multiple markers at coordinates from the map: removeMarkerAtCoordinates(listOf(Pair(49.180803, -8.001330), Pair(50.180803, -8.001330))
removeMarkerAtSuggestionremoveMarkerAtSuggestion This method allow you to remove a marker defined by a what3words suggestion from the map.removeMarkerAtSuggestion(suggestion) or remove multiple suggestions: removeMarkerAtSuggestion(suggestions)
removeMarkerAtWordsThis method allow you to remove a marker at what3words address from the map.removeMarkerAtWords("filled.count.soap") or remove multiple markers at 3 word adresses from the map: removeMarkerAtWords(listOf("filled.count.soap", "index.home.raft"))
selectAtCoordinatesThis method allow you to set coordinates for a selected marker on the map. It can only have one selected marker at the time.selectAtCoordinates(50.180803, -8.001330, { selectedMarker }, { error }
selectAtSquareThis method allow you to set square for a selected marker on the map. It can only have one selected marker at the time.selectAtSquare(square: SuggestionWithCoordinates, zoomOption: W3WZoomOption, onSuccess: Consumer?, onError: Consumer<apiresponse.what3wordserror>?) {}</apiresponse.what3wordserror>
selectAtSuggestionThis method allow you to set suggestion for a selected marker on the map. It can only have one selected marker at the time.selectAtSuggestion(suggestion, { selected marker }, { error })
selectAtWordsThis method allow you to set 3 word address for a selected marker on the map. It can only have one selected marker at the time.selectAtWords("filled.count.soap", { selectedMarker }, { error })
setGridColorThis method allow you to set a different color to the Grid when the background mode is dark or light. To be noted that map providers have different Dark/Light modes settings i.e: GoogleMaps sets dark mode using JSON styles but Mapbox has dark mode as a MapType. [GridColor.AUTO] - Will leave up to the library to decide which Grid color and selected square color to use to match some specific map types, i.e: use [GridColor.DARK] on normal map types, [GridColor.LIGHT] on Satellite and Traffic map types. [GridColor.LIGHT] - Will force grid and selected square color to be light. [GridColor.DARK] - Will force grid and selected square color to be dark.setGridColor(gridColor: GridColor.LIGHT)
setLanguageThis method allow you to set the default language for all the calls that the map makes to the API. The parameter should be a supported what3words address language as an ISO 639-1 2 letter code. Defaults to en (English).setLanguage("en")
unselectThis method allow you to remove the selected marker from the map.unselect()
updateMapThis method allow you to refresh the grid bounds and draw the grid. This method should be called on GoogleMap.setOnCameraIdleListener or MapboxMap.addOnMapIdleListener. Enabled is set to true (default)*updateMap()*
updateMoveThis method allow you to swap from markers to squares and show/hide grid when zoom goes higher or lower than the zoom level threshold. This method should be called on GoogleMap.setOnCameraMoveListener or MapboxMap.addOnCameraChangeListener. Enabled is set to true (default)*updateMove()*
10Events
EventDescriptionExample
onMarkerClickedThis method allow you to set up a callback for when an existing marker is clicked on the map.onMarkerClicked { marker }
onSquareSelectedThis method allow you to set up a callback for when a square is selected either by clicking on the map or programmatically using any of [selectAtWords], [selectAtCoordinates], [selectAtSuggestion].map.onSquareSelected(onSuccess = { square, _, _ Snackbar.make(binding.root, square.words, Snackbar.LENGTH_INDEFINITE).show()})

Listening for events

Using an event listener, it is possible to fire other functionality in an app when something changes in the Map Component. For example, when you click on the map marker you can display the what3words address if you trigger the onSquareSelected event.

Note: Only one square can be selected at the same time, just like our core apps.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.mapView.getMapboxMap().loadStyleUri(Style.MAPBOX_STREETS)
        setContentView(binding.root)

        val wrapper = What3WordsV3("YOUR_API_KEY_HERE", this)
        val mapboxWrapper = W3WMapBoxWrapper(
            this,
            binding.mapView.getMapboxMap(),
            wrapper,
        ).setLanguage("en") // set the language of the what3words addresses

        //show an example on how to add a blue marker 
        //on a valid 3 word address and move the camera to the added marker.
        mapboxWrapper.addMarkerAtWords(
            "filled.count.soap",
            markerColor.BLUE,
            { marker ->

            }, { error ->
                Log.e("MainActivity", "${error.message}")
            }
        )

        //Using an event listener → click on existing what3words markers on the map.
        mapboxWrapper.onMarkerClicked {
            Log.i("MainActivity", "clicked: ${it.words}")
        }

        //REQUIRED
        binding.mapView.getMapboxMap().addOnMapIdleListener {
            //existing code here...

            //needed to draw the 3x3m grid on the map
            mapboxWrapper.updateMap()
        }

        //REQUIRED
        binding.mapView.getMapboxMap().addOnCameraChangeListener {
            //existing code here...

            //needed to draw the 3x3m grid on the map
            mapboxWrapper.updateMove()
        }
    }
}
Copied
11Troubleshooting

If you encounter errors or issues related to convert-to-coordinate, convert-to-3wa and grid-section requests while using the Free plan, please check the network panel for the following error message Error 402 payment required and its response, indicating the need to upgrade to a higher plan:

{
    "error": {
        "code": "QuotaExceeded",
        "message": "Quota exceeded or API plan does not have access to this feature. Please change your plan at https://accounts.what3words.com/select-plan, or contact support@what3words.com"
    }
}
Copied

For more information, visit our API plans page. If you need further assistance, contact support@what3words.com.

Mobile AppAdd a 3 word address input fieldDisplay a 3 word addressUse 3 word addresses with a mapUse 3 word addresses within an address searchAndroid

Related tutorials