Industrial Training




Google Map Current Location


To implement the Google Map in an Android application, we need to generate the Google Map API key. The process of creating the Google Map API key is described in Google Map Fixed Location tutorial.
In the previous tutorial of Kotlin Android Google Map Fixed Location, we have displayed the fixed Google location.
Now in this tutorial, we will display and place the marker at user's current location. To view the user's current location, we need to implement some Google Map interfaces and call there callbacks methods.


  • OnMapRreadyCallback: This interface invokes when its instance is set on a MapFragment object. The onMapReady(GoogleMap) method of OnMapReadyCallback interface is called when the map is ready to use. In the onMapReady(GoogleMap) method, we can add markers, listeners, and other attributes.
  • LocationListener: This interface is used to receive the notification when the device location is changed. The abstract method onLocationChanged(Location) of LocationListener interface is called when the location has changed.
  • GoogleApiClient.ConnectionCallbacks: This interface provides the callbacks methods onConnected(Bundle) and onConnectionSuspended(int) which are called when the device is connected and disconnected respectively.
  • GoogleApiClient.OnConnectionFailedListener: This interface provides callbacks method onConnectionFailed(ConnectionResult) which is called when the error occurs while connecting the device to the service.

The isLocationEnabled property of GoogleMap is used to enable location layer, which allows the device to interact with the current location.
The tutorial using Java to display Google Map user's current location is described at Android Google Map Displaying Current Location.


Types of Google Map


There are four different types of Google map are available in map API. Each of them has different view of the map. These types are Normal, Hybrid, Satellite and Terrain.


  • googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
  • googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
  • googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
  • googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);

Using Kotlin syntax, we will use the above Google map types as:


  • googleMap.mapType = MAP_TYPE_NONE
  • googleMap.mapType = MAP_TYPE_HYBRID
  • googleMap.mapType = MAP_TYPE_SATELLITE
  • googleMap.mapType = MAP_TYPE_TERRAIN

The detail about these map types are explain here.


activity_maps.xml


Add the following code in activity_maps.xml layout file.


< fragment xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:map="http://schemas.android.com/apk/res-auto"  
    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="example.javatpoint.com.kotlingooglemapcurrentlocation.MapsActivity" />  
< fragment xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:map="http://schemas.android.com/apk/res-auto"  
    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="example.javatpoint.com.kotlingooglemapcurrentlocation.MapsActivity" />

strings.xml


< resources>  
    < string name="app_name">Kotlin Google Map Current Location< /string>  
    < string name="title_activity_maps">Map Current Location< /string>  
< /resources>  
< resources>  
    < string name="app_name">Kotlin Google Map Current Location< /string>  
    < string name="title_activity_maps">Map Current Location< /string>  
< /resources> 

build.gradle


Add the Google Map Service and Google Location Service dependencies in build.gradle file.


dependencies {  
    implementation fileTree(dir: 'libs', include: ['*.jar'])  
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"  
    implementation 'com.android.support:appcompat-v7:26.1.0'  
    implementation 'com.google.android.gms:play-services-maps:11.8.0'  
    compile 'com.google.android.gms:play-services-location:11.8.0'  
    testImplementation 'junit:junit:4.12'  
}  
dependencies {  
    implementation fileTree(dir: 'libs', include: ['*.jar'])  
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"  
    implementation 'com.android.support:appcompat-v7:26.1.0'  
    implementation 'com.google.android.gms:play-services-maps:11.8.0'  
    compile 'com.google.android.gms:play-services-location:11.8.0'  
    testImplementation 'junit:junit:4.12'  
}  

google_maps_api.xml


Place the Google Map API key in res/values/google_map_api.xml file.


< resources>  
    < !--  
     https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=20:0B:71:3B:B2:46:75:A1:87:78:2E:4C:49:3F:E3:B6:FD:2D:76:D3%3Bexample.javatpoint.com.kotlingooglemapcurrentlocation  
  
    Alternatively, follow the directions here:  
    https://developers.google.com/maps/documentation/android/start#get-key  
    -->  
    < string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyCuxsZ0D73o-REPLACE-WITH-YOUR-API< /string>  
< /resources>  
< resources>  
    < !--  
     https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=20:0B:71:3B:B2:46:75:A1:87:78:2E:4C:49:3F:E3:B6:FD:2D:76:D3%3Bexample.javatpoint.com.kotlingooglemapcurrentlocation  
  
    Alternatively, follow the directions here:  
    https://developers.google.com/maps/documentation/android/start#get-key  
    -->  
    < string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyCuxsZ0D73o-REPLACE-WITH-YOUR-API< /string>  
< /resources>   

MapsActivity.kt


Add the following code in MapsActivity.kt class file.


