Cómo agregar un mapa con un marcador

En este instructivo, se muestra cómo agregar un mapa de Google Maps a tu app para Android. El mapa incluye un marcador, también denominado pin, el cual indica una ubicación específica.

Sigue el instructivo para compilar una app para Android con el SDK de Maps para Android. El entorno de desarrollo recomendado es Android Studio.

Obtén el código

En GitHub, clona o descarga el repositorio de muestras de la versión 2 de la API de Google Maps para Android.

Consulta la versión de Java de la actividad:

    // Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.example.mapwithmarker;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

/** An activity that displays a Google map with a marker (pin) to indicate a particular location. */
public class MapsMarkerActivity extends AppCompatActivity implements OnMapReadyCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Retrieve the content view that renders the map.
        setContentView(R.layout.activity_maps);

        // Get the SupportMapFragment and request notification when the map is ready to be used.
        SupportMapFragment mapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**
     * Manipulates the map when it's available. The API invokes this callback when the map is ready
     * to be used. This is where we can add markers or lines, add listeners or move the camera. In
     * this case, we just add a marker near Sydney, Australia. If Google Play services is not
     * installed on the device, the user receives a prompt to install Play services inside the
     * SupportMapFragment. The API invokes this method after the user has installed Google Play
     * services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        // Add a marker in Sydney, Australia,
        // and move the map's camera to the same location.
        LatLng sydney = new LatLng(-33.852, 151.211);
        googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}

    

Consulta la versión de Kotlin de la actividad:

    // Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.example.mapwithmarker

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions

/**
 * An activity that displays a Google map with a marker (pin) to indicate a particular location.
 */
class MapsMarkerActivity :
    AppCompatActivity(),
    OnMapReadyCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Retrieve the content view that renders the map.
        setContentView(R.layout.activity_maps)

        // Get the SupportMapFragment and request notification when the map is ready to be used.
        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment
        mapFragment?.getMapAsync(this)
    }

    override fun onMapReady(googleMap: GoogleMap) {
        val sydney = LatLng(-33.852, 151.211)
        googleMap.addMarker(
            MarkerOptions()
                .position(sydney)
                .title("Marker in Sydney"),
        )
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
    }
}

    

Configura tu proyecto de desarrollo

Sigue estos pasos para crear el proyecto del instructivo en Android Studio:

  1. Descarga Android Studio y, luego, instálalo.
  2. Agrega el paquete de Servicios de Google Play a Android Studio.
  3. Clona o descarga el repositorio de muestras de la versión 2 de la API de Google Maps para Android si no lo hiciste cuando empezaste a leer este instructivo.
  4. Abre el proyecto en Android Studio:

    • En Android Studio, selecciona File > Open.
    • Ve a la ubicación en la que guardaste el repositorio de muestras de la versión 2 de la API de Google Maps para Android tras descargarlo, selecciona el directorio raíz android-samples y haz clic en Open. Android Studio sincroniza el proyecto de varios módulos con Gradle.
    • En el menú de configuración de ejecución de Android Studio de la barra de herramientas, selecciona tutorials.java.MapWithMarker (fuente en tutorials/java/MapWithMarker) o tutorials.kotlin.MapWithMarker (fuente en tutorials/kotlin/MapWithMarker).

Habilita las APIs necesarias y obtén una clave de API

Para completar este instructivo, necesitas un proyecto de Google Cloud con las APIs necesarias habilitadas y una clave de API autorizada para utilizar el SDK de Maps para Android. Para obtener más información, consulta los siguientes recursos:

Agrega la clave de API a tu app

  1. En el directorio raíz android-samples (la misma carpeta que local.defaults.properties), abre o crea un archivo secrets.properties. No registres este archivo en el control de versiones.
  2. Agrega la siguiente cadena a secrets.properties y reemplaza YOUR_API_KEY por el valor de tu clave de API:

    MAPS_API_KEY=YOUR_API_KEY
    

    Cuando compilas tu app, el complemento Secrets Gradle para Android copia la clave de API y la pone a disposición como una variable de compilación en el manifiesto de Android, tal como se explica en Verifica tu manifiesto de Android.

Compila y ejecuta tu app

Para compilar y ejecutar la app, sigue estos pasos:

  1. Conecta un dispositivo Android a tu computadora. Sigue las instrucciones para habilitar las opciones para desarrolladores en tu dispositivo Android y configurar el sistema para que lo detecte.

    También puedes usar el Administrador de dispositivos en Android Studio para configurar un dispositivo virtual. Cuando elijas un emulador, selecciona un perfil de dispositivo con el ícono de Google Play en la columna Play para que la imagen del sistema incluya las APIs de Google. Para obtener más detalles, consulta Configura un proyecto de Android Studio.

  2. En Android Studio, verifica que esté seleccionado tutorials.java.MapWithMarker o tutorials.kotlin.MapWithMarker en el menú de configuración de ejecución. Luego, haz clic en Run y elige un dispositivo según se te indique.

    También puedes compilar el instructivo desde el directorio raíz android-samples en la línea de comandos:

    ./gradlew :tutorials:java:MapWithMarker:assembleDebug
    ./gradlew :tutorials:kotlin:MapWithMarker:assembleDebug
    

Android Studio invoca a Gradle para compilar la app y, luego, la ejecuta en el dispositivo o el emulador. Deberías ver un mapa con un marcador en Sídney, en la costa este de Australia, similar al de la imagen que se muestra en esta página.

