Cómo comenzar a usar el SDK de Places para Android (Kotlin)

1. Antes de comenzar

En este codelab, aprenderás a integrar el SDK de Places para Android en tu app y a usar cada una de las funciones del SDK de Places.

App de demo de Places

Requisitos previos

  • Conocimientos básicos sobre desarrollo en Kotlin y para Android

Qué aprenderás

  • Cómo instalar el SDK de Places para Android con extensiones de Kotlin
  • Cómo cargar Place Details para un lugar específico
  • Cómo agregar un widget de Place Autocomplete a tu app
  • Cómo cargar el Current Place según la ubicación actual informada del dispositivo

Otros requisitos

Para completar este codelab, necesitarás las siguientes cuentas, servicios y herramientas:

2. Prepárate

Para este paso, habilita la API de Places.

Configura Google Maps Platform

Si todavía no tienes una cuenta de Google Cloud Platform y un proyecto con la facturación habilitada, consulta la guía Cómo comenzar a utilizar Google Maps Platform para crear una cuenta de facturación y un proyecto.

  1. En Cloud Console, haz clic en el menú desplegable del proyecto y selecciona el proyecto que deseas usar para este codelab.

  1. Habilita las API y los SDK de Google Maps Platform necesarios para este codelab en Google Cloud Marketplace. Para hacerlo, sigue los pasos que se indican en este video o esta documentación.
  2. Genera una clave de API en la página Credenciales de Cloud Console. Puedes seguir los pasos que se indican en este video o esta documentación. Todas las solicitudes a Google Maps Platform requieren una clave de API.

3. Inicio rápido

Para que puedas comenzar lo más rápido posible, descarga el código inicial que te ayudará a seguir este codelab. Puedes pasar directamente a la solución, pero si quieres ir paso a paso para ver cómo crearla tú mismo, sigue leyendo.

  1. Si tienes git instalado, clona el repositorio.
git clone https://github.com/googlemaps/codelab-places-101-android.git

También puedes hacer clic en este botón para descargar el código fuente.

  1. Después de descargar el código, abre el proyecto del directorio /starter en Android Studio. Este proyecto incluye la estructura de archivos básica que necesitarás para completar el codelab. Todo lo que necesitas para este proyecto se encuentra en el directorio /starter.

Si deseas ver el código completo de la solución en ejecución, puedes ver el código completo en el directorio /solution.

4. Instala el SDK de Places para Android

En esta sección, agregarás el SDK de Places para Android a las dependencias de tu app.

Agrega tu clave de API

Proporciona la clave de API que creaste anteriormente en la app para que el SDK de Places para Android pueda asociar esa clave con tu app.

  1. Abre el archivo llamado local.properties en el directorio raíz de tu proyecto (el mismo nivel en el que están gradle.properties y settings.gradle).
  2. Define una clave GOOGLE_MAPS_API_KEY nueva y configura su valor como la clave de API que creaste.

local.properties

GOOGLE_MAPS_API_KEY=YOUR_KEY_HERE

Ten en cuenta que local.properties está incluido en el archivo .gitignore, en el repositorio de Git. Esto se debe a que tu clave de API se considera información sensible y, de ser posible, no debe incluirse en el control de versiones.

  1. Luego, debes exponer tu API a fin de que pueda usarse en toda tu app. Para eso, incluye el complemento Secrets Gradle Plugin for Android en el archivo build.gradle de tu app ubicado en el directorio app/ y agrega la siguiente línea dentro del bloque plugins:

Archivo build.gradle a nivel de la app

