Google Map
Set up a map
Let's take our new key and add it to the project.
First, add the name of the key to a secrets.properties
file in the root directory of your
project. It should contain the following (replace YOUR_KEY_NAME_GOES_HERE
with your API key)
# DO NOT CHECK THIS FILE IN!
MAPS_API_KEY=YOUR_KEY_NAME_GOES_HERE
This file should NEVER be checked into git, as the key name is a secret. (Because
this file isn't checked in, and I'm using git to generate the code display on the right, I'll
show its contents below). Be sure to add secrets.properties
to the top-level .gitignore
file:
show in full file .gitignore
// ...
.cxx
local.properties
secrets.properties
To access the key, we'll use the "secrets" plugin, which reads secrets.properties
and makes the
properties available in other files.
To add the secrets plugin to your build, declare the version of the secrets plugin and the plugin artifact in your version catalog
show in full file gradle/libs.versions.toml
[versions]
// ...
activityCompose = "1.9.3"
composeBom = "2024.12.01"
secrets = "2.0.1"
maps-compose = "6.2.1"
// ...
[libraries]
// ...
[plugins]
// ...
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
//
secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" }
Declare that you want to use the plugin in your root build.gradle.kts. We use apply false
so it
doesn't do anything other than set up the plugin on the classpath for all modules that will use it.
show in full file build.gradle.kts
// ...
plugins {
// ...
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.secrets) apply false
}
Apply the plugin in your app/build.gradle.kts
and configure it to use our secrets.properties
file
show in full file app/build.gradle.kts
plugins {
// ...
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.secrets)
}
// ...
}
secrets {
propertiesFileName = "secrets.properties"
}
Then we can drop the key in the Manifest for Google Maps to find at runtime.
show in full file app/src/main/AndroidManifest.xml
// ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
// ...
<application
// ...
tools:targetApi="31">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
<activity
// ...
</application>
// ...
</manifest>
So far we don't have access to the Google Maps @Composable function, so we add versions and libraries to the version catalog:
show in full file gradle/libs.versions.toml
[versions]
// ...
secrets = "2.0.1"
maps-compose = "6.2.1"
[libraries]
maps-compose = { group = "com.google.maps.android", name = "maps-compose", version.ref = "maps-compose" }
maps-compose-utils = { group = "com.google.maps.android", name = "maps-compose-utils", version.ref = "maps-compose" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
// ...
[plugins]
// ...
Then add the dependencies to the app
's build script.
show in full file app/build.gradle.kts
// ...
dependencies {
//
implementation(libs.maps.compose)
implementation(libs.maps.compose.utils)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
// ...
}
// ...
Finally, add a Map to the UI
show in full file app/src/main/java/com/androidbyexample/compose/google/google/maps/MainActivity.kt
// ...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
setContent {
GoogleMapsTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
// Greeting(
// name = "Android",
// modifier = Modifier.padding(innerPadding)
// )
GoogleMap(
modifier = Modifier.padding(innerPadding).fillMaxSize(),
) {
// no content yet
}
}
}
}
}
}
// ...
When we run the app, we'll see
All code changes
CHANGED: .gitignore
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
secrets.properties
CHANGED: app/build.gradle.kts
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.secrets)
}
android {
namespace = "com.androidbyexample.compose.google.google.maps"
compileSdk = 35
defaultConfig {
applicationId = "com.androidbyexample.compose.google.google.maps"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
}
dependencies {
//
implementation(libs.maps.compose)
implementation(libs.maps.compose.utils)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
secrets {
propertiesFileName = "secrets.properties"
}
CHANGED: app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.GoogleMaps"
tools:targetApi="31">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.GoogleMaps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
CHANGED: app/src/main/java/com/androidbyexample/compose/google/google/maps/MainActivity.kt
package com.androidbyexample.compose.google.google.maps
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.androidbyexample.compose.google.google.maps.ui.theme.GoogleMapsTheme
import com.google.maps.android.compose.GoogleMap
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
GoogleMapsTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
// Greeting(
// name = "Android",
// modifier = Modifier.padding(innerPadding)
// )
GoogleMap(
modifier = Modifier.padding(innerPadding).fillMaxSize(),
) {
// no content yet
}
}
}
}
}
}
//
//@Composable
//fun Greeting(name: String, modifier: Modifier = Modifier) {
// Text(
// text = "Hello $name!",
// modifier = modifier
// )
//}
//
//@Preview(showBackground = true)
//@Composable
//fun GreetingPreview() {
// GoogleMapsTheme {
// Greeting("Android")
// }
//}
CHANGED: build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.secrets) apply false
}
CHANGED: gradle/libs.versions.toml
[versions]
agp = "8.7.3"
kotlin = "2.0.21"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.7"
activityCompose = "1.9.3"
composeBom = "2024.12.01"
secrets = "2.0.1"
maps-compose = "6.2.1"
[libraries]
maps-compose = { group = "com.google.maps.android", name = "maps-compose", version.ref = "maps-compose" }
maps-compose-utils = { group = "com.google.maps.android", name = "maps-compose-utils", version.ref = "maps-compose" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
//
secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" }