Solución de problemas:

Comprende el código

En esta sección del instructivo, se explican los componentes más importantes de la app MapWithMarker para ayudarte a comprender cómo compilar una app similar.

Verifica el manifiesto de Android

Observa los siguientes elementos en el archivo AndroidManifest.xml de tu app:

  • Agrega un elemento meta-data para incorporar la versión de Servicios de Google Play con la que se compiló la app.

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_serv>ices_version" /
    
  • Agrega un elemento meta-data en el que se especifique tu clave de API. En el ejemplo incluido en este instructivo, se asigna el valor de la clave de API a una variable de compilación con el nombre de la clave que definiste antes, MAPS_API_KEY. Cuando compiles tu app, el complemento Secrets Gradle para Android permitirá que las claves de tu archivo secrets.properties estén disponibles como variables de compilación en el manifiesto.

    <meta-data
      android:name="com.google.android.geo.API_KEY"
      android:value="${M>APS_API_KEY}" /
    

    En el archivo build.gradle.kts a nivel del módulo, el complemento com.google.android.libraries.mapsplatform.secrets-gradle-plugin y el siguiente bloque secrets configuran el complemento Secrets Gradle para que lea tu clave de API de secrets.properties (con local.defaults.properties como resguardo) y la pase a tu manifiesto de Android:

    secrets {
        // To add your Maps API key to this project:
        // 1. If the secrets.properties file does not exist, create it in the root directory (the same folder as the root local.properties file).
        // 2. Add this line, where YOUR_API_KEY is your API key:
        //        MAPS_API_KEY=YOUR_API_KEY
        propertiesFileName = "secrets.properties"
    
        // A properties file containing default secret values. This file can be
        // checked in version control.
        defaultPropertiesFileName = "local.defaultt;
    }build.gradle.kts

En el siguiente ejemplo, se muestra un manifiesto completo:

<?xml version="1.0" encodin>g<="utf-8"?
!--
 Copyright 2020 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permission>s <and
 limitations under the License.
--

manifest xmlns:android=&quo>t;http<://schemas.android.com/apk/res/android"

    application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name&>quot;
    <    android:supportsRtl="true"
        android:theme="@style/AppTheme"

        meta-data
            android:name=>"com.<google.android.gms.version"
            android:value="@i>nteger/go<ogle_play_services_version" /

        !--
             The API key for Google Maps-based APIs.
        --
 >       met<a-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${MAPS_API_KEY}" /

        activit>y
           < android:name>=".MapsMarke<rActivity"
            android:label="@s>tring/title_activi<ty_maps"
            android:exported="true">;
           < intent-filter>
        <        a>ction< android:nam>e=<"and>roid.intent.action.MAIN" /

                category android:name="android.intent.category.LAUNCHER" /
            /intent-filter
        /activity
    /application

/manifest

Agrega un mapa

Muestra un mapa con el SDK de Maps para Android.

  1. Agrega un elemento <fragment> al archivo de diseño de tu actividad, activity_maps.xml. Este elemento define un fragmento (SupportMapFragment) para que actúe como contenedor del mapa y proporcione acceso al objeto GoogleMap. En el instructivo, se utiliza la versión de AndroidX correspondiente al fragmento de mapa para garantizar la retrocompatibilidad con versiones anteriores del framework de Android.

    <!--
     Copyright 2020 Google LLC
    
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
    
          http://www.apache.org/licenses/LICENSE-2.0
    
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations u>nd<er the License.
    --
    
    fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match>_parent"
        tools:context="com.example.mapwithmarker.MapsMarkerActivity" /
  2. En el método onCreate de tu actividad, establece el archivo de diseño como la vista de contenido. Llama a FragmentManager.findFragmentById para generar un controlador para el fragmento de mapa. Luego, utiliza getMapAsync para registrarte para la devolución de llamada del mapa:

    Java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Retrieve the content view that renders the map.
        setContentView(R.layout.activity_maps);
    
        // Get the SupportMapFragment and request notification when the map is ready to be used.
        SupportMapFragment mapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Retrieve the content view that renders the map.
        setContentView(R.layout.activity_maps)
    
        // Get the SupportMapFragment and request notification when the map is ready to be used.
        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment
        mapFragment?.getMapAsync(this)
    }
  3. Implementa la interfaz OnMapReadyCallback y anula el método onMapReady para configurar el mapa cuando el objeto GoogleMap esté disponible:

    Java

    public class MapsMarkerActivity extends AppCompatActivity implements OnMapReadyCallback {
    
        // ...
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            LatLng sydney = new LatLng(-33.852, 151.211);
            googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        }
    }

    Kotlin

    class MapsMarkerActivity :
        AppCompatActivity(),
        OnMapReadyCallback {
    
        // ...
    
        override fun onMapReady(googleMap: GoogleMap) {
            val sydney = LatLng(-33.852, 151.211)
            googleMap.addMarker(
                MarkerOptions()
                    .position(sydney)
                    .title("Marker in Sydney"),
            )
        }
    }

De forma predeterminada, el SDK de Maps para Android muestra el contenido de la ventana de información cuando el usuario presiona un marcador. Si deseas utilizar el comportamiento predeterminado, no es necesario agregar un objeto de escucha de clics para el marcador.

Próximos pasos

Obtén más información sobre el objeto de mapa y lo que puedes hacer con los marcadores.