Acerca de este codelab
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.
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:
- Una Cuenta de Google con facturación habilitada
- Android Studio Bumblebee o una versión posterior
- Servicios de Google Play instalados en Android Studio
- Un dispositivo Android o Android Emulator que ejecute la plataforma de API de Google basada en Android 8 o una versión posterior (consulta Cómo ejecutar apps en Android Emulator para conocer los pasos de instalación).
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.
- En Cloud Console, haz clic en el menú desplegable del proyecto y selecciona el proyecto que deseas usar para este codelab.
- 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.
- 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.
- 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.
- 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.
- Abre el archivo llamado
local.properties
en el directorio raíz de tu proyecto (el mismo nivel en el que estángradle.properties
ysettings.gradle
). - 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.
- 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 directorioapp/
y agrega la siguiente línea dentro del bloqueplugins
:
Archivo build.gradle a nivel de la app
plugins {
// ...
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
- 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
- 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'
}
- 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:
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
- Crea un archivo
DetailsActivity.kt
en la carpetasrc/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)
}
}
- 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)
- 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.
- Convierte la
FetchPlaceResponse
en texto mediante la definición de una función de extensión. Se proporciona un archivoStringUtil.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
- Ejecuta la app. Esta vez, deberías ver un elemento en la lista que presenta la demostración de Place Details.
- Presiona el texto de Place Details. Deberías ver la vista que creaste con un campo de entrada y un botón.
- 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.
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
- Crea un archivo
AutocompleteActivity.kt
en la carpetasrc/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.
- 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
- Ejecuta la app. Esta vez, deberías ver dos elementos en la lista de la pantalla principal.
- Presiona la fila Place Autocomplete. Deberías ver una ventana emergente de entrada de Place Autocomplete, tal como se muestra en la Figura 2.
- 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.
- 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.
Figura 2. Actividad de Autocomplete después de que el usuario presiona el campo de entrada
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
- Crea un archivo
CurrentActivity.kt
en la carpetasrc/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.
- 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ónonCreate
.
/**
* 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
}
- Cuando la rama
else
de la funcióncheckPermissionThenFindCurrentPlace
llama arequestPermissions
, 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.
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()
}
- 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ónonRequestPermissionsResult
.
/**
* 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.
- Convierte la
FindCurrentPlaceResponse
en texto mediante la definición de una función de extensión. Se proporciona un archivoStringUtil.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
- Ejecuta la app. Esta vez, deberías ver tres elementos en la lista de la pantalla principal.
- Presiona la fila Current Place. Deberías ver un botón en la pantalla.
- Presiona el botón. Si no le otorgaste permiso de ubicación a esta app anteriormente, aparecerá una solicitud de permiso emergente.
- Otorga permiso a la app para que acceda a la ubicación del dispositivo.
- 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.
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
- Cómo instalar y configurar el SDK de Places para Android
- Cómo instalar extensiones de Kotlin para el SDK de Places para Android
- Cómo cargar Place Details
- Cómo agregar Place Autocomplete
- Cómo obtener el lugar actual con Current Place
¿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?
¿El codelab que quieres no figura arriba? Crea un nuevo problema aquí para solicitarlo.