> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/search/llms.txt)

# Address Autofill + Search UI + Maps SDK

> **Note**
> 
> This example is a part of the [Search SDK for Android sample app](https://github.com/mapbox/mapbox-search-android). You can find the values for all referenced resources in the [`res`](https://github.com/mapbox/mapbox-search-android/tree/main/MapboxSearch/sample/src/main/res) directory. For example, see [`res/values/strings.xml`](https://github.com/mapbox/mapbox-search-android/tree/main/MapboxSearch/sample/src/main/res/values/strings.xml) for `R.string.*` references used in this example. The dependencies can be found [here.](https://github.com/mapbox/mapbox-navigation-android-examples/blob/main/app/build.gradle) The examples use View binding. [See setup documention if necessary.](https://developer.android.com/topic/libraries/view-binding)

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/android/android/assets/medias/search-autofill-demo-257a6197a64ee4750643d7a1f14cb429.mp4).

Title: `activity_address_autofill`

[View on GitHub](https://github.com/mapbox/mapbox-search-android/tree/main/MapboxSearch/sample/src/main/res/layout/activity_address_autofill.xml)

```xml
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/windowBackground"
    tools:context=".AddressAutofillUiActivity"
    >

    <EditText
        android:id="@+id/query_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:autofillHints="@null"
        android:background="@drawable/card_background"
        android:elevation="4dp"
        android:hint="@string/address_autofill_query_hint"
        android:inputType="text"
        android:minHeight="?actionBarSize"
        android:paddingHorizontal="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/card_background"
        android:elevation="4dp"
        android:padding="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/query_text"
        >

        <EditText
            android:id="@+id/address_city"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:autofillHints="postalAddress"
            android:hint="@string/address_autofill_address_city_hint"
            android:inputType="textPostalAddress"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

        <EditText
            android:id="@+id/address_state"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:autofillHints="postalAddress"
            android:hint="@string/address_autofill_address_state_hint"
            android:inputType="textPostalAddress"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/address_city"
            />

        <EditText
            android:id="@+id/address_zip"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:autofillHints="postalAddress"
            android:hint="@string/address_autofill_address_zip_hint"
            android:inputType="number"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/address_state"
            />

        <EditText
            android:id="@+id/address_apartment"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:autofillHints="postalAddress"
            android:hint="@string/address_autofill_address_apt_hint"
            android:inputType="textPostalAddress"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/address_zip"
            />

        <TextView
            android:id="@+id/full_address"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="16dp"
            android:visibility="gone"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/address_apartment"
            tools:visibility="visible"
            />

        <TextView
            android:id="@+id/pin_correction_note"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:visibility="gone"
            android:text="@string/address_autofill_pin_correction_note"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/full_address"
            tools:visibility="visible"
            />

        <com.mapbox.maps.MapView
            android:id="@+id/map"
            android:layout_width="0dp"
            android:layout_height="150dp"
            android:layout_margin="8dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/pin_correction_note"
            />

        <ImageView
            android:id="@+id/map_pin"
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:adjustViewBounds="true"
            android:src="@drawable/red_marker"
            android:visibility="gone"
            app:layout_constraintBottom_toTopOf="@+id/map_center"
            app:layout_constraintEnd_toEndOf="@+id/map"
            app:layout_constraintStart_toStartOf="@+id/map"
            />

        <Space
            android:id="@+id/map_center"
            android:layout_width="1dp"
            android:layout_height="1dp"
            app:layout_constraintBottom_toBottomOf="@+id/map"
            app:layout_constraintEnd_toEndOf="@+id/map"
            app:layout_constraintStart_toStartOf="@+id/map"
            app:layout_constraintTop_toTopOf="@+id/map"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.mapbox.search.ui.view.SearchResultsView
        android:id="@+id/search_results_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="16dp"
        android:background="@drawable/card_background"
        android:clipToPadding="false"
        android:elevation="4dp"
        android:paddingTop="8dp"
        android:paddingBottom="22dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/query_text"
        />
</androidx.constraintlayout.widget.ConstraintLayout>
```

**Kotlin**

Title: `AddressAutofillUiActivity.kt`

[View on GitHub](https://github.com/mapbox/mapbox-search-android/tree/main/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/AddressAutofillUiActivity.kt)

```kt
package com.mapbox.search.sample

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.mapbox.common.location.Location
import com.mapbox.common.location.LocationServiceFactory
import com.mapbox.geojson.Point
import com.mapbox.maps.CameraOptions
import com.mapbox.maps.MapView
import com.mapbox.maps.MapboxMap
import com.mapbox.maps.Style
import com.mapbox.search.autofill.AddressAutofill
import com.mapbox.search.autofill.AddressAutofillOptions
import com.mapbox.search.autofill.AddressAutofillResult
import com.mapbox.search.autofill.AddressAutofillSuggestion
import com.mapbox.search.autofill.Query
import com.mapbox.search.ui.adapter.autofill.AddressAutofillUiAdapter
import com.mapbox.search.ui.view.CommonSearchViewConfiguration
import com.mapbox.search.ui.view.DistanceUnitType
import com.mapbox.search.ui.view.SearchResultsView

class AddressAutofillUiActivity : AppCompatActivity() {

    private lateinit var addressAutofill: AddressAutofill

    private lateinit var searchResultsView: SearchResultsView
    private lateinit var addressAutofillUiAdapter: AddressAutofillUiAdapter

    private lateinit var queryEditText: EditText

    private lateinit var apartmentEditText: EditText
    private lateinit var cityEditText: EditText
    private lateinit var stateEditText: EditText
    private lateinit var zipEditText: EditText
    private lateinit var fullAddress: TextView
    private lateinit var pinCorrectionNote: TextView
    private lateinit var mapView: MapView
    private lateinit var mapPin: View
    private lateinit var mapboxMap: MapboxMap

    private var ignoreNextMapIdleEvent: Boolean = false
    private var ignoreNextQueryTextUpdate: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_address_autofill)

        // Set your Access Token here if it's not already set in some other way
        // MapboxOptions.accessToken = "<my-access-token>"
        addressAutofill = AddressAutofill.create()

        queryEditText = findViewById(R.id.query_text)
        apartmentEditText = findViewById(R.id.address_apartment)
        cityEditText = findViewById(R.id.address_city)
        stateEditText = findViewById(R.id.address_state)
        zipEditText = findViewById(R.id.address_zip)
        fullAddress = findViewById(R.id.full_address)
        pinCorrectionNote = findViewById(R.id.pin_correction_note)

        mapPin = findViewById(R.id.map_pin)
        mapView = findViewById(R.id.map)
        mapboxMap = mapView.mapboxMap

        mapboxMap.loadStyle(Style.MAPBOX_STREETS)
        mapboxMap.subscribeMapIdle {
            if (ignoreNextMapIdleEvent) {
                ignoreNextMapIdleEvent = false
                return@subscribeMapIdle
            }

            val mapCenter = mapboxMap.cameraState.center
            findAddress(mapCenter)
        }

        searchResultsView = findViewById(R.id.search_results_view)

        searchResultsView.initialize(
            SearchResultsView.Configuration(
                commonConfiguration = CommonSearchViewConfiguration(DistanceUnitType.IMPERIAL)
            )
        )

        addressAutofillUiAdapter = AddressAutofillUiAdapter(
            view = searchResultsView,
            addressAutofill = addressAutofill
        )
        fun Location.toPoint(): Point = Point.fromLngLat(longitude, latitude)
        val locationService = LocationServiceFactory.getOrCreate()
            .getDeviceLocationProvider(null)
            .value
        locationService?.getLastLocation { location ->
            location?.toPoint()?.let {
                mapView.mapboxMap.setCamera(
                    CameraOptions.Builder()
                        .center(it)
                        .zoom(9.0)
                        .build()
                )
                ignoreNextMapIdleEvent = true
            }
        }

        addressAutofillUiAdapter.addSearchListener(object : AddressAutofillUiAdapter.SearchListener {

            override fun onSuggestionSelected(suggestion: AddressAutofillSuggestion) {
                selectSuggestion(suggestion)
            }

            override fun onSuggestionsShown(suggestions: List<AddressAutofillSuggestion>) {
                // Nothing to do
            }

            override fun onError(e: Exception) {
                // Nothing to do
            }
        })

        queryEditText.addTextChangedListener(object : TextWatcher {

            override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {
                if (ignoreNextQueryTextUpdate) {
                    ignoreNextQueryTextUpdate = false
                    return
                }

                val query = Query.create(text.toString())
                if (query != null) {
                    lifecycleScope.launchWhenStarted {
                        addressAutofillUiAdapter.search(query)
                    }
                }
                searchResultsView.isVisible = query != null
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
                // Nothing to do
            }

            override fun afterTextChanged(s: Editable) {
                // Nothing to do
            }
        })

        if (!isPermissionGranted(Manifest.permission.ACCESS_FINE_LOCATION)) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ),
                PERMISSIONS_REQUEST_LOCATION
            )
        }
    }

    private fun Context.showToast(@StringRes resId: Int): Unit = Toast.makeText(this, resId, Toast.LENGTH_LONG).show()

    private fun Context.isPermissionGranted(permission: String): Boolean =
        ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED

    private fun findAddress(point: Point) {
        lifecycleScope.launchWhenStarted {
            val response = addressAutofill.reverse(point, AddressAutofillOptions())
            response.onValue { result ->
                if (result.isEmpty()) {
                    showToast(R.string.address_autofill_error_pin_correction)
                } else {
                    showAddressAutofillResult(result.first(), fromReverseGeocoding = true)
                }
            }.onError {
                showToast(R.string.address_autofill_error_pin_correction)
            }
        }
    }

    private fun selectSuggestion(suggestion: AddressAutofillSuggestion) {
        lifecycleScope.launchWhenStarted {
            val response = addressAutofill.select(suggestion)
            response.onValue { result ->
                showAddressAutofillResult(result, fromReverseGeocoding = false)
            }.onError {
                showToast(R.string.address_autofill_error_select)
            }
        }
    }

    private fun showAddressAutofillResult(result: AddressAutofillResult, fromReverseGeocoding: Boolean) {
        val address = result.address
        cityEditText.setText(address.place)
        stateEditText.setText(address.region)
        zipEditText.setText(address.postcode)

        fullAddress.isVisible = true
        fullAddress.text = result.suggestion.formattedAddress

        pinCorrectionNote.isVisible = true

        if (!fromReverseGeocoding) {
            mapView.mapboxMap.setCamera(
                CameraOptions.Builder()
                    .center(result.coordinate)
                    .zoom(16.0)
                    .build()
            )
            ignoreNextMapIdleEvent = true
            mapPin.isVisible = true
        }

        ignoreNextQueryTextUpdate = true
        queryEditText.setText(
            listOfNotNull(
                address.houseNumber,
                address.street
            ).joinToString()
        )
        queryEditText.clearFocus()

        searchResultsView.isVisible = false
        searchResultsView.hideKeyboard()
    }

    private fun View.hideKeyboard() =
        (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(windowToken, 0)

    private companion object {
        const val PERMISSIONS_REQUEST_LOCATION = 0
    }
}
```