Location-Aware Apps with Google Maps

  1. Create a new project and make sure to select Google Maps Activity in the Create New Project template wizard.

2. Add a Button “Find Location” in the Main Layout.

activity_main.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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnFindLocation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Find Location"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt (no changes)

package com.example.mymapapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btnFindLocation.setOnClickListener {
            startActivity(Intent(this, MapsActivity::class.java))
        }
    }
}

2. Update the MapsActivity.kt to includes codes to detect current location.

package com.example.mymapapp

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

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
    var locationManager: LocationManager? = null
    lateinit var locationListener: LocationListener

    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)
    }

    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap

        // check for permission
        if (ContextCompat.checkSelfPermission(
                applicationContext,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
            != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this@MapsActivity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1
            )

        }

        // initialize location manager
        locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

        // initialize the location listener
        locationListener = object : LocationListener {
            // when location update received, this function will be triggered
            override fun onLocationChanged(location: Location) {
                Toast.makeText(applicationContext, "onLocationChanged", Toast.LENGTH_SHORT).show()
                if (location != null) {
                    // update the map
                    val userLocation = LatLng(location!!.latitude, location!!.longitude)
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15F))
                    mMap.addMarker(MarkerOptions().position(userLocation).title("Your Location"))
                } else {
                    Toast.makeText(applicationContext, "null", Toast.LENGTH_SHORT).show()
                }
            }
        }

        // get location updates
        locationManager!!.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            0, 100f, locationListener
        )

    }
}

3. Login to your Google Developer Consoles and get your API key. Updates your app with the key. Replace the placeholder (YOUR_KEY_HERE) with the key you’ve copied from the Google Developer Console.

google_maps_api.xml

<resources>
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>

4. Launch the AVD. Open the Extended Controls (3-dots as pictured below)

This will bring up the extended controls window. Make sure Location > Single points is selected. Type your address or preferred location and then click “Set Location”.

5.Now run your app. On the MainActivity, click on “Find Location”.

Test the app with other locations to make sure it works correctly.