plugins {
    // ...
    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
  1. Modifica tu archivo build.gradle a nivel de proyecto para incluir la siguiente ruta de clase:

Archivo build.gradle a nivel de proyecto

buildscript {
    dependencies {
        // ...
        classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
    }
}

Este complemento hará que las claves que definiste dentro del archivo local.properties estén disponibles como variables de compilación en el archivo de manifiesto de Android y como variables en la clase BuildConfig generada por Gradle durante el tiempo de compilación. Al usar este complemento, se quita el código estándar que habría sido necesario para leer las propiedades de local.properties a fin de acceder a ellas desde cualquier lugar de la app.

Agrega la dependencia del SDK de Places para Android

  1. Ahora que se puede acceder a tu clave de API dentro de la app, agrega la dependencia del SDK de Places para Android al archivo build.gradle de tu app.

En el proyecto inicial que viene con este codelab, esta dependencia ya está incluida.

Archivo build.gradle a nivel de la app

dependencies {
   // Dependency to include Places SDK for Android
   implementation 'com.google.android.libraries.places:places:2.6.0'
}
  1. Ejecuta la app.

Ahora deberías ver una app con la pantalla vacía. Siga completando esta pantalla con tres demostraciones.

5. Instala Places Android KTX

En el caso de las apps de Kotlin que usan uno o más SDK de Android para Google Maps Platform, las bibliotecas de extensiones de Kotlin (KTX) te permiten aprovechar las funciones del lenguaje Kotlin, como corrutinas, propiedades y funciones de extensiones, y mucho más. Cada SDK de Google Maps tiene una biblioteca KTX correspondiente, como se muestra a continuación:

Diagrama de KTX de Google Maps Platform

En esta tarea, utiliza la biblioteca de Places Android KTX para usar funciones específicas del lenguaje Kotlin en tu app.

Agrega la dependencia de Places Android KTX

Para aprovechar las funciones específicas de Kotlin, incluye la biblioteca KTX correspondiente para este SDK en tu archivo build.gradle a nivel de la app.

build.gradle

dependencies {
    // ...

    // Places SDK for Android KTX Library
    implementation 'com.google.maps.android:places-ktx:2.0.0'
}

6. Inicializa el cliente de Places

Inicializa el SDK de Places para el alcance de la aplicación

Dentro del archivo DemoApplication.kt de la carpeta app/src/main/java/com/google/codelabs/maps/placesdemo, inicializa el SDK de Places para Android. Pega las siguientes líneas al final de la función onCreate:

        // Initialize the SDK with the Google Maps Platform API key
        Places.initialize(this, BuildConfig.GOOGLE_MAPS_API_KEY)

Cuando compilas tu app, Secrets Gradle Plugin for Android hace que la clave de API del archivo local.properties esté disponible como BuildConfig.GOOGLE_MAPS_API_KEY.

Agrega el archivo de la aplicación al manifiesto

Como extendiste Application con DemoApplication, debes actualizar el manifiesto. Agrega la propiedad android:name al elemento application en el archivo AndroidManifest.xml, ubicado en app/src/main:

    <application
        android:name=".DemoApplication"
        ...
    </application>

Este código apunta el manifiesto de la aplicación a la clase DemoApplication en la carpeta src/main/java/com/google/codelabs/maps/placesdemo/.

7. Conéctate con Place Details

Crea una pantalla de Details

Hay un diseño activity_details.xml con un LinearLayout vacío disponible en la carpeta app/src/main/res/layout/. Para propagar el diseño lineal, agrega el siguiente código entre los corchetes angulares de <LinearLayout>.

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/details_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/details_input_hint"
            android:text="@string/details_input_default" />

    </com.google.android.material.textfield.TextInputLayout>

    <Button
        android:id="@+id/details_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_details" />

    <TextView
        android:id="@+id/details_response_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:textIsSelectable="true" />

Este código agrega un campo de entrada de texto en el que el usuario puede ingresar cualquier ID de lugar o usar el valor predeterminado, un botón para iniciar la solicitud de Place Details y un TextView para mostrar la información de la respuesta. Tú defines las strings asociadas en el archivo src/main/res/values/strings.xml.

Crea una actividad de Details

  1. Crea un archivo DetailsActivity.kt en la carpeta src/main/java/com/google/codelabs/maps/placesdemo/ y asócialo con el diseño que acabas de crear. Pega este código en el archivo:
class DetailsActivity : AppCompatActivity() {
    private lateinit var placesClient: PlacesClient
    private lateinit var detailsButton: Button
    private lateinit var detailsInput: TextInputEditText
    private lateinit var responseView: TextView

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

        // Set up view objects
        detailsInput = findViewById(R.id.details_input)
        detailsButton = findViewById(R.id.details_button)
        responseView = findViewById(R.id.details_response_content)

    }
}
  1. Crea un cliente de Places para usarlo con esta actividad. Pega este código después de la configuración del objeto de vista en la función onCreate.
        // Retrieve a PlacesClient (previously initialized - see DemoApplication)
        placesClient = Places.createClient(this)
  1. Una vez configurado el cliente de Places, adjunta un objeto de escucha de clics al botón. Pega este código después de crear el cliente de Places en la función onCreate.
        // Upon button click, fetch and display the Place Details
        detailsButton.setOnClickListener {
            val placeId = detailsInput.text.toString()
            val placeFields = listOf(
                Place.Field.NAME,
                Place.Field.ID,
                Place.Field.LAT_LNG,
                Place.Field.ADDRESS
            )
            lifecycleScope.launch {
                try {
                    val response = placesClient.awaitFetchPlace(placeId, placeFields)
                    responseView.text = response.prettyPrint()
                } catch (e: Exception) {
                    e.printStackTrace()
                    responseView.text = e.message
                }
            }
        }

Este código recupera el ID de lugar que se ingresó en el campo de entrada, define qué campos solicitar para el lugar, crea un FetchPlaceRequest, inicia la tarea y escucha si la solicitud se completa correctamente o no. Si todo está bien, la función propaga la TextView con los detalles solicitados.

  1. Convierte la FetchPlaceResponse en texto mediante la definición de una función de extensión. Se proporciona un archivo StringUtil.kt para simplificar la conversión de respuestas del SDK de Places en strings legibles.

Al final del archivo DetailsActivity.kt, define una función para convertir el objeto de FetchPlaceResponse en una string.

fun FetchPlaceResponse.prettyPrint(): String {
    return StringUtil.stringify(this, false)
}

Agrega la actividad de Details al manifiesto

Agrega un elemento <activity> a DetailsActivity como elemento secundario del elemento <application> en el archivo AndroidManifest.xml, ubicado en app/src/main:

        <activity android:name=".DetailsActivity" />

Agrega la actividad de Details al menú de demostración

Se proporciona un módulo Demo vacío para enumerar las demostraciones disponibles en la pantalla principal. Ahora que creaste una actividad de Place Details, agrégala al archivo Demo.kt de la carpeta src/main/java/com/google/codelabs/maps/placesdemo/ con este código:

    DETAILS_FRAGMENT_DEMO(
        R.string.details_demo_title,
        R.string.details_demo_description,
        DetailsActivity::class.java
    ),

Las strings asociadas se definen en el archivo src/main/res/values/strings.xml.

Inspecciona MainActivity.kt y observa que crea una ListView que se propaga mediante la iteración por el contenido del módulo Demo. Si el usuario presiona un elemento de la lista, el objeto de escucha de clics abrirá la actividad asociada.

Ejecuta la app

  1. Ejecuta la app. Esta vez, deberías ver un elemento en la lista que presenta la demostración de Place Details.
  2. Presiona el texto de Place Details. Deberías ver la vista que creaste con un campo de entrada y un botón.
  3. Presiona el botón "GET DETAILS". Si utilizaste el ID de lugar predeterminado, deberías ver el nombre, la dirección y las coordenadas del mapa correspondientes al lugar que se muestran como en la Figura 1.

Actividad de Place Details con respuesta

Figura 1. Actividad de Place Details con presentación de la respuesta.

8. Agrega Place Autocomplete

Crea una pantalla de Autocomplete

Hay un diseño activity_autocomplete.xml con un LinearLayout vacío disponible en la carpeta app/src/main/res/layout/. Para propagar el diseño lineal, agrega este código entre los corchetes angulares de <LinearLayout>.

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/autocomplete_fragment"
        android:background="@android:color/white"
        android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/autocomplete_response_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:textIsSelectable="true" />

Este código agrega un widget AutocompleteSupportFragment y una TextView para mostrar la información de la respuesta. Las strings asociadas se definen en el archivo src/main/res/values/strings.xml.

Crea una actividad de Autocomplete

  1. Crea un archivo AutocompleteActivity.kt en la carpeta src/main/java/com/google/codelabs/maps/placesdemo/ y defínelo con este código:
class AutocompleteActivity : AppCompatActivity() {
    private lateinit var responseView: TextView

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