package example.javatpoint.com.kotlingooglemapcurrentlocation  
  
import android.content.pm.PackageManager  
import android.location.Location  
import android.os.Build  
import android.os.Bundle  
import android.support.v4.app.FragmentActivity  
import android.support.v4.content.ContextCompat  
import com.google.android.gms.common.ConnectionResult  
import com.google.android.gms.common.api.GoogleApiClient  
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.BitmapDescriptorFactory  
import com.google.android.gms.maps.model.LatLng  
import com.google.android.gms.maps.model.Marker  
import com.google.android.gms.maps.model.MarkerOptions  
import android.Manifest  
import android.os.Looper  
import android.widget.Toast  
import com.google.android.gms.location.*  
import com.google.android.gms.location.FusedLocationProviderClient  
import com.google.android.gms.location.LocationCallback  
import com.google.android.gms.location.LocationRequest  
import com.google.android.gms.location.LocationServices  
  
  
class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,  
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {  
  
    private var mMap: GoogleMap? = null  
    internal lateinit var mLastLocation: Location  
    internal lateinit var mLocationResult: LocationRequest  
    internal lateinit var mLocationCallback: LocationCallback  
    internal var mCurrLocationMarker: Marker? = null  
    internal var mGoogleApiClient: GoogleApiClient? = null  
    internal lateinit var mLocationRequest: LocationRequest  
    internal var mFusedLocationClient: FusedLocationProviderClient? = null  
  
  
    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  
  
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
            if (ContextCompat.checkSelfPermission(this,  
                            Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {  
                buildGoogleApiClient()  
                mMap!!.isMyLocationEnabled = true  
            }  
        } else {  
            buildGoogleApiClient()  
            mMap!!.isMyLocationEnabled = true  
        }  
  
    }  
  
    @Synchronized  
    protected fun buildGoogleApiClient() {  
        mGoogleApiClient = GoogleApiClient.Builder(this)  
                .addConnectionCallbacks(this)  
                .addOnConnectionFailedListener(this)  
                .addApi(LocationServices.API).build()  
        mGoogleApiClient!!.connect()  
    }  
  
    override fun onConnected(bundle: Bundle?) {  
  
        mLocationRequest = LocationRequest()  
        mLocationRequest.interval = 1000  
        mLocationRequest.fastestInterval = 1000  
        mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY  
        if (ContextCompat.checkSelfPermission(this,  
                        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {  
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)  
            mFusedLocationClient?.requestLocationUpdates(mLocationRequest,mLocationCallback, Looper.myLooper())  
        }  
    }  
  
  
    override fun onLocationChanged(location: Location) {  
  
        mLastLocation = location  
        if (mCurrLocationMarker != null) {  
            mCurrLocationMarker!!.remove()  
        }  
        //Place current location marker  
        val latLng = LatLng(location.latitude, location.longitude)  
        val markerOptions = MarkerOptions()  
        markerOptions.position(latLng)  
        markerOptions.title("Current Position")  
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))  
        mCurrLocationMarker = mMap!!.addMarker(markerOptions)  
  
        //move map camera  
        mMap!!.moveCamera(CameraUpdateFactory.newLatLng(latLng))  
        mMap!!.animateCamera(CameraUpdateFactory.zoomTo(11f))  
  
        //stop location updates  
        if (mGoogleApiClient != null) {  
            mFusedLocationClient?.removeLocationUpdates(mLocationCallback)  
        }  
    }  
  
    override fun onConnectionFailed(connectionResult: ConnectionResult) {  
        Toast.makeText(applicationContext,"connection failed", Toast.LENGTH_SHORT).show()  
    }  
  
    override fun onConnectionSuspended(p0: Int) {  
        Toast.makeText(applicationContext,"connection suspended", Toast.LENGTH_SHORT).show()  
    }  
}    
package example.javatpoint.com.kotlingooglemapcurrentlocation  
  
