Introduction to Google Maps API for Android with Kotlin

In this Google Maps API Tutorial for Android you will learn how to retrieve the user’s current location, get location updates and search for places. By Joe Howard.

4.1 (17) · 1 Review

Save for later
Share

Update Note: This tutorial is now up to date with the latest version of the Google Maps API, the latest version of Android Studio version 3.0.1, and uses Kotlin for app development. Update by Joe Howard. Original tutorial by Eunice Obugyei.

Update Note: This tutorial is now up to date with the latest version of the Google Maps API, the latest version of Android Studio version 3.0.1, and uses Kotlin for app development. Update by Joe Howard. Original tutorial by Eunice Obugyei.

From fitness apps such as Runkeeper to games such as Pokemon Go, location services are an increasingly important part of modern apps.

In this Google Maps API tutorial, you will create an app named City Guide. The app allows a user to search for a location, use Google Maps to show the address of the location and listen for the user’s location changes.

You will learn how to use the Google Maps Android API, the Google Location Services API and the Google Places API for Android to do the following:

  • Show a user’s current location
  • Display and customize markers on a map
  • Retrieve the address of a location given the coordinates
  • Listen for location updates
  • Search for places
Note: This Google Maps API tutorial assumes you are already familiar with the basics of Android development with Kotlin. If you are completely new to Android development, read through our Beginning Android Development with Kotlin tutorial to familiarize yourself with the basics.

Getting Started

Open Android Studio 3.0.1 or later and select Start a new Android Studio project from the Quick Start menu, or choose File/New Project…:

Quick Start menu

In the Create New Project dialog, on the Create Android Project view, enter the name of the app as City Guide, company domain of android.raywenderlich.com, select your preferred folder location for the project files, make sure that Include Kotlin support, and click Next:

Create Android Project

On the Target Android Devices view, check the Phone and Tablet box and select the minimum SDK you want the app to support. Specify API 16 from the Minimum SDK drop down and click Next.

Target Android Devices

On the Add an Activity to Mobile view, select the Google Maps Activity and click Next.

Add an Activity to Mobile

On the Configure Activity view, click Finish to complete the project creation process.

Configure Activity

Android Studio will use Gradle to build your project. This may take a few seconds.

Open MapsActivity.kt. It should look like this:

package com.raywenderlich.android.cityguide

import android.support.v7.app.AppCompatActivity
import android.os.Bundle

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

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

  private lateinit var mMap: GoogleMap

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_maps)
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    val mapFragment = supportFragmentManager
        .findFragmentById(R.id.map) as SupportMapFragment
    mapFragment.getMapAsync(this)
  }

  /**
   * Manipulates the map once available.
   * This callback is triggered 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 will be prompted to install
   * it inside the SupportMapFragment. This method will only be triggered once the user has
   * installed Google Play services and returned to the app.
   */
  override fun onMapReady(googleMap: GoogleMap) {
    mMap = googleMap

    // Add a marker in Sydney and move the camera
    val sydney = LatLng(-34.0, 151.0)
    mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
  }
}
  1. MapsActivity currently implements the OnMapReadyCallback interface and extends AppCompatActivity.
  2. The class overrides AppCompatActivity’s onCreate() method
  3. You also override OnMapReadyCallback’s onMapReady() method. This method is called when the map is ready to be used. The code declared in this method creates a marker with coordinates near Sydney, Australia and adds the marker to the map.

The template adds the following in the manifests/AndroidManifest.xml:

  1. A declaration of the ACCESS_FINE_LOCATION permission. This is required to access the user’s precise location.
  2. The com.google.android.geo.API_KEY meta-data. This is used to specify the API key.

The template also adds a Google Play Services dependency to build.gradle. This dependency exposes the Google Maps and Location Services APIs to the application.

implementation 'com.google.android.gms:play-services-maps:11.8.0'

When the build is complete, run the app to see what you have:

mapping_start_project_6_run_1

All you have is a blank screen with no map; you haven’t yet set up the API key for the Google Map. You’ll do that next.

