All tutorials

Android

intermediate

If you are migrating from version 3.x of the Android API Wrapper library, please refer to the Migration Guide from Version 3.x to 4.x for detailed instructions.

The Android API wrapper helps developers easily integrate the what3words API into their Android applications, avoiding the complexity of managing low-level API calls.

The what3words API allows conversion between what3words addresses (e.g., ///index.home.raft) and coordinates (e.g., -0.203586, 51.521251). It features powerful autosuggest functions to validate and autocorrect user input, restrict suggestions to specific areas, request sections of the what3words grid as GeoJSON, and list all supported languages. Advanced users can also post-process voice output with autosuggest.

All coordinates are in latitude, longitude pairs using the WGS-84 standard, with latitudes ranging from -90 to 90.

Full sample app for the wrapper can be found in our Github repo
github icon white Android Sample Apps

1Get an API Key
2Installation

The library is available through Maven Central. Please add the following to your gradle.build:

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


repositories {
    mavenCentral()
}

dependencies {
    implementation("com.what3words:w3w-android-wrapper:$latest_version")
}
Copied
3Setup

Android Manifest

Add to AndroidManifest.xml:

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

    <uses-permission android:name="android.permission.INTERNET" />

    <!-- add if using voice api autosuggest -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>
Copied
4Usage

This step-by-step guide demonstrates the usage of the new Android API Wrapper library using Kotlin Coroutines. For a cleaner architecture or a Java example, refer to the sample app.

We’ve restructured What3WordsV3 into two distinct classes, each serving specific functions:

  1. W3WApiTextDataSource: Handles text-based tasks like address searching and conversions.
  2. W3WApiVoiceDataSource: Specialises in voice-based address suggestions.
5W3WApiTextDataSource

The W3WApiTextDataSource class facilitates the conversion of coordinates to what3words addresses and vice versa, as well as providing suggestions for slightly incomplete what3words addresses.

Create an instance of W3WApiTextDataSource via the factory method:

val textDataSource = W3WApiTextDataSource.create(context, "YOUR_API_KEY")
Copied

If you are running your own Enterprise Suite API Server, specify the URL to your server:

val textDataSource = W3WApiTextDataSource.create(context, "YOUR_API_KEY", "YOUR_SERVER_ENPOINT")
Copied

Convert Coordinates to what3words Address

This function converts coordinates (expressed as latitude and longitude) to a what3words address.

More information about convertTo3wa, including returned results, is available in the what3words REST API documentation.

Find the words for (lat:51.222011, long: 0.152311):

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        val coordinates = W3WCoordinates("51.222011", "0.152311")
        val language = W3WRFC5646Language.EN_GB
        
        CoroutineScope(Dispatchers.IO).launch { 
            // Run to convert method in Dispatchers.IO   
            val result = textDataSource.convertTo3wa(coordinates, language)
            
            //Switch to Dispatcher.Main to update your views with the results if needed
            withContext(Dispatchers.Main) {
                when (result) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> {
                        Log.d("MainActivity", "what3words address: ${result.value.address}")
                    }
                }
            }
        
        }
    }
}
Copied

Convert what3words Address to Coordinates

This function converts a 3 word address to a position, expressed as coordinates of latitude and longitude.

This function takes the words parameter as a string of what3words address e.g.filled.count.soap

More information about convertToCoordinates, including returned results is available in the what3words REST API documentation.

Find the coordinates for ///filled.count.soap:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        val w3wAddress = "filled.count.soap"
        
        CoroutineScope(Dispatchers.IO).launch { 
            val result = textDataSource.convertToCoordinates(w3wAddress)
            withContext(Dispatchers.Main) {
                when (result) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> {
                        Log.d("MainActivity", "Coordinates: ${result.value.center.lat}, ${result.value.center.lng}")
                    }
                }
            }
        }
    }
}
Copied

AutoSuggest

When presented with a what3words address that may be incorrectly entered, AutoSuggest returns a list of potential correct what3wordsaddresses. It needs the first two words plus at least the first character of the third word to produce suggestions.

This method provides corrections for mis-typed words (including plural vs singular), and words being in the wrong order.

Optionally, clipping can narrow down the possibilities, and limit results to:

  • One or more countries
  • A geographic area (a circle, box or polygon)

This dramatically improves results, so we recommend that you use clipping if possible.

To improve results even further, set the focus to user’s current location. This will make autosuggest return results which are closer to the user.

More information about autosuggest, including returned results is available in the what3words REST API documentation.

Example: Basic AutoSuggest call

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        val incompletedW3WAddress = "filled.count.so"
        
        CoroutineScope(Dispatchers.IO).launch { 
            // Run to auto suggest method in Dispatchers.IO   
            val result = textDataSource.autosuggest(incompletedW3WAddress)
            
            //Switch to Dispatcher.Main to update your views with the results if needed
            withContext(Dispatchers.Main) {
                when (result) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> {
                        if (result.value.isNotEmpty()) {
                            Log.d("MainActivity", "Suggestions: ${result.value.joinToString { it.w3wAddress.address }}")
                        } else {
                            Log.d("MainActivity", "No suggestions found")
                        } 
                    }
                }
            }
        }
    }
}
Copied