import android.content.pm.PackageManager  
import android.location.Location  
import android.os.Build  
import android.os.Bundle  
import android.support.v4.app.FragmentActivity  
import android.support.v4.content.ContextCompat  
import com.google.android.gms.common.ConnectionResult  
import com.google.android.gms.common.api.GoogleApiClient  
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.BitmapDescriptorFactory  
import com.google.android.gms.maps.model.LatLng  
import com.google.android.gms.maps.model.Marker  
import com.google.android.gms.maps.model.MarkerOptions  
import android.Manifest  
import android.os.Looper  
import android.widget.Toast  
import com.google.android.gms.location.*  
import com.google.android.gms.location.FusedLocationProviderClient  
import com.google.android.gms.location.LocationCallback  
import com.google.android.gms.location.LocationRequest  
import com.google.android.gms.location.LocationServices  
  
  
class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,  
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {  
  
    private var mMap: GoogleMap? = null  
    internal lateinit var mLastLocation: Location  
    internal lateinit var mLocationResult: LocationRequest  
    internal lateinit var mLocationCallback: LocationCallback  
    internal var mCurrLocationMarker: Marker? = null  
    internal var mGoogleApiClient: GoogleApiClient? = null  
    internal lateinit var mLocationRequest: LocationRequest  
    internal var mFusedLocationClient: FusedLocationProviderClient? = null  
  
  
    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  
  
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
            if (ContextCompat.checkSelfPermission(this,  
                            Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {  
                buildGoogleApiClient()  
                mMap!!.isMyLocationEnabled = true  
            }  
        } else {  
            buildGoogleApiClient()  
            mMap!!.isMyLocationEnabled = true  
        }  
  
    }  
  
    @Synchronized  
    protected fun buildGoogleApiClient() {  
        mGoogleApiClient = GoogleApiClient.Builder(this)  
                .addConnectionCallbacks(this)  
                .addOnConnectionFailedListener(this)  
                .addApi(LocationServices.API).build()  
        mGoogleApiClient!!.connect()  
    }  
  
    override fun onConnected(bundle: Bundle?) {  
  
        mLocationRequest = LocationRequest()  
        mLocationRequest.interval = 1000  
        mLocationRequest.fastestInterval = 1000  
        mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY  
        if (ContextCompat.checkSelfPermission(this,  
                        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {  
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)  
            mFusedLocationClient?.requestLocationUpdates(mLocationRequest,mLocationCallback, Looper.myLooper())  
        }  
    }  
  
  
    override fun onLocationChanged(location: Location) {  
  
        mLastLocation = location  
        if (mCurrLocationMarker != null) {  
            mCurrLocationMarker!!.remove()  
        }  
        //Place current location marker  
        val latLng = LatLng(location.latitude, location.longitude)  
        val markerOptions = MarkerOptions()  
        markerOptions.position(latLng)  
        markerOptions.title("Current Position")  
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))  
        mCurrLocationMarker = mMap!!.addMarker(markerOptions)  
  
        //move map camera  
        mMap!!.moveCamera(CameraUpdateFactory.newLatLng(latLng))  
        mMap!!.animateCamera(CameraUpdateFactory.zoomTo(11f))  
  
        //stop location updates  
        if (mGoogleApiClient != null) {  
            mFusedLocationClient?.removeLocationUpdates(mLocationCallback)  
        }  
    }  
  
    override fun onConnectionFailed(connectionResult: ConnectionResult) {  
        Toast.makeText(applicationContext,"connection failed", Toast.LENGTH_SHORT).show()  
    }  
  
    override fun onConnectionSuspended(p0: Int) {  
        Toast.makeText(applicationContext,"connection suspended", Toast.LENGTH_SHORT).show()  
    }  
}    

AndroidManifest.xml


< ?xml version="1.0" encoding="utf-8"?>  
< manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="example.javatpoint.com.kotlingooglemapcurrentlocation">  
  
    < uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
  
    < application  
        android:allowBackup="true"  
        android:icon="@mipmap/ic_launcher"  
        android:label="@string/app_name"  
        android:roundIcon="@mipmap/ic_launcher_round"  
        android:supportsRtl="true"  
        android:theme="@style/AppTheme">  
   
        < meta-data  
            android:name="com.google.android.geo.API_KEY"  
            android:value="@string/google_maps_key" />  
  
        < activity  
            android:name=".MapsActivity"  
            android:label="@string/title_activity_maps">  
            < intent-filter>  
                < action android:name="android.intent.action.MAIN" />  
  
                < category android:name="android.intent.category.LAUNCHER" />  
            < /intent-filter>  
        < /activity>  
    < /application>  
  
< /manifest>  
< ?xml version="1.0" encoding="utf-8"?>  
< manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="example.javatpoint.com.kotlingooglemapcurrentlocation">  
  
    < uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
  
    < application  
        android:allowBackup="true"  
        android:icon="@mipmap/ic_launcher"  
        android:label="@string/app_name"  
        android:roundIcon="@mipmap/ic_launcher_round"  
        android:supportsRtl="true"  
        android:theme="@style/AppTheme">  
   
        < meta-data  
            android:name="com.google.android.geo.API_KEY"  
            android:value="@string/google_maps_key" />  
  
        < activity  
            android:name=".MapsActivity"  
            android:label="@string/title_activity_maps">  
            < intent-filter>  
                < action android:name="android.intent.action.MAIN" />  
  
                < category android:name="android.intent.category.LAUNCHER" />  
            < /intent-filter>  
        < /activity>  
    < /application>  
  
< /manifest>  

Output:


Hi I am Pluto.