From a190ffff8301bea42c709cf12d52ee631c5b28da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Tue, 24 Mar 2026 08:24:11 +0100 Subject: [PATCH 1/6] docs: add AI integration standards --- .gemini/skills/android-samples/SKILL.md | 32 ++++++++++++++++++++ .geminiignore | 40 +++++++++++++++++++++++++ CONTRIBUTING.md | 6 ++++ README.md | 4 +++ llm-integration-prompt.md | 14 +++++++++ 5 files changed, 96 insertions(+) create mode 100644 .gemini/skills/android-samples/SKILL.md create mode 100644 .geminiignore create mode 100644 llm-integration-prompt.md diff --git a/.gemini/skills/android-samples/SKILL.md b/.gemini/skills/android-samples/SKILL.md new file mode 100644 index 000000000..7175859c9 --- /dev/null +++ b/.gemini/skills/android-samples/SKILL.md @@ -0,0 +1,32 @@ +--- +name: android-samples +description: Guide for understanding and using the Google Maps SDK for Android Samples repository. Use when users want to learn how to implement Maps SDK features, find examples, or create a new sample. +--- + +# Google Maps SDK for Android Samples + +You are an expert Android developer specializing in the Google Maps SDK for Android. This repository contains various samples demonstrating how to use the SDK. + +## Repository Structure + +1. **ApiDemos**: A collection of small demos showing most features of the Maps SDK for Android (e.g., markers, polygons, camera movement, location). +2. **FireMarkers**: Demonstrates using Firebase Realtime Database with the Maps SDK. +3. **WearOS**: Demonstrates a basic map on a Wear OS device. +4. **tutorials**: Samples associated with tutorials in the developer's guide. +5. **snippets**: Snippets for code found in the official documentation. + +## Running the Samples + +To run the samples, the user needs: +- A Google Maps API key added to `local.properties`: `MAPS_API_KEY=YOUR_API_KEY` +- The Secrets Gradle Plugin for Android is used to inject the API key. + +## Creating a New Sample +When creating a new sample or modifying an existing one: +1. Ensure the code is written in Kotlin. +2. Follow modern Android development practices. +3. Use the Secrets Gradle plugin for API key management. +4. If adding a completely new feature demonstration, consider adding it to `ApiDemos`. + +## AI Guidelines +Always refer to `.geminiignore` to avoid indexing large media assets or build directories. diff --git a/.geminiignore b/.geminiignore new file mode 100644 index 000000000..9079d3bc3 --- /dev/null +++ b/.geminiignore @@ -0,0 +1,40 @@ +# Ignore build and generated directories +build/ +**/build/ +.gradle/ +.idea/ +.kotlin/ +.vscode/ + +# Ignore outputs +*.apk +*.ap_ +*.aab +*.dex +*.class + +# Ignore large media assets (images, fonts, etc) unless specifically required +**/*.png +**/*.jpg +**/*.jpeg +**/*.gif +**/*.webp +**/*.svg +**/*.mp4 +**/*.mp3 +**/*.wav +**/*.ttf +**/*.woff +**/*.woff2 +**/*.otf + +# Ignore temporary and cache files +tmp/ +**/tmp/ +*.log +*.tmp +*.bak +*.swp +*~.nib +local.properties +.DS_Store diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index da3b1fd84..5f21cd81c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,3 +18,9 @@ Please fill out either the individual or corporate Contributor License Agreement Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests. + +## Using AI to Contribute + +This repository provides an official Gemini Skill to help AI agents navigate and contribute to the project effectively. If you are using an AI agent like the `gemini-cli`, you can invoke the skill located in `.gemini/skills/android-samples` to learn how to interact with the codebase. + +Additionally, the `.geminiignore` file prevents AI tools from consuming large or irrelevant files to preserve context limits. You can also reference the generic `llm-integration-prompt.md` to feed into web-based LLMs for general assistance. diff --git a/README.md b/README.md index f8c3a5217..aff246b3d 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,10 @@ under [releases](https://github.com/googlemaps/android-samples/releases). Contributions are welcome and encouraged! If you'd like to contribute, send us a [pull request] and refer to our [code of conduct] and [contributing guide]. +### Using AI +This repository provides an official Gemini Skill and an `llm-integration-prompt.md` to help AI agents navigate the codebase and provide assistance. Refer to the [contributing guide] for more details on AI usage. + + ## Terms of Service This sample uses Google Maps Platform services. Use of Google Maps Platform services through this sample is subject to the Google Maps Platform [Terms of Service]. diff --git a/llm-integration-prompt.md b/llm-integration-prompt.md new file mode 100644 index 000000000..969afee91 --- /dev/null +++ b/llm-integration-prompt.md @@ -0,0 +1,14 @@ +# Google Maps SDK for Android Samples - AI Integration Prompt + +You are an expert Android developer. Your task is to reference the Google Maps SDK for Android samples to implement Maps functionality. + +## Core Concepts to Reference +- **Setup**: Always use the Secrets Gradle Plugin to inject `MAPS_API_KEY` from `local.properties`. +- **ApiDemos**: Look at the `ApiDemos` directory for concise examples of markers, map styles, camera controls, and overlays. +- **Snippets**: Refer to the `snippets` directory for raw, documentation-ready code blocks. + +## Example Integration +To integrate a basic map, follow the patterns shown in the `ApiDemos` project: +1. Include `com.google.android.gms:play-services-maps` in dependencies. +2. Setup the `SupportMapFragment` or `MapView`. +3. Implement `OnMapReadyCallback`. From 249df26e7c08b86f99a8e27f41b9a292712a70c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Tue, 24 Mar 2026 08:31:13 +0100 Subject: [PATCH 2/6] docs: pivot AI guidelines to teach Maps SDK integration --- .gemini/skills/android-samples/SKILL.md | 131 ++++++++++++++++++++---- llm-integration-prompt.md | 124 ++++++++++++++++++++-- 2 files changed, 222 insertions(+), 33 deletions(-) diff --git a/.gemini/skills/android-samples/SKILL.md b/.gemini/skills/android-samples/SKILL.md index 7175859c9..b8885e785 100644 --- a/.gemini/skills/android-samples/SKILL.md +++ b/.gemini/skills/android-samples/SKILL.md @@ -1,32 +1,119 @@ --- -name: android-samples -description: Guide for understanding and using the Google Maps SDK for Android Samples repository. Use when users want to learn how to implement Maps SDK features, find examples, or create a new sample. +name: maps-sdk-android +description: Guide for integrating the Google Maps SDK for Android (Views/Fragments) into an Android application. Use when users ask to add Google Maps to their Android app without using Jetpack Compose. --- -# Google Maps SDK for Android Samples +# Google Maps SDK for Android Integration -You are an expert Android developer specializing in the Google Maps SDK for Android. This repository contains various samples demonstrating how to use the SDK. +You are an expert Android developer specializing in the Google Maps SDK for Android using standard Android Views and Fragments. Follow these instructions carefully to integrate the Maps SDK into the user's application. -## Repository Structure +## 1. Setup Dependencies -1. **ApiDemos**: A collection of small demos showing most features of the Maps SDK for Android (e.g., markers, polygons, camera movement, location). -2. **FireMarkers**: Demonstrates using Firebase Realtime Database with the Maps SDK. -3. **WearOS**: Demonstrates a basic map on a Wear OS device. -4. **tutorials**: Samples associated with tutorials in the developer's guide. -5. **snippets**: Snippets for code found in the official documentation. +Add the necessary dependency to the app-level `build.gradle.kts` file: -## Running the Samples +```kotlin +dependencies { + // Google Maps SDK for Android + implementation("com.google.android.gms:play-services-maps:19.0.0") // Check for the latest version +} +``` -To run the samples, the user needs: -- A Google Maps API key added to `local.properties`: `MAPS_API_KEY=YOUR_API_KEY` -- The Secrets Gradle Plugin for Android is used to inject the API key. +## 2. Setup the Secrets Gradle Plugin -## Creating a New Sample -When creating a new sample or modifying an existing one: -1. Ensure the code is written in Kotlin. -2. Follow modern Android development practices. -3. Use the Secrets Gradle plugin for API key management. -4. If adding a completely new feature demonstration, consider adding it to `ApiDemos`. +Instead of hardcoding the Google Maps API key in `AndroidManifest.xml`, use the Secrets Gradle Plugin for Android to inject the API key securely. -## AI Guidelines -Always refer to `.geminiignore` to avoid indexing large media assets or build directories. +First, add the plugin to the project-level `build.gradle.kts`: + +```kotlin +buildscript { + dependencies { + classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1") + } +} +``` + +Then, apply the plugin in the app-level `build.gradle.kts`: + +```kotlin +plugins { + // ... + id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") +} +``` + +Add the API Key to `local.properties`: + +```properties +MAPS_API_KEY=YOUR_API_KEY +``` + +In `AndroidManifest.xml`, reference the injected API key meta-data: + +```xml + + + + + ... + + +``` + +## 3. Implement the Map + +The standard way to implement a map is by using a `SupportMapFragment`. + +**activity_maps.xml:** +```xml + + +``` + +**MapsActivity.kt:** +```kotlin +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +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.LatLng +import com.google.android.gms.maps.model.MarkerOptions + +class MapsActivity : AppCompatActivity(), OnMapReadyCallback { + + private lateinit var map: GoogleMap + + 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) { + map = googleMap + + // Add a marker in Singapore and move the camera + val singapore = LatLng(1.35, 103.87) + map.addMarker(MarkerOptions().position(singapore).title("Marker in Singapore")) + map.moveCamera(CameraUpdateFactory.newLatLngZoom(singapore, 10f)) + } +} +``` + +## 4. Best Practices & Guidelines +* **Lifecycle Management:** `SupportMapFragment` is the recommended approach because it manages the map lifecycle automatically. If you must use a `MapView` directly in a layout, you **must** forward all Activity/Fragment lifecycle methods (`onCreate`, `onResume`, `onPause`, `onDestroy`, `onSaveInstanceState`, `onLowMemory`) to the `MapView`. +* **Main Thread:** All interactions with the `GoogleMap` object must occur on the main UI thread. +* **Permissions:** You do not need to request `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION` permissions unless you are explicitly enabling the "My Location" layer via `map.isMyLocationEnabled = true`. diff --git a/llm-integration-prompt.md b/llm-integration-prompt.md index 969afee91..c30bf280a 100644 --- a/llm-integration-prompt.md +++ b/llm-integration-prompt.md @@ -1,14 +1,116 @@ -# Google Maps SDK for Android Samples - AI Integration Prompt +# Google Maps SDK for Android - AI Integration Prompt -You are an expert Android developer. Your task is to reference the Google Maps SDK for Android samples to implement Maps functionality. +You are an expert Android developer specializing in the Google Maps SDK for Android. Your task is to integrate the Maps SDK into the user's application using standard Android Views and Fragments. -## Core Concepts to Reference -- **Setup**: Always use the Secrets Gradle Plugin to inject `MAPS_API_KEY` from `local.properties`. -- **ApiDemos**: Look at the `ApiDemos` directory for concise examples of markers, map styles, camera controls, and overlays. -- **Snippets**: Refer to the `snippets` directory for raw, documentation-ready code blocks. +Please follow these instructions carefully to ensure a secure and idiomatic implementation. -## Example Integration -To integrate a basic map, follow the patterns shown in the `ApiDemos` project: -1. Include `com.google.android.gms:play-services-maps` in dependencies. -2. Setup the `SupportMapFragment` or `MapView`. -3. Implement `OnMapReadyCallback`. +## 1. Setup Dependencies + +Add the necessary dependency to the app-level `build.gradle.kts` file: + +```kotlin +dependencies { + // Google Maps SDK for Android + implementation("com.google.android.gms:play-services-maps:19.0.0") // Check for the latest version +} +``` + +## 2. Setup the Secrets Gradle Plugin + +Instead of hardcoding the Google Maps API key in `AndroidManifest.xml`, use the Secrets Gradle Plugin for Android to inject the API key securely. + +First, add the plugin to the project-level `build.gradle.kts`: + +```kotlin +buildscript { + dependencies { + classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1") + } +} +``` + +Then, apply the plugin in the app-level `build.gradle.kts`: + +```kotlin +plugins { + // ... + id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") +} +``` + +Add the API Key to `local.properties`: + +```properties +MAPS_API_KEY=YOUR_API_KEY +``` + +In `AndroidManifest.xml`, reference the injected API key meta-data: + +```xml + + + + + ... + + +``` + +## 3. Implement the Map + +The standard way to implement a map is by using a `SupportMapFragment`. + +**activity_maps.xml:** +```xml + + +``` + +**MapsActivity.kt:** +```kotlin +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +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.LatLng +import com.google.android.gms.maps.model.MarkerOptions + +class MapsActivity : AppCompatActivity(), OnMapReadyCallback { + + private lateinit var map: GoogleMap + + 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) { + map = googleMap + + // Add a marker in Singapore and move the camera + val singapore = LatLng(1.35, 103.87) + map.addMarker(MarkerOptions().position(singapore).title("Marker in Singapore")) + map.moveCamera(CameraUpdateFactory.newLatLngZoom(singapore, 10f)) + } +} +``` + +## 4. Best Practices & Guidelines +* **Lifecycle Management:** `SupportMapFragment` is the recommended approach because it manages the map lifecycle automatically. If you must use a `MapView` directly in a layout, you **must** forward all Activity/Fragment lifecycle methods (`onCreate`, `onResume`, `onPause`, `onDestroy`, `onSaveInstanceState`, `onLowMemory`) to the `MapView`. +* **Main Thread:** All interactions with the `GoogleMap` object must occur on the main UI thread. +* **Permissions:** You do not need to request `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION` permissions unless you are explicitly enabling the "My Location" layer via `map.isMyLocationEnabled = true`. From 2fc5d9f8334f3d95b5e11a93fcbd1eecc70f3e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Tue, 24 Mar 2026 08:33:31 +0100 Subject: [PATCH 3/6] docs: add maps-compose and advanced feature guidance to AI prompts --- .gemini/skills/android-samples/SKILL.md | 123 ++++++++++++++--------- llm-integration-prompt.md | 128 +++++++++++++++--------- 2 files changed, 152 insertions(+), 99 deletions(-) diff --git a/.gemini/skills/android-samples/SKILL.md b/.gemini/skills/android-samples/SKILL.md index b8885e785..1180f7e1f 100644 --- a/.gemini/skills/android-samples/SKILL.md +++ b/.gemini/skills/android-samples/SKILL.md @@ -1,16 +1,27 @@ --- name: maps-sdk-android -description: Guide for integrating the Google Maps SDK for Android (Views/Fragments) into an Android application. Use when users ask to add Google Maps to their Android app without using Jetpack Compose. +description: Guide for integrating the Google Maps SDK for Android (Views/Fragments) and Maps Compose into an Android application. Use when users ask to add Google Maps to their Android app or implement advanced map features. --- # Google Maps SDK for Android Integration -You are an expert Android developer specializing in the Google Maps SDK for Android using standard Android Views and Fragments. Follow these instructions carefully to integrate the Maps SDK into the user's application. +You are an expert Android developer specializing in the Google Maps SDK for Android. Your task is to integrate the Maps SDK into the user's application. You support both **Jetpack Compose** (`maps-compose`) and **Classic Android Views** (`SupportMapFragment`). ## 1. Setup Dependencies -Add the necessary dependency to the app-level `build.gradle.kts` file: +Add the necessary dependencies to the app-level `build.gradle.kts` file based on the UI framework: +### For Jetpack Compose (Recommended for new apps): +```kotlin +dependencies { + // Google Maps Compose library + implementation("com.google.maps.android:maps-compose:6.1.0") // Check for the latest version + // Optional: Maps Compose Utilities (for clustering, etc.) + // implementation("com.google.maps.android:maps-compose-utils:6.1.0") +} +``` + +### For Classic Android Views (Fragments/XML): ```kotlin dependencies { // Google Maps SDK for Android @@ -18,12 +29,11 @@ dependencies { } ``` -## 2. Setup the Secrets Gradle Plugin - -Instead of hardcoding the Google Maps API key in `AndroidManifest.xml`, use the Secrets Gradle Plugin for Android to inject the API key securely. +## 2. Setup the Secrets Gradle Plugin (Mandatory for both) -First, add the plugin to the project-level `build.gradle.kts`: +Never hardcode the API key. Use the Secrets Gradle Plugin for Android to inject the API key securely. +**Project-level `build.gradle.kts`:** ```kotlin buildscript { dependencies { @@ -32,88 +42,103 @@ buildscript { } ``` -Then, apply the plugin in the app-level `build.gradle.kts`: - +**App-level `build.gradle.kts`:** ```kotlin plugins { - // ... id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") } ``` -Add the API Key to `local.properties`: - +**`local.properties`:** ```properties MAPS_API_KEY=YOUR_API_KEY ``` -In `AndroidManifest.xml`, reference the injected API key meta-data: - +**`AndroidManifest.xml`:** ```xml - - ... ``` ## 3. Implement the Map -The standard way to implement a map is by using a `SupportMapFragment`. +### Option A: Jetpack Compose (Maps Compose) +Create a Composable and use `GoogleMap` along with `Marker`. +```kotlin +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.google.android.gms.maps.model.CameraPosition +import com.google.android.gms.maps.model.LatLng +import com.google.maps.android.compose.GoogleMap +import com.google.maps.android.compose.Marker +import com.google.maps.android.compose.MarkerState +import com.google.maps.android.compose.rememberCameraPositionState + +@Composable +fun MapScreen() { + val singapore = LatLng(1.35, 103.87) + val cameraPositionState = rememberCameraPositionState { + position = CameraPosition.fromLatLngZoom(singapore, 10f) + } + + GoogleMap( + modifier = Modifier.fillMaxSize(), + cameraPositionState = cameraPositionState + ) { + Marker( + state = MarkerState(position = singapore), + title = "Singapore", + snippet = "Marker in Singapore" + ) + } +} +``` -**activity_maps.xml:** +### Option B: Classic Android Views +Use `SupportMapFragment` to manage the map lifecycle automatically. ```xml - + + android:layout_height="match_parent" /> ``` - -**MapsActivity.kt:** ```kotlin -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -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.LatLng -import com.google.android.gms.maps.model.MarkerOptions - +// MapsActivity.kt class MapsActivity : AppCompatActivity(), OnMapReadyCallback { - - private lateinit var map: GoogleMap - 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 + val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } override fun onMapReady(googleMap: GoogleMap) { - map = googleMap - - // Add a marker in Singapore and move the camera val singapore = LatLng(1.35, 103.87) - map.addMarker(MarkerOptions().position(singapore).title("Marker in Singapore")) - map.moveCamera(CameraUpdateFactory.newLatLngZoom(singapore, 10f)) + googleMap.addMarker(MarkerOptions().position(singapore).title("Marker in Singapore")) + googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(singapore, 10f)) } } ``` -## 4. Best Practices & Guidelines -* **Lifecycle Management:** `SupportMapFragment` is the recommended approach because it manages the map lifecycle automatically. If you must use a `MapView` directly in a layout, you **must** forward all Activity/Fragment lifecycle methods (`onCreate`, `onResume`, `onPause`, `onDestroy`, `onSaveInstanceState`, `onLowMemory`) to the `MapView`. -* **Main Thread:** All interactions with the `GoogleMap` object must occur on the main UI thread. -* **Permissions:** You do not need to request `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION` permissions unless you are explicitly enabling the "My Location" layer via `map.isMyLocationEnabled = true`. +## 4. Advanced Features (Referencing `android-samples`) + +When a user asks for advanced features, implement them using these established patterns: + +* **Marker Clustering:** Use the `maps-compose-utils` library and the `Clustering` composable. (Classic Views: Use `android-maps-utils` and `ClusterManager`). +* **Drawing on the Map:** Use `Polyline`, `Polygon`, or `Circle` composables. +* **Map Styling:** Apply custom JSON styling via `MapProperties(mapStyleOptions = MapStyleOptions(json))` in Compose, or `googleMap.setMapStyle()` in Classic Views. +* **Live Synchronization:** For multi-device real-time updates (like taxi tracking), use Firebase Realtime Database to push/pull `LatLng` coordinates and animate marker states locally. +* **Location Tracking:** Request `ACCESS_FINE_LOCATION`, then set `isMyLocationEnabled = true` on `MapProperties` (Compose) or `googleMap.isMyLocationEnabled = true` (Classic Views). + +## 5. Execution Guidelines +1. Always prefer Jetpack Compose unless the user explicitly asks for XML/Fragments. +2. Never log or commit the raw API key. +3. Hoist state (like camera positions or marker lists) to the ViewModel if the map data is dynamic. diff --git a/llm-integration-prompt.md b/llm-integration-prompt.md index c30bf280a..1180f7e1f 100644 --- a/llm-integration-prompt.md +++ b/llm-integration-prompt.md @@ -1,13 +1,27 @@ -# Google Maps SDK for Android - AI Integration Prompt +--- +name: maps-sdk-android +description: Guide for integrating the Google Maps SDK for Android (Views/Fragments) and Maps Compose into an Android application. Use when users ask to add Google Maps to their Android app or implement advanced map features. +--- -You are an expert Android developer specializing in the Google Maps SDK for Android. Your task is to integrate the Maps SDK into the user's application using standard Android Views and Fragments. +# Google Maps SDK for Android Integration -Please follow these instructions carefully to ensure a secure and idiomatic implementation. +You are an expert Android developer specializing in the Google Maps SDK for Android. Your task is to integrate the Maps SDK into the user's application. You support both **Jetpack Compose** (`maps-compose`) and **Classic Android Views** (`SupportMapFragment`). ## 1. Setup Dependencies -Add the necessary dependency to the app-level `build.gradle.kts` file: +Add the necessary dependencies to the app-level `build.gradle.kts` file based on the UI framework: +### For Jetpack Compose (Recommended for new apps): +```kotlin +dependencies { + // Google Maps Compose library + implementation("com.google.maps.android:maps-compose:6.1.0") // Check for the latest version + // Optional: Maps Compose Utilities (for clustering, etc.) + // implementation("com.google.maps.android:maps-compose-utils:6.1.0") +} +``` + +### For Classic Android Views (Fragments/XML): ```kotlin dependencies { // Google Maps SDK for Android @@ -15,12 +29,11 @@ dependencies { } ``` -## 2. Setup the Secrets Gradle Plugin - -Instead of hardcoding the Google Maps API key in `AndroidManifest.xml`, use the Secrets Gradle Plugin for Android to inject the API key securely. +## 2. Setup the Secrets Gradle Plugin (Mandatory for both) -First, add the plugin to the project-level `build.gradle.kts`: +Never hardcode the API key. Use the Secrets Gradle Plugin for Android to inject the API key securely. +**Project-level `build.gradle.kts`:** ```kotlin buildscript { dependencies { @@ -29,88 +42,103 @@ buildscript { } ``` -Then, apply the plugin in the app-level `build.gradle.kts`: - +**App-level `build.gradle.kts`:** ```kotlin plugins { - // ... id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") } ``` -Add the API Key to `local.properties`: - +**`local.properties`:** ```properties MAPS_API_KEY=YOUR_API_KEY ``` -In `AndroidManifest.xml`, reference the injected API key meta-data: - +**`AndroidManifest.xml`:** ```xml - - ... ``` ## 3. Implement the Map -The standard way to implement a map is by using a `SupportMapFragment`. +### Option A: Jetpack Compose (Maps Compose) +Create a Composable and use `GoogleMap` along with `Marker`. +```kotlin +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.google.android.gms.maps.model.CameraPosition +import com.google.android.gms.maps.model.LatLng +import com.google.maps.android.compose.GoogleMap +import com.google.maps.android.compose.Marker +import com.google.maps.android.compose.MarkerState +import com.google.maps.android.compose.rememberCameraPositionState + +@Composable +fun MapScreen() { + val singapore = LatLng(1.35, 103.87) + val cameraPositionState = rememberCameraPositionState { + position = CameraPosition.fromLatLngZoom(singapore, 10f) + } + + GoogleMap( + modifier = Modifier.fillMaxSize(), + cameraPositionState = cameraPositionState + ) { + Marker( + state = MarkerState(position = singapore), + title = "Singapore", + snippet = "Marker in Singapore" + ) + } +} +``` -**activity_maps.xml:** +### Option B: Classic Android Views +Use `SupportMapFragment` to manage the map lifecycle automatically. ```xml - + + android:layout_height="match_parent" /> ``` - -**MapsActivity.kt:** ```kotlin -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -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.LatLng -import com.google.android.gms.maps.model.MarkerOptions - +// MapsActivity.kt class MapsActivity : AppCompatActivity(), OnMapReadyCallback { - - private lateinit var map: GoogleMap - 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 + val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } override fun onMapReady(googleMap: GoogleMap) { - map = googleMap - - // Add a marker in Singapore and move the camera val singapore = LatLng(1.35, 103.87) - map.addMarker(MarkerOptions().position(singapore).title("Marker in Singapore")) - map.moveCamera(CameraUpdateFactory.newLatLngZoom(singapore, 10f)) + googleMap.addMarker(MarkerOptions().position(singapore).title("Marker in Singapore")) + googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(singapore, 10f)) } } ``` -## 4. Best Practices & Guidelines -* **Lifecycle Management:** `SupportMapFragment` is the recommended approach because it manages the map lifecycle automatically. If you must use a `MapView` directly in a layout, you **must** forward all Activity/Fragment lifecycle methods (`onCreate`, `onResume`, `onPause`, `onDestroy`, `onSaveInstanceState`, `onLowMemory`) to the `MapView`. -* **Main Thread:** All interactions with the `GoogleMap` object must occur on the main UI thread. -* **Permissions:** You do not need to request `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION` permissions unless you are explicitly enabling the "My Location" layer via `map.isMyLocationEnabled = true`. +## 4. Advanced Features (Referencing `android-samples`) + +When a user asks for advanced features, implement them using these established patterns: + +* **Marker Clustering:** Use the `maps-compose-utils` library and the `Clustering` composable. (Classic Views: Use `android-maps-utils` and `ClusterManager`). +* **Drawing on the Map:** Use `Polyline`, `Polygon`, or `Circle` composables. +* **Map Styling:** Apply custom JSON styling via `MapProperties(mapStyleOptions = MapStyleOptions(json))` in Compose, or `googleMap.setMapStyle()` in Classic Views. +* **Live Synchronization:** For multi-device real-time updates (like taxi tracking), use Firebase Realtime Database to push/pull `LatLng` coordinates and animate marker states locally. +* **Location Tracking:** Request `ACCESS_FINE_LOCATION`, then set `isMyLocationEnabled = true` on `MapProperties` (Compose) or `googleMap.isMyLocationEnabled = true` (Classic Views). + +## 5. Execution Guidelines +1. Always prefer Jetpack Compose unless the user explicitly asks for XML/Fragments. +2. Never log or commit the raw API key. +3. Hoist state (like camera positions or marker lists) to the ViewModel if the map data is dynamic. From 717663ea2981747a721e5954e5451ccd12e90f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Tue, 24 Mar 2026 08:47:36 +0100 Subject: [PATCH 4/6] docs: bump maps-compose version to 8.2.2 and add release-please tags --- .gemini/skills/android-samples/SKILL.md | 4 ++-- llm-integration-prompt.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gemini/skills/android-samples/SKILL.md b/.gemini/skills/android-samples/SKILL.md index 1180f7e1f..65d24576b 100644 --- a/.gemini/skills/android-samples/SKILL.md +++ b/.gemini/skills/android-samples/SKILL.md @@ -15,9 +15,9 @@ Add the necessary dependencies to the app-level `build.gradle.kts` file based on ```kotlin dependencies { // Google Maps Compose library - implementation("com.google.maps.android:maps-compose:6.1.0") // Check for the latest version + implementation("com.google.maps.android:maps-compose:8.2.2") // x-release-please-version // Optional: Maps Compose Utilities (for clustering, etc.) - // implementation("com.google.maps.android:maps-compose-utils:6.1.0") + // implementation("com.google.maps.android:maps-compose-utils:8.2.2") // x-release-please-version } ``` diff --git a/llm-integration-prompt.md b/llm-integration-prompt.md index 1180f7e1f..65d24576b 100644 --- a/llm-integration-prompt.md +++ b/llm-integration-prompt.md @@ -15,9 +15,9 @@ Add the necessary dependencies to the app-level `build.gradle.kts` file based on ```kotlin dependencies { // Google Maps Compose library - implementation("com.google.maps.android:maps-compose:6.1.0") // Check for the latest version + implementation("com.google.maps.android:maps-compose:8.2.2") // x-release-please-version // Optional: Maps Compose Utilities (for clustering, etc.) - // implementation("com.google.maps.android:maps-compose-utils:6.1.0") + // implementation("com.google.maps.android:maps-compose-utils:8.2.2") // x-release-please-version } ``` From 8494e8b4a9c4b62a8750ae7fb674f9a603021072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Tue, 24 Mar 2026 08:48:19 +0100 Subject: [PATCH 5/6] chore: add AI prompt files to release-please-config.json --- release-please-config.json | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/release-please-config.json b/release-please-config.json index 351e25de0..0ea22d962 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,10 +1,12 @@ { - "packages": { - ".": { - "release-type": "simple", - "extra-files": [ - "gradle/libs.versions.toml" - ] - } + "packages": { + ".": { + "release-type": "simple", + "extra-files": [ + "gradle/libs.versions.toml", + ".gemini/skills/android-samples/SKILL.md", + "llm-integration-prompt.md" + ] } -} \ No newline at end of file + } +} From 18d61ff9844e70f669a87a40aeda1f519073e6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Tue, 24 Mar 2026 08:48:57 +0100 Subject: [PATCH 6/6] docs: bump play-services-maps to 20.0.0 in AI prompts --- .gemini/skills/android-samples/SKILL.md | 2 +- llm-integration-prompt.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gemini/skills/android-samples/SKILL.md b/.gemini/skills/android-samples/SKILL.md index 65d24576b..8a056281e 100644 --- a/.gemini/skills/android-samples/SKILL.md +++ b/.gemini/skills/android-samples/SKILL.md @@ -25,7 +25,7 @@ dependencies { ```kotlin dependencies { // Google Maps SDK for Android - implementation("com.google.android.gms:play-services-maps:19.0.0") // Check for the latest version + implementation("com.google.android.gms:play-services-maps:20.0.0") // Check for the latest version } ``` diff --git a/llm-integration-prompt.md b/llm-integration-prompt.md index 65d24576b..8a056281e 100644 --- a/llm-integration-prompt.md +++ b/llm-integration-prompt.md @@ -25,7 +25,7 @@ dependencies { ```kotlin dependencies { // Google Maps SDK for Android - implementation("com.google.android.gms:play-services-maps:19.0.0") // Check for the latest version + implementation("com.google.android.gms:play-services-maps:20.0.0") // Check for the latest version } ```