Get Grid Section

Grid Section returns a section of the what3words 3m x 3m grid as a set of horizontal and vertical lines covering the requested area, which can then be drawn onto a map.

The requested box must not exceed 4km from corner to corner, or a BadBoundingBoxTooBig error will be returned.

More information about gridSection, including returned results is available in the what3words REST API documentation.

Get a grid for (51.222609, 0.152898) in the south-west, and (51.222011, 0.152311) in the north-east:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        
        CoroutineScope(Dispatchers.IO).launch { 
            // Run to gridSection method in Dispatchers.IO   
            val result = w3WApiTextDataSource.gridSection(
                W3WRectangle(W3WCoordinates(51.222609, 0.152898), W3WCoordinates(51.222011, 0.152311)))
            
            //Switch to Dispatcher.Main to update your views with the results if needed
            withContext(Dispatchers.Main) {
                when (result) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> { 
                        val gridSection = result.value
                        // Convert to GeoJSON
                        val geoJsonString = gridSection.toGeoJSON()
                    }
                }
            }
        }
    }
}
Copied

Get Available Languages

This function returns the currently supported languages. It will return the two letter code, and the name of the language both in that language and in English.

More information about availableLanguages, including returned results is available in the what3words REST API documentation.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        
        CoroutineScope(Dispatchers.IO).launch { 
            // Run to availableLanguages method in Dispatchers.IO   
            val result = textDataSource.availableLanguages()
            
            //Switch to Dispatcher.Main to update your views with the results if needed
            withContext(Dispatchers.Main) {
                when (result) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> { 
                        result.value.forEach {
                            Log.d("MainActivity", "languageCode: ${it.code} - locale: ${it.locale}")
                        }
                    }
                }
            }
        }
    }
}
Copied
6W3WApiVoiceDataSource

The W3WApiVoiceDataSource class allows searching for what3words addresses using voice input. Ensure you have a Voice API plan enabled in your account to use this feature.

Create a W3WApiVoiceDataSource Instance:

val voiceDataSource = W3WApiVoiceDataSource("YOUR_API_KEY")
Copied

If you are running your own Enterprise Suite API Server, you can specify the URL to your server:

val voiceDataSource = W3WApiVoiceDataSource("YOUR_API_KEY", "YOUR_SERVER_ENDPOINT")
Copied

Create a W3WMicrophone instance to handle voice recording:

val microphone = W3WMicrophone()
Copied

You can set up callbacks to receive information about the recording progress:

microphone.setEventsListener(object : W3WAudioStream.EventsListener {
    override fun onVolumeChange(volume: Float) {
        
    }

    override fun onError(error: W3WError) {
        
    }

    override fun onAudioStreamStateChange(state: W3WAudioStreamState) {
        
    }
})
Copied

Perform Voice AutoSuggest

The Voice API AutoSuggest allows the user to say what3words and using speech recognition technology displays what3words address suggestions to the user.

Before enabling Voice AutoSuggest you will need to add a Voice API plan in your account.

For a full working example with voice and AUDIO_RECORD permission, request check our sample app.

Note: Please bear in mind that the Android Emulator cannot record audio. Therefore, you will need to test on a real device that can record.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        
        val voiceLanguage = W3WRFC5646Language.EN_GB

        CoroutineScope(Dispatchers.IO).launch { 
            // Perform the Voice AutoSuggest in Dispatchers.IO
            voiceDataSource.autosuggest(
                microphone,
                voiceLanguage,
                null, // W3WAutosuggestOptions
                null, // onSpeechDetected
            ) { result ->
                //Switch to Dispatcher.Main to update your views with the results if needed
                withContext(Dispatchers.IO) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> {
                        if (result.value.isNotEmpty()) {
                            Log.d("MainActivity", "Suggestions: ${result.value.joinToString { it.w3wAddress.address }}")
                        } else {
                            Log.d("MainActivity", "No suggestions found")
                        } 
                    }
                }
            }
        }
    }
}
Copied
7Using AutosuggestHelper Class

Add what3words AutoSuggest to an existing text field

Add the API and helper wherever you make your class variables and be sure to use your API key:

val dataSource = W3WApiTextDataSource.create(context, "YOUR_API_KEY_HERE")
val autosuggestOptions = W3WAutosuggestOptions.Builder().
    .focus(...)
    .clipToCountry(...)
    // others options as well
    .build()

val autosuggestHelper = AutosuggestHelper(dataSource).options(autosuggestOptions)
Copied