Note: If you’re using an emulator, the emulator’s installed version will have to satisfy the version of Google Play Services required in your build.gradle file. If you see a message that you need to update the emulator’s Google Play Services version, you can either download the latest Google APIs using your Android Studio SDK Manager and install on your Virtual Device, or lower the version in your gradle dependency.

Using the Google Maps APIs

To use any of the Google Maps APIs, you need to create an API key and enable any required APIs from the developer console. If you don’t already have a Google account, create one now — it’s free!

Creating API Keys

Open res/values/google_maps_api.xml. You will see the following:

google_maps_api.xml

Now copy and paste the link shown above into your browser.

On the Enable an API page, select Create a project and click Continue.

mapping_start_project_8_create_api_2

On the next screen, click the Create API key button to continue.

mapping_start_project_9_create_api_3

When that’s done, copy the API key shown in the API key created dialog and click Close.

Getting an API Key

Head back to google_maps_api.xml, replace the value of google_maps_key key with the copied API key.

Build and run again. You should see a map with a red marker on the screen.

Run with API key

Go back to the developer console and enable the Google Places API for Android. You will be using this later on to search for a place:

Enable Google Places

Setting up a Fused Location Client

Before adding any Kotlin code, you’ll need to configure Android Studio to automatically insert import statements to save you from having to add each one manually.

Go to your Android Studio Preferences (or Settings on PC) and go to Editor > General > Auto Import, select the Add unambiguous imports on the fly and the Show import popup checkboxes, and click OK.

Import Settings

Open MapsActivity.kt and first rename the GoogleMap property to map by setting the cursor on it and hitting Shift + F6:

private lateinit var map: GoogleMap

Open your app build.gradle file and add the Google Maps location dependency:

implementation 'com.google.android.gms:play-services-location:11.8.0'

Next, add a FusedLocationProviderClient to MapActivity

private lateinit var fusedLocationClient: FusedLocationProviderClient

Add the following line of code to the end of onCreate(),

fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

Have MapActivity implement the GoogleMap.OnMarkerClickListener interface, which defines the onMarkerClick(), called when a marker is clicked or tapped:

class MapsActivity : AppCompatActivity(), OnMapReadyCallback,
    GoogleMap.OnMarkerClickListener {

Now you need to implement all methods declared in each of the interfaces added above. To do this, follow the steps below:

Implement members

  1. Place the cursor anywhere on the class declaration and click on the red light bulb icon that appears above the class declaration.
  2. Select Implement members from the options that appear.
  3. On the Implement members dialog, click OK.
  4. Implement members

Update onMarkerClick() to be

override fun onMarkerClick(p0: Marker?) = false

Add the following code to onMapReady():

map.getUiSettings().setZoomControlsEnabled(true)
map.setOnMarkerClickListener(this)

Here you enable the zoom controls on the map and declare MapsActivity as the callback triggered when the user clicks a marker on this map.

Now build and run the app and click the marker on the map near Sydney, and you’ll see the title text appear:

Sydney

Enter a different set of latitude and longitude values and you’ll see the marker move to your chosen location.

Replace the Sydney code with the following code to set a marker at New York City with the title “My Favorite City”:

val myPlace = LatLng(40.73, -73.99)  // this is New York 
map.addMarker(MarkerOptions().position(myPlace).title("My Favorite City"))
map.moveCamera(CameraUpdateFactory.newLatLng(myPlace))

Build and run.

New York

Notice the map automatically centered the marker on the screen; moveCamera() does this for you. However, the zoom level of the map isn’t right, as it’s fully zoomed out.

Modify moveCamera() as shown below:

map.moveCamera(CameraUpdateFactory.newLatLngZoom(myPlace, 12.0f))

Zoom level 0 corresponds to the fully zoomed-out world view. Most areas support zoom levels up to 20, while more remote areas only support zoom levels up to 13. A zoom level of 12 is a nice in-between value that shows enough detail without getting crazy-close.

Build and run to view your progress so far.

New York - Zoomed