        // Set up view objects
        responseView = findViewById(R.id.autocomplete_response_content)
        val autocompleteFragment =
            supportFragmentManager.findFragmentById(R.id.autocomplete_fragment)
                    as AutocompleteSupportFragment
    }
}

Este código asocia la actividad con las vistas y el AutocompleteSupportFramgent que definiste en el archivo de diseño.

  1. A continuación, define lo que sucede cuando el usuario selecciona una de las predicciones que hace Place Autocomplete. Agrega el siguiente código al final de la función onCreate:
        // Specify the types of place data to return.
        autocompleteFragment.setPlaceFields(listOf(Place.Field.NAME, Place.Field.ID, Place.Field.LAT_LNG, Place.Field.ADDRESS))

        // Listen to place selection events
        lifecycleScope.launchWhenCreated {
            autocompleteFragment.placeSelectionEvents().collect { event ->
                when (event) {
                    is PlaceSelectionSuccess -> {
                        val place = event.place
                        responseView.text = StringUtil.stringifyAutocompleteWidget(place, false)
                    }
                    is PlaceSelectionError -> Toast.makeText(
                        this@AutocompleteActivity,
                        "Failed to get place '${event.status.statusMessage}'",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }

Este código define qué campos solicitar para el lugar, escucha si hay un evento de selección de lugar y si la solicitud se completa correctamente o no. Si todo está bien, la función propaga la TextView con los detalles del lugar. Ten en cuenta que Place Autocomplete devuelve un objeto de lugar. No es necesario realizar una solicitud de Place Details por separado si usas el widget de Place Autocomplete.

Agrega la actividad de Autocomplete al manifiesto

Agrega un elemento <activity> a AutocompleteActivity como elemento secundario del elemento <application> en el archivo AndroidManifest.xml, ubicado en app/src/main:

        <activity android:name=".AutocompleteActivity" />

Agrega la actividad de Autocomplete al menú de demostración

Al igual que antes, incluye la demostración de Place Autocomplete en la pantalla principal agregándola a la lista del módulo Demo. Ahora que creaste una actividad de Place Autocomplete, agrégala al archivo Demo.kt en la carpeta src/main/java/com/google/codelabs/maps/placesdemo/. Pega este código inmediatamente después del elemento DETAILS_FRAGMENT_DEMO:

    AUTOCOMPLETE_FRAGMENT_DEMO(
        R.string.autocomplete_fragment_demo_title,
        R.string.autocomplete_fragment_demo_description,
        AutocompleteActivity::class.java
    ),

Las strings asociadas se definen en el archivo src/main/res/values/strings.xml.

Ejecuta la app

  1. Ejecuta la app. Esta vez, deberías ver dos elementos en la lista de la pantalla principal.
  2. Presiona la fila Place Autocomplete. Deberías ver una ventana emergente de entrada de Place Autocomplete, tal como se muestra en la Figura 2.
  3. Comienza a escribir el nombre de un lugar. Puede ser el nombre de un establecimiento, una dirección o una región geográfica. Las predicciones deben aparecer a medida que escribes.
  4. Selecciona una de las predicciones. Las predicciones deberían desaparecer, y TextView debería mostrar los detalles sobre el lugar seleccionado, como se ve en la Figura 3.

Actividad de Autocomplete después de que el usuario presiona el campo de entrada

Figura 2. Actividad de Autocomplete después de que el usuario presiona el campo de entrada

Actividad de Autocomplete después de que el usuario escribió y seleccionó las cataratas del Niágara

Figura 3. Actividad de Autocomplete que muestra Place Details después de que el usuario escribió y seleccionó "Niagara Falls"

9. Obtén el Current Place del dispositivo

Crea una pantalla de Current Place

Hay un diseño activity_current.xml con un LinearLayout vacío disponible en la carpeta app/src/main/res/layout/. Para propagar el diseño lineal, agrega el siguiente código entre los corchetes angulares de <LinearLayout>.

    <Button
        android:id="@+id/current_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/current_button" />

    <TextView
        android:id="@+id/current_response_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:scrollbars = "vertical"
        android:textIsSelectable="true" />

Crea una actividad de Current Place

  1. Crea un archivo CurrentActivity.kt en la carpeta src/main/java/com/google/codelabs/maps/placesdemo/ y defínelo con este código:
class CurrentPlaceActivity : AppCompatActivity() {
    private lateinit var placesClient: PlacesClient
    private lateinit var currentButton: Button
    private lateinit var responseView: TextView

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

        // Retrieve a PlacesClient (previously initialized - see DemoApplication)
        placesClient = Places.createClient(this)

        // Set view objects
        currentButton = findViewById(R.id.current_button)
        responseView = findViewById(R.id.current_response_content)

        // Set listener for initiating Current Place
        currentButton.setOnClickListener {
            checkPermissionThenFindCurrentPlace()
        }
    }
}

Este código asocia la actividad con las vistas que definiste en el archivo de diseño. También agrega un objeto de escucha de clics al botón para llamar a la función checkPermissionThenFindCurrentPlace cuando se hace clic en el botón.

  1. Define checkPermissionThenFindCurrentPlace() para verificar el permiso de ubicación precisa y solicitarlo si todavía no se otorgó. Pega este código después de la función onCreate.
    /**
     * Checks that the user has granted permission for fine or coarse location.
     * If granted, finds current Place.
     * If not yet granted, launches the permission request.
     * See https://developer.android.com/training/permissions/requesting
     */
    private fun checkPermissionThenFindCurrentPlace() {
        when {
            (ContextCompat.checkSelfPermission(
                this,
                ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
                this,
                ACCESS_COARSE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED) -> {
                // You can use the API that requires the permission.
                findCurrentPlace()
            }
            shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)
            -> {
                Log.d(TAG, "Showing permission rationale dialog")
                // TODO: In an educational UI, explain to the user why your app requires this
                // permission for a specific feature to behave as expected. In this UI,
                // include a "cancel" or "no thanks" button that allows the user to
                // continue using your app without granting the permission.
            }
            else -> {
                // Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                    ),
                    PERMISSION_REQUEST_CODE
                )
            }
        }
    }

    companion object {
        private val TAG = "CurrentPlaceActivity"
        private const val PERMISSION_REQUEST_CODE = 9
    }
  1. Cuando la rama else de la función checkPermissionThenFindCurrentPlace llama a requestPermissions, la app presentará un diálogo de solicitud de permiso al usuario. Si el usuario ejecuta un dispositivo con un SO inferior a Android 12, solo puede otorgar permiso de ubicación precisa (puntual). Si el usuario utiliza un dispositivo con Android 12 o una versión posterior, tendrá la opción de proporcionar una ubicación aproximada (amplia) en lugar de precisa (puntual), tal como se muestra en la Figura 4.

Solicitud de permiso del usuario en un dispositivo con Android 12 o una versión posterior

Figura 4. Cuando se solicita permiso del usuario en un dispositivo con Android 12 o una versión posterior, se ofrece la opción de otorgar la ubicación precisa o aproximada.

Una vez que el usuario responde al diálogo de permisos del sistema, este invoca la implementación de onRequestPermissionsResult de tu app. El sistema pasa la respuesta del usuario al diálogo de permisos, así como el código de solicitud que definiste. Anula onRequestPermissionResult a fin de controlar el código de solicitud para los permisos de ubicación relacionados con esta actividad de Current Place. Para ello, pega el siguiente código debajo de checkPermissionThenFindCurrentPlace.

    @SuppressLint("MissingPermission")
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>, grantResults: IntArray
    ) {
        if (requestCode != PERMISSION_REQUEST_CODE) {
            super.onRequestPermissionsResult(
                requestCode,
                permissions,
                grantResults
            )
            return
        } else if (permissions.toList().zip(grantResults.toList())
                .firstOrNull { (permission, grantResult) ->
                    grantResult == PackageManager.PERMISSION_GRANTED && (permission == ACCESS_FINE_LOCATION || permission == ACCESS_COARSE_LOCATION)
                } != null
        )
            // At least one location permission has been granted, so proceed with Find Current Place
            findCurrentPlace()
    }
  1. Una vez que se otorgue el permiso, se ejecutará la función findCurrentPlace. Define la función con este código después de la función onRequestPermissionsResult.
    /**
     * Fetches a list of [PlaceLikelihood] instances that represent the Places the user is
     * most
     * likely to be at currently.
     */
    @RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
    private fun findCurrentPlace() {
        // Use fields to define the data types to return.
        val placeFields: List<Place.Field> =
            listOf(Place.Field.NAME, Place.Field.ID, Place.Field.ADDRESS, Place.Field.LAT_LNG)

        // Use the builder to create a FindCurrentPlaceRequest.
        val request: FindCurrentPlaceRequest = FindCurrentPlaceRequest.newInstance(placeFields)

        // Call findCurrentPlace and handle the response (first check that the user has granted permission).
        if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) ==
            PackageManager.PERMISSION_GRANTED ||
            ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // Retrieve likely places based on the device's current location
            lifecycleScope.launch {
                try {
                    val response = placesClient.awaitFindCurrentPlace(placeFields)
                    responseView.text = response.prettyPrint()

                    // Enable scrolling on the long list of likely places
                    val movementMethod = ScrollingMovementMethod()
                    responseView.movementMethod = movementMethod
                } catch (e: Exception) {
                    e.printStackTrace()
                    responseView.text = e.message
                }
            }
        } else {
            Log.d(TAG, "LOCATION permission not granted")
            checkPermissionThenFindCurrentPlace()

        }
    }