Next step is to use a TextWatcher (or doOnTextChanged EditText extension) and let AutoSuggestHelper know about the changed text and add what3words suggestion data to your existing RecyclerView/Adapter. (check sample for complete working example with custom data model and RecyclerView adapter to show different autosuggest sources and EditText and RecyclerView setup.

 
editText.doOnTextChanged { text, _, _, _ -> 
	// update options in case of new clippings applying/changing dynamically i.e: Location.  
	autosuggestHelper.options(autosuggestOptions).update(  
	    text.toString(),  
	    onSuccessListener = { suggestionResults ->  
		suggestionResults.forEach { suggestion ->  
		    //Add suggestion to existing RecyclerView adapter
	            list.add(suggestion)
	            Log.i("MainActivity", suggestion.w3wAddress.address)  
	        } 
	        //notify adapter that there's changes on the data. 
		adapter.notifyDataSetChanged()  
	    },  
	    onFailureListener = {  
                //log any errors returned by what3words API.
	        Log.e("MainActivity", it.message)  
	    }  
	)
}
Copied

Get the full what3words address once the user has selected a row

When user selects a row from the RecyclerView autosuggestHelper.selected() or autosuggestHelper.selectedWithCoordinates() should be called to retrieve the full what3words address with or without coordinates.

Note: that selectedWithCoordinates() will convert the what3words address to a lat/lng which will count against your plan’s quota.

autosuggestHelper.selectedWithCoordinates(  
    query.text.toString(),  
    selectedSuggestion,  
    onSuccessListener = { suggestion ->
        Log.d("MainActivity", "suggestion selected from what3words: ${suggesstion.w3wAddress.address}, lat=${suggestion.w3wAddress.center?.lat} lng=${suggestion.w3wAddress.center?.lng}")
    },  
    onFailureListener = {  
	    Log.e("MainActivity", it.message)  
    }  
)
Copied
8RegEx Functions

This section introduces RegEx functions that can assist with checking and finding possible what3words addresses in strings. The three main functions covered are:

  • isPossible3wa – Match what3words address format;
  • findPossible3wa – Find what3words address in Text;
  • isValid3wa – Verify a what3words address with the API;

isPossible3wa

Our API wrapper RegEx function “isPossible3wa” can be used used to detect if a text string (like “filled.count.soap“) in the format of a what3words address without having to ask the API. This functionality checks if a given string could be a what3words address. It returns true if it could be, otherwise false.

Note: This function checks the text format but not the validity of a what3words address. Use isValid3wa to verify validity.

com.what3words.javawrapper.What3WordsV3.isPossible3wa("filled.count.soap") returns true
com.what3words.javawrapper.What3WordsV3.isPossible3wa("not a 3wa") returns false
com.what3words.javawrapper.What3WordsV3.isPossible3wa("not.3wa address") returns false
Copied

findPossible3wa

Our API wrapper RegEx function “findPossible3wa” can be used to detect a what3words address within a block of text, useful for finding a what3words address in fields like Delivery Notes. For example, it can locate a what3words address in a note like “Leave at my front door ///filled.count.soap”. The function will match if there is a what3words address within the text. If no possible addresses are found, it returns an empty list.

Note:

  • This function checks the text format but not the validity of a what3words address. Use isValid3wa to verify validity.
  • This function is designed to work across languages but do not work for Vietnamese (VI) due to spaces within words.
com.what3words.javawrapper.What3WordsV3.findPossible3wa("Please leave by my porch at filled.count.soap") returns ["filled.count.soap"]
com.what3words.javawrapper.What3WordsV3.findPossible3wa("Please leave by my porch at filled.count.soap or deed.tulip.judge") returns ["filled.count.soap", "deed.tulip.judge"]
com.what3words.javawrapper.What3WordsV3.findPossible3wa("Please leave by my porch at") returns []
Copied

isValid3wa

Our API wrapper RegEx function “isValid3wa” can be used to determine if a string is a valid what3words address by checking it against the what3words RegEx filter and verifying it with the what3words API.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        
        CoroutineScope(Dispatchers.IO).launch { 
            // Run to gridSection method in Dispatchers.IO   
            val result = w3WApiTextDataSource.isValid3wa("filled.count.soap")
            
            //Switch to Dispatcher.Main to update your views with the results if needed
            withContext(Dispatchers.Main) {
                when (result) {
                    is W3WResult.Failure -> {
                        Log.e("MainActivity", "Error: ${result.message}")
                    }
                    is W3WResult.Success -> {
                      Log.d("MainActivity", "isValid: ${result.value}")
                    }
                }
            }
        }
    }
}
Copied
9Troubleshooting

If you encounter errors or issues related to convert-to-coordinate 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. Please upgrade your usage 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 AppServer and ScriptingAdd a 3 word address input fieldUse 3 word addresses with a mapUse 3 word addresses with voice inputUse 3 word addresses within an address searchAndroid

Related tutorials