Google Maps in Jetpack Compose Android

Muhammad Danish
Geek Culture
Published in
2 min readMay 25, 2021

--

Integration of google maps is little bit difficult in jetpack compose as compare to android xml. But with out Xml we can’t integrate google maps in jetpack compose android app too.

In order to integrate google maps in jetpack compose you need to generate google map api key from google cloud console then you need to add below 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.3.2")

After that add meta data tag with your google map api key and internet permission in android manifest.xml file

<uses-permission android:name="android.permission.INTERNET"/><meta-data android:name="com.google.android.geo.API_KEY"
android:value="Api_key_here"/>

Now create a new directory under res directory and named it as layout and create a new resource file as i created layout_map.xml file and add below code in this file

<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"/>

Now you will be wondering how can we use this in jetpack compose so don’t worry I am going to show you that as well.

Now create a new file as i named it as MapUtils.kt and add below code in it

@Composable
fun rememberMapViewWithLifecycle(): MapView {
val context = LocalContext.current
val mapView = remember {
MapView(context).apply {
id = R.id.map
}
}

// Makes MapView follow the lifecycle of this composable
val lifecycleObserver = rememberMapLifecycleObserver(mapView)
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect
(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}

return mapView
}

@Composable
fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
remember(mapView) {
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()
}
}
}

These are two composable functions which we are going to use. I copied these functions from https://github.com/joreilly/GalwayBus you can have a look for more information.

After that you need to write below in your activity composable function

val mapView = rememberMapViewWithLifecycle()

We can use Xml layout files using AndroidView() in composable functions

Column(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color.White)
) {
AndroidView({ mapView}) {mapView->
CoroutineScope(Dispatchers.Main).launch {
val map = mapView.awaitMap()
map.uiSettings.isZoomControlsEnabled = true

val pickUp = LatLng(-35.016, 143.321)
val destination = LatLng(-32.491, 147.309)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(destination,6f))
val markerOptions = MarkerOptions()
.title("Sydney Opera House")
.position(pickUp)
map.addMarker(markerOptions)

val markerOptionsDestination = MarkerOptions()
.title("Restaurant Hubert")
.position(destination)
map.addMarker(markerOptionsDestination)

map.addPolyline(PolylineOptions().add( pickUp,
LatLng(-34.747, 145.592),
LatLng(-34.364, 147.891),
LatLng(-33.501, 150.217),
LatLng(-32.306, 149.248),
destination))

}



}
}

I have intialized map in Coroutine scope and draw two markers on map and then i draw polyline for routine showing.

Finally the output :

If you face any issue then please comment so that i can help you.

--

--