Este código define qué campos solicitar para los lugares probables, crea una FindCurrentPlaceRequest, inicia la tarea y propaga la TextView con los detalles solicitados.

  1. Convierte la FindCurrentPlaceResponse en texto mediante la definición de una función de extensión. Se proporciona un archivo StringUtil.kt para simplificar la conversión de respuestas del SDK de Places en strings legibles.

Al final del archivo CurrentPlaceActivity.kt, define una función para convertir el objeto de la respuesta de Current Place en una string.

fun FindCurrentPlaceResponse.prettyPrint(): String {
    return StringUtil.stringify(this, false)
}

Agrega la actividad de Current Place al manifiesto

Agrega un elemento <activity> a CurrentPlaceActivity como elemento secundario del elemento <application> en el archivo AndroidManifest.xml, ubicado en app/src/main:

        <activity android:name=".CurrentPlaceActivity" />

Agrega la actividad de Current Place al menú de demostración

Al igual que antes, incluye la demostración de Current Place en la pantalla principal agregándola a la lista del módulo Demo. Ahora que creaste una actividad de Current Place, agrégala al archivo Demo.kt en la carpeta src/main/java/com/google/codelabs/maps/placesdemo/. Pega este código inmediatamente después del elemento AUTOCOMPLETE_FRAGMENT_DEMO:

    CURRENT_FRAGMENT_DEMO(
        R.string.current_demo_title,
        R.string.current_demo_description,
        CurrentPlaceActivity::class.java
    ),

