Many applications such as Swiggy, Zomato, Ola, and others use Google Maps within their application to display the location within their application. Most of these applications use Google Maps to display the details within their application. In this article, we will take a look at How to integrate Google Maps in Android using Jetpack Compose.
Step by Step Implementation
Step 1: Create a New Project in Android Studio
To create a new project in the Android Studio, please refer to How to Create a new Project in Android Studio with Jetpack Compose.
Step 2: Adding dependency to use Google Maps
Navigate to build.gradle file and add the below dependency in the build.gradle file.
dependencies {
...
implementation("com.google.android.libraries.maps:maps:3.1.0-beta")
implementation("com.google.maps.android:maps-v3-ktx:2.2.0")
implementation("androidx.fragment:fragment:1.8.6")
implementation("com.google.android.gms:play-services-maps:19.1.0")
}
After adding the dependency simply click on the sync now option to install it.
Step 3: Adding permissions and google maps API key
Navigate to app > AndroidManifest.xml file and add the below code in the application tag for adding the API key.
<application
...
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="Enter your API key" />
</application>
Check out the below article on How to generate API key for Google Maps in Android.
Step 4: Create a new layout file for the map layout
Navigate to app > res, Right click on it, New > Directory and name it as layout. Now right-click on that directory and click on New > Layout resource file. Create a new XML file and name it map_layout and add the below code to it. Comments are added in the code to get to know it in detail.
map_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Step 5: Create a new file for creating a Map
Navigate to app > kotlin+java > {package-name} Right click on it, New > Kotlin Class/File and name it as MapUtils and add the below code to it. Comments are added in the code to get to know it in detail.
MapUtils.kt:
package com.geeksforgeeks.demo
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.google.android.libraries.maps.MapView
// on below line creating a new
// composable widget for displaying map
@Composable
fun rememberMapViewWithLifecycle(): MapView {
val context = LocalContext.current
// on below line initializing
// our maps view with id.
val mapView = remember {
MapView(context).apply {
id = R.id.map
}
}
// Makes MapView follow the lifecycle of this composable
val lifecycleObserver = rememberMapLifecycleObserver(mapView)
// on below line initializing lifecycle variable.
val lifecycle = LocalLifecycleOwner.current.lifecycle
// on below line adding observer for lifecycle.
DisposableEffect(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
// returning map view on below line.
return mapView
}
@Composable
// creating a function for map lifecycle observer.
fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
remember(mapView) {
// on below line adding different events for maps view
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
Lifecycle.Event.ON_START -> mapView.onStart()
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_STOP -> mapView.onStop()
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
else -> throw IllegalStateException()
}
}
}
Step 6: Working with MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
MainActivity.kt:
package com.geeksforgeeks.demo
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.viewinterop.AndroidView
import com.geeksforgeeks.demo.ui.theme.DemoTheme
import com.google.maps.android.ktx.awaitMap
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DemoTheme {
MapScreen()
}
}
}
}
@Composable
fun MapScreen() {
val mapView = rememberMapViewWithLifecycle()
Column(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color.White)
) {
// Map View
AndroidView({ mapView }) { mapView ->
// launch map view
CoroutineScope(Dispatchers.Main).launch {
val map = mapView.awaitMap()
// adding zoom controls
map.uiSettings.isZoomControlsEnabled = true
}
}
}
}
Output:
