Learn how to find an address or place with a search bar and the Geocoding service.
    
Geocoding is the process of converting address or place text into a location. The geocoding service can search for an address or a place and perform reverse geocoding.
In this tutorial, you use a search bar in the user interface to access the geocoding service and search for addresses and places.
To learn how to use the geocoding service to reverse geocode, visit the Reverse geocode tutorial.
Prerequisites
Before starting this tutorial:
- 
You need an ArcGIS Location Platform or ArcGIS Online account.
 - 
Confirm that your system meets the system requirements.
 - 
An IDE for Android development in Kotlin.
 
Steps
Get an access token
You need an access token to use the location services used in this tutorial.
- 
Go to the Create an API key tutorial to obtain an access token using your ArcGIS Location Platform or ArcGIS Online account.
 - 
Ensure that the following privileges are enabled: Location services > Basemaps > Basemap styles service and Location services > Geocoding.
 - 
Copy the access token as it will be used in the next step.
 
To learn more about other ways to get an access token, go to Types of authentication.
Open an Android Studio project
- 
To start this tutorial, complete the Display a map tutorial. Or download and unzip the Display a map solution in a new folder.
 - 
Modify the old project for use in this new tutorial. Expand More info for instructions.
- 
On your file system, delete the .idea folder, if present, at the top level of your project.
 - 
In the Android tool window, open app > res > values > strings.xml.
In the
<string name="appelement, change the text content to Search for an address._name" > strings.xmlUse dark colors for code blocks 1 2 4 5Change line <resources> <string name="app_name">Search for an address</string> </resources> - 
In the Android tool window, open Gradle Scripts > settings.gradle.
Change the value of
rootto "Search for an address".Project.name settings.gradleUse dark colors for code blocks 23 24Change line rootProject.name = "Search for an address" include ':app' - 
Click File > Sync Project with Gradle files. Android Studio will recognize your changes and create a new .idea folder.
 
 - 
 - 
Set the API key using the copied access token.
- 
In Android Studio: in the Android tool window, open app > java > com.example.app > MainActivity.
 - 
In the
setmethod, find theApi Key For App() ArcGIScall and paste your access token inside the double quotes, replacing YOUR_ACCESS_TOKEN.Runtime Environment.set Api Key(" YOUR _ACCESS _TOKE N") MainActivity.ktUse dark colors for code blocks private fun setApiKeyForApp(){ ArcGISRuntimeEnvironment.setApiKey("YOUR_ACCESS_TOKEN") } 
 - 
 
Add import statements
Modify import statements to reference the packages and classes required for this tutorial.
- 
In Android Studio, in the Android tool window, open app > java > com.example.app > MainActivity.
 - 
Replace app-specific import statements with the imports needed for this tutorial.
MainActivity.ktUse dark colors for code blocks 17 18 19 20 21 39 40Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line Change line package com.example.app import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import android.graphics.Color import android.util.Log import android.widget.SearchView import android.widget.Toast import com.esri.arcgisruntime.ArcGISRuntimeEnvironment import com.esri.arcgisruntime.mapping.ArcGISMap import com.esri.arcgisruntime.mapping.BasemapStyle import com.esri.arcgisruntime.mapping.Viewpoint import com.esri.arcgisruntime.mapping.view.Graphic import com.esri.arcgisruntime.mapping.view.GraphicsOverlay import com.esri.arcgisruntime.mapping.view.MapView import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol import com.esri.arcgisruntime.symbology.TextSymbol import com.esri.arcgisruntime.tasks.geocode.GeocodeParameters import com.esri.arcgisruntime.tasks.geocode.GeocodeResult import com.esri.arcgisruntime.tasks.geocode.LocatorTask import com.example.app.databinding.ActivityMainBinding 
Declare graphics overlay and locator task and initialize map view
A graphics overlay is a container for graphics. A locator task converts an address to a point. You will create the properties graphics and locator for use later in later steps. Next you will initialize the map.
- 
In the
Mainmethod, create a lazy property namedActivity graphicsthat references a newOverlay Graphicsfor storing geocode result graphics (address location and label).Overlay Since
graphicsis a lazy property, aOverlay Graphicswill not be created until the property is initialized, which occurs in theOverlay setupmethod that you will modify shortly.Map() MainActivity.ktUse dark colors for code blocks 42 43 44 45 46 47 48 49 50 51 55Add line. Add line. Add line. class MainActivity : AppCompatActivity() { private val activityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) } private val mapView: MapView by lazy { activityMainBinding.mapView } private val graphicsOverlay: GraphicsOverlay by lazy { GraphicsOverlay() } - 
Create a property named
locatorthat references a newTask Locatorfor geocoding an address.Task MainActivity.ktUse dark colors for code blocks 42 43 44 45 46 47 48 49 50 51 52 53 54 55Add line. class MainActivity : AppCompatActivity() { private val activityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) } private val mapView: MapView by lazy { activityMainBinding.mapView } private val graphicsOverlay: GraphicsOverlay by lazy { GraphicsOverlay() } private val locatorTask = LocatorTask("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer") - 
At the end of the
setupmethod, initialize theMap mapby calling the scope functionView applyand passing a lambda expression that does the following:- assigns the local variable 
arcto theGI Smap mapproperty - creates a 
Viewpointand pass it tosetViewpoint()  - adds 
graphicsto theOverlay graphicscollection.Overlays  
Declared at the start of the
Mainclass, the lazy propertyActivity graphicsis initialized at its first access, which is in this lambda expression. The newOverlay Graphicsis not created until now.Overlay MainActivity.ktUse dark colors for code blocks 87 88 89 90 91 101 102Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. // set up your map here. You will call this method from onCreate() private fun setupMap() { // create a map with the BasemapStyle topographic val arcGISmap = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) mapView.apply { // set the map to be displayed in the layout's MapView map = arcGISmap // set the viewpoint, Viewpoint(latitude, longitude, scale) setViewpoint(Viewpoint(34.0270, -118.8050, 72000.0)) graphicsOverlays.add(graphicsOverlay) } } - assigns the local variable 
 