Las strings asociadas se definen en el archivo src/main/res/values/strings.xml.

Ejecuta la app

  1. Ejecuta la app. Esta vez, deberías ver tres elementos en la lista de la pantalla principal.
  2. Presiona la fila Current Place. Deberías ver un botón en la pantalla.
  3. Presiona el botón. Si no le otorgaste permiso de ubicación a esta app anteriormente, aparecerá una solicitud de permiso emergente.
  4. Otorga permiso a la app para que acceda a la ubicación del dispositivo.
  5. Vuelve a presionar el botón. Esta vez, debería aparecer una lista de hasta 20 lugares cercanos y sus probabilidades, tal como se muestra en la Figura 5.

Presentación de las coincidencias probables de Current Place para la ubicación informada del dispositivo

Figura 5. Presentación de las coincidencias probables de Current Place para la ubicación informada del dispositivo

10. Felicitaciones

Creaste correctamente una app para Android con el SDK de Places para Android.

Lo que aprendiste

¿Qué sigue?

  • Explora o bifurca el repositorio de muestras y demostraciones de android-places-demos en GitHub para obtener más inspiración.
  • Aprende con más codelabs de Kotlin que te permitirán crear apps para Android con Google Maps Platform.
  • Responde la siguiente pregunta para ayudarnos a crear el contenido que te resultaría más útil:

¿Qué otros codelabs te gustaría ver?

Visualización de datos en mapas Más información sobre cómo personalizar el estilo de mis mapas Creación de interacciones 3D en los mapas

¿El codelab que quieres no figura arriba? Crea un nuevo problema aquí para solicitarlo.