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 your local.properties
file in the root directory of your project. 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)
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\Android\\sdk
MAPS_API_KEY=YOUR_KEY_NAME_GOES_HERE
(Don't worry about that comment at the top; the MAPS_API_KEY really goes here. If you re-checkout the project, you'll need to add this key again)
To access the key, we'll use the "secrets" plugin, which reads local.properties
and makes the properties available in other files.
To add the secrets plugin to your build:
- Declare the version of the secrets plugin in your version catalog.
- Declare the plugin variable in your version catalog.
- Declare that you want to use the plugin in your root build.gradle.kts.
- Apply the plugin in your
app/build.gradle.kts
Then we can drop the key in the Manifest for Google Maps to find at runtime.
So far we don't have access to the Google Maps @Composable function, so we add
versions and
dependency variables, then
add dependencies to the app
's build script.
Finally! Time to add a Map to the UI!
When we run the app, we'll see
Code Changes
CHANGED: /app/build.gradle.kts
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.kotlinAndroid)alias(libs.plugins.secrets)} kotlin { jvmToolchain(17) } android { namespace = "com.androidbyexample.googlemap" compileSdk = 34 defaultConfig { applicationId = "com.androidbyexample.googlemap" minSdk = 24 targetSdk = 34 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } buildFeatures { compose = true } composeOptions { kotlinCompilerExtensionVersion = "1.5.3" } packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } } dependencies {implementation(libs.maps.compose) implementation(libs.maps.compose.utils)implementation(libs.core.ktx) implementation(libs.lifecycle.runtime.ktx) implementation(libs.activity.compose) implementation(platform(libs.compose.bom)) implementation(libs.ui) implementation(libs.ui.graphics) implementation(libs.ui.tooling.preview) implementation(libs.material3) testImplementation(libs.junit) androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.espresso.core) androidTestImplementation(platform(libs.compose.bom)) androidTestImplementation(libs.ui.test.junit4) debugImplementation(libs.ui.tooling) debugImplementation(libs.ui.test.manifest) }
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.GoogleMap" 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.GoogleMap"> <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/googlemap/MainActivity.kt
package com.androidbyexample.googlemap import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface//import androidx.compose.material3.Text//import androidx.compose.runtime.Composableimport androidx.compose.ui.Modifier//import androidx.compose.ui.tooling.preview.Previewimport com.androidbyexample.googlemap.ui.theme.GoogleMapTheme import com.google.maps.android.compose.GoogleMap class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { GoogleMapTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) {} } } } }// Greeting("Android")GoogleMap( modifier = Modifier.fillMaxSize(), ) {// no content yet }//@Composable//fun Greeting(name: String, modifier: Modifier = Modifier) {// Text(// text = "Hello $name!",// modifier = modifier// )//}//@Preview(showBackground = true)//@Composable//fun GreetingPreview() {// GoogleMapTheme {// Greeting("Android")// }//}
CHANGED: /app/src/main/res/values/strings.xml
<resources>// <string name="app_name">Car Finder</string><string name="app_name">Google map</string></resources>
CHANGED: /build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules. @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { alias(libs.plugins.androidApplication) apply false alias(libs.plugins.kotlinAndroid) apply falsealias(libs.plugins.secrets) apply false} true // Needed to make the Suppress annotation work for the plugins block
CHANGED: /gradle/libs.versions.toml
[versions] agp = "8.2.0-beta06" kotlin = "1.9.10" core-ktx = "1.12.0" junit = "4.13.2" androidx-test-ext-junit = "1.1.5" espresso-core = "3.5.1" lifecycle-runtime-ktx = "2.6.2" activity-compose = "1.8.0" compose-bom = "2023.10.00"secrets = "2.0.1"maps-compose = "3.0.0" # bug in 3.1.0 - map only takes up 50% of column[libraries] core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-ktx" } activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity-compose" } compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" } ui = { group = "androidx.compose.ui", name = "ui" } ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } material3 = { group = "androidx.compose.material3", name = "material3" }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" }[plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" }
CHANGED: /settings.gradle.kts
pluginManagement { repositories { google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }//rootProject.name = "Car Finder"rootProject.name = "Google map"include(":app")