Add a UI for user input
To search an address using the application, add a UI element to prompt the user for text input. The text input will be used as the geocode search text in a later step.
- 
In activity_main.xml, add a
Searchelement. This widget will display a search text field at the top of the app window.View activity_main.xmlUse dark colors for code blocks 3 4 5 6 7 8 9 19Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <SearchView android:id="@+id/searchView" android:layout_width="0dp" android:layout_height="0dp" android:queryHint="@string/search_hint" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - 
In MainActivity.kt, create a
setupmethod to handle user activity by changing the current address in the search field and submitting the search. In the first line, get the boundSearch View Listener() searchby callingView activity. Then callMain Binding.search View setand pass an anonymous class that implements theOn Query Text Listener() Searchinterface.View. On Query Text Listener MainActivity.ktUse dark colors for code blocks Add line. Add line. Add line. Add line. Add line. Add line. private fun setupSearchViewListener() { activityMainBinding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { }) } - 
Implement the two methods of the
Searchinterface:View. On Query Text Listener onandQuery Text Change() on.Query Text Submit() - Returning 
falsespecifies the standard Android behavior. 
MainActivity.ktUse dark colors for code blocks 106 107 108 109 118 119 120Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. private fun setupSearchViewListener() { activityMainBinding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextChange(newText: String): Boolean { return false } override fun onQueryTextSubmit(query: String): Boolean { return false } }) } - Returning 
 - 
In the
onlifecycle method, add aCreate() setupcall.Search View Listener() MainActivity.ktUse dark colors for code blocks 58 59 60 61 62 63 64 65 67 68Add line. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(activityMainBinding.root) setApiKeyForApp() setupMap() setupSearchViewListener() } 
Create a function to geocode an address
Geocoding is implemented with a locator, typically created by referencing a service such as the Geocoding service or, for offline geocoding, by referencing locator data contained in a mobile package. Geocoding parameters can be used to refine the results, such as setting a maximum number of results or requesting additional attributes in the results.
- 
Create a method named
perform.Geocode()  - 
Create a new
Geocodeand initialize it by calling the scope functionParameters applyand passing a lambda expression that does the following:- Adds the names of result attributes to the 
resultcollection. These are the names of attributes to be returned. An asterisk (Attribute Names *) indicates all attributes. - Sets 
maxto the maximum number of results to be returned. Results are ordered byResults score, so that the first result has the best match score (ranging from 0 for no match to 100 for the best match). - Sets 
outputto the spatial reference for result locations. By default, the output spatial reference is defined by the geocode service. For optimal performance when displaying the geocode result, you can ensure that returned coordinates match those of the map view by providing the map view's spatial reference.Spatial Reference  
When geocoding an address, you can optionally provide
Geocodeto control certain aspects of the geocoding operation and specify the kinds of results to return from the locator task. Learn more about these parameters in the API documentation. For a list of attributes returned with geocode results, see Geocoding service output in the ArcGIS services reference.Parameters MainActivity.ktUse dark colors for code blocks Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. private fun performGeocode(query: String) { val geocodeParameters = GeocodeParameters().apply { resultAttributeNames.add("*") maxResults = 1 outputSpatialReference = mapView.spatialReference } } - Adds the names of result attributes to the 
 - 
To find the location for the provided address, call
geocodeon theAsync() locator, passing theTask query(the address to find) and thegeocode. The call returns aParameters Listenable, which you should store in the read-only variableFuture geocode.Result Future MainActivity.ktUse dark colors for code blocks 124 125 126 127 128 129 130 131 133 134Add line. private fun performGeocode(query: String) { val geocodeParameters = GeocodeParameters().apply { resultAttributeNames.add("*") maxResults = 1 outputSpatialReference = mapView.spatialReference } val geocodeResultFuture = locatorTask.geocodeAsync(query, geocodeParameters) } - 
Call
addonDone Listener geocodeand specify a lambda expression to be executed when geocoding is complete. In the lambda, callResult Future displayto display the first item in theResult(geocode Result[0]) geocodelist. This is the location of the address on the map. In this tutorial, the maximum results parameter was set to 1, so you pass the first and only item in theResult geocodelist.Result MainActivity.ktUse dark colors for code blocks 124 125 126 127 128 129 130 131 132 133 147 148Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. private fun performGeocode(query: String) { val geocodeParameters = GeocodeParameters().apply { resultAttributeNames.add("*") maxResults = 1 outputSpatialReference = mapView.spatialReference } val geocodeResultFuture = locatorTask.geocodeAsync(query, geocodeParameters) geocodeResultFuture.addDoneListener { try { val geocodeResult = geocodeResultFuture.get() if (geocodeResult.isNotEmpty()) { displayResult(geocodeResult[0]) } else { Toast.makeText(this, "No results found.", Toast.LENGTH_LONG).show() } } catch (e: Exception) { Log.e(MainActivity::class.simpleName, "Error getting result" + e.message) } } } - 
In the
setupmethod, find theSearch View Listener() onmethod of theQuery Text Submit() Searchinterface implementation, and callView. On Query Text Listener perform.Code() MainActivity.ktUse dark colors for code blocks 108 109 110 111 112 113 114 115 116 117 119 120 121 122 123 124Add line. private fun setupSearchViewListener() { activityMainBinding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextChange(newText: String): Boolean { return false } override fun onQueryTextSubmit(query: String): Boolean { performGeocode(query) return false } }) } 
Display the result
The result obtained from the geocode operation can be displayed by adding two graphics to the map view's graphics overlay: one graphic that shows the address text and the other a red location marker.
- 
Create a method named
displayand clear the graphics overlay of any previous result.Result() MainActivity.ktUse dark colors for code blocks 152 153 156 157Add line. Add line. private fun displayResult(geocodeResult: GeocodeResult) { // clear the overlay of any previous result graphicsOverlay.graphics.clear() } - 
Create a
Textfor displaying the address text on the map. Then create aSymbol Graphic, passing thegeocode(the location on the map) and theResult.display Location text. Finally, add the graphic to theSymbol graphicscollection.Overlay MainActivity.ktUse dark colors for code blocks 152 153 154 155 156 165 168 169Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. private fun displayResult(geocodeResult: GeocodeResult) { // clear the overlay of any previous result graphicsOverlay.graphics.clear() // create a graphic to display the address text val textSymbol = TextSymbol( 18f, geocodeResult.label, Color.BLACK, TextSymbol.HorizontalAlignment.CENTER, TextSymbol.VerticalAlignment.BOTTOM ) val textGraphic = Graphic(geocodeResult.displayLocation, textSymbol) graphicsOverlay.graphics.add(textGraphic) } - 
Create a graphic to display a red marker symbol indicating the location on the map, and add the graphic to the
graphicscollection.Overlay MainActivity.ktUse dark colors for code blocks 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 172 176 177Add line. Add line. Add line. Add line. Add line. Add line. private fun displayResult(geocodeResult: GeocodeResult) { // clear the overlay of any previous result graphicsOverlay.graphics.clear() // create a graphic to display the address text val textSymbol = TextSymbol( 18f, geocodeResult.label, Color.BLACK, TextSymbol.HorizontalAlignment.CENTER, TextSymbol.VerticalAlignment.BOTTOM ) val textGraphic = Graphic(geocodeResult.displayLocation, textSymbol) graphicsOverlay.graphics.add(textGraphic) // create a graphic to display the location as a red square val simpleMarkerSymbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.SQUARE, Color.RED, 12.0f) val markerGraphic = Graphic(geocodeResult.displayLocation, geocodeResult.attributes, simpleMarkerSymbol) graphicsOverlay.graphics.add(markerGraphic) } - 
Call
setonViewpoint Center Async mapto display the two graphics at the proper location on the map.View MainActivity.ktUse dark colors for code blocks 169 170 171 172 173 174 175 176Add line. // create a graphic to display the location as a red square val simpleMarkerSymbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.SQUARE, Color.RED, 12.0f) val markerGraphic = Graphic(geocodeResult.displayLocation, geocodeResult.attributes, simpleMarkerSymbol) graphicsOverlay.graphics.add(markerGraphic) mapView.setViewpointCenterAsync(geocodeResult.displayLocation) - 
Click Run > Run > app to run the app.
 
You should see a search box on the top left of the map. Search for an address by entering an address and press Return on the keyboard. The result of the search should display on the map as a red square.
What's next?
Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: