Google Map Integration in Flutter: Complete Tutorial (2026)
Last Updated: | Author: Deep Singh
Maps are one of the most useful features you can add to a mobile app. Whether you're building a store locator, a delivery tracker, or a travel guide, embedding Google Maps is often the fastest way to give users location context.
In this tutorial, you'll learn how to integrate Google Maps into a Flutter app from scratch. We'll cover getting an API key from the Google Cloud Console, wiring it into your Android project, and displaying a map with markers and switchable map types.
Before You Start
Make sure you have the following ready:
- Flutter SDK installed (use the latest stable version for best compatibility)
- Android Studio or VS Code with the Flutter plugin
- A Google account for the Google Cloud Console
- A physical device or emulator with Google Play Services installed
- Your
minSdkVersionset to at least 21 inandroid/app/build.gradle
Important: Google Maps will not work on an emulator without Google Play Services. If you're using an Android emulator, make sure to pick an image that includes the Play Store.
Adding the Plugin
Add the google_maps_flutter plugin to your project. The easiest way is to run this command:
flutter pub add google_maps_flutter
Or add it manually to your pubspec.yaml file under dependencies:
dependencies:
google_maps_flutter: ^2.9.0
Then run flutter pub get.
Note on plugin versions: The version ^2.0.3 used in older tutorials still works, but newer versions include bug fixes and support for the latest Flutter and platform SDKs. Use the latest stable version unless you have a specific reason to pin an older one.
Getting a Google Maps API Key
Google Maps requires an API key. Without one, the map will render as a blank grey tile. Here's how to get one:
Step 1: Open the Google Cloud Console
Go to the Google Cloud Console. You can either create a new project or use an existing one. For this tutorial, I created a new project called Google Map Integration.
Step 2: Select Your Project
After creating the project, select it from the project dropdown at the top of the console.
Step 3: Enable APIs and Services
Navigate to APIs & Services and click Enable APIs and Services.
Step 4: Enable the Maps SDK
Search for Maps SDK for Android (or iOS if you're targeting iOS). Select it and click Enable.
Step 5: Create Credentials
Go to the Credentials tab and click Create Credentials.
Step 6: Choose API Key
Select API key from the list of credential types.
Step 7: Copy Your API Key
Your API key will be generated. Copy it — you'll need it in the next step.
Adding the API Key to AndroidManifest.xml
Open android/app/src/main/AndroidManifest.xml and add a <meta-data> tag inside the <application> element. Replace YOUR_API_KEY_HERE with the key you copied:
<application
android:label="your_app_name"
android:icon="@mipmap/ic_launcher">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY_HERE" />
<activity android:name=".MainActivity">
...
</activity>
</application>
Security note: Storing your API key directly in the manifest is fine for development, but for production you should restrict the key. In the Google Cloud Console, you can limit the key to your app's package name and SHA-1 fingerprint so it can't be misused if it leaks.
The Full Code
Here's a complete working example. It displays a map centered on New Delhi, adds a marker, and includes buttons to switch between normal, satellite, terrain, and hybrid map types.
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() {
runApp(const MaterialApp(
home: MyGoogleMap(),
title: 'Google Map Tutorial',
));
}
class MyGoogleMap extends StatefulWidget {
const MyGoogleMap({super.key});
@override
State<MyGoogleMap> createState() => _MyGoogleMapState();
}
class _MyGoogleMapState extends State<MyGoogleMap> {
MapType _mapType = MapType.normal;
final Set<Marker> _markers = {};
static const LatLng _initialPosition = LatLng(28.7041, 77.1025);
void _onMapCreated(GoogleMapController controller) {
setState(() {
_markers.add(
Marker(
markerId: const MarkerId('first_marker'),
position: _initialPosition,
infoWindow: const InfoWindow(
title: 'Institute',
snippet: 'Education Center',
),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Google Map Tutorial'),
),
body: Stack(
children: [
GoogleMap(
initialCameraPosition: const CameraPosition(
target: _initialPosition,
zoom: 18,
),
mapType: _mapType,
markers: _markers,
onMapCreated: _onMapCreated,
onTap: (LatLng tappedPoint) {
debugPrint(
'Tapped: ${tappedPoint.latitude}, ${tappedPoint.longitude}',
);
},
),
Align(
alignment: Alignment.topRight,
child: Card(
margin: const EdgeInsets.all(8),
elevation: 10,
color: Colors.black45,
child: ButtonBar(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
tooltip: 'Normal',
onPressed: () =>
setState(() => _mapType = MapType.normal),
icon: const Icon(Icons.map, color: Colors.white),
),
IconButton(
tooltip: 'Satellite',
onPressed: () =>
setState(() => _mapType = MapType.satellite),
icon: const Icon(Icons.satellite_alt, color: Colors.white),
),
IconButton(
tooltip: 'Terrain',
onPressed: () =>
setState(() => _mapType = MapType.terrain),
icon: const Icon(Icons.terrain, color: Colors.white),
),
IconButton(
tooltip: 'Hybrid',
onPressed: () =>
setState(() => _mapType = MapType.hybrid),
icon: const Icon(Icons.layers, color: Colors.white),
),
],
),
),
),
],
),
);
}
}
How the Code Works
Let's walk through the key parts of the code:
1. Setting the Initial Camera Position
The initialCameraPosition parameter tells the map where to center when it first loads. It takes a CameraPosition with a target (latitude and longitude) and a zoom level. Higher zoom values mean a closer view.
2. Adding a Marker
Markers are stored in a Set<Marker>. We add one inside onMapCreated, which is called once the map is ready. Each marker needs a unique MarkerId, a position, and optionally an InfoWindow with a title and snippet that appears when the user taps it.
3. Handling Map Taps
The onTap callback receives a LatLng representing where the user tapped. We just log it here, but you could use it to place a new marker, fetch nearby places, or trigger any other action.
4. Switching Map Types
The buttons in the top-right corner let the user switch between normal, satellite, terrain, and hybrid views. Each button calls setState() to update the _mapType variable, and the map rebuilds with the new style.
Wrapping Up
You now have a working Google Map inside your Flutter app, complete with markers and switchable map types. From here, you can build on this foundation by adding live location tracking, custom marker icons, polylines between points, or place search.
A few things to keep in mind:
- Restrict your API key. Don't ship an unrestricted key to production. Limit it to your app's package name and SHA-1 fingerprint in the Google Cloud Console.
- Watch your billing. Google Maps API calls are billed after the free tier. Check the pricing page to understand your limits.
- Test on a real device. Some emulators don't have Google Play Services, which the Maps SDK depends on.
No comments:
Post a Comment