Google Maps (Java)
The previous lesson got RecipeBox a latitude/longitude for the user's current position. Now it's time to actually show that on a map. The Google Maps SDK for Android renders an interactive map inside RecipeBox's "Nearby Grocery Stores" screen, complete with pan, zoom, and markers for points of interest.
Adding the Dependency & API Key
The Maps SDK dependency goes in Gradle, but it also requires an API key obtained from the Google Cloud Console (enable the "Maps SDK for Android" API on a project there, then generate a key restricted to your app's package name and signing certificate). That key is not passed in Java code — it's declared once in the manifest.
// app/build.gradle
dependencies {
implementation 'com.google.android.gms:play-services-maps:19.0.0'
}
<!-- AndroidManifest.xml, inside <application> -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_MAPS_API_KEY" />
Adding a SupportMapFragment to the Layout
<androidx.fragment.app.FragmentContainerView
android:id="@+id/mapFragment"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Getting the GoogleMap Object Asynchronously
Rendering a map involves loading tiles and Play Services internals, which takes time — so RecipeBox can't just call findViewById() and start adding markers immediately. Instead, getMapAsync() hands back a ready-to-use GoogleMap once the map has actually finished initializing.
// NearbyStoresActivity.java
private GoogleMap googleMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nearby_stores);
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap map) {
googleMap = map;
showUserLocationAndStores();
}
});
}
Adding Markers
Using the current location from the Fused Location Provider lesson, RecipeBox drops one marker for the user and one for each nearby grocery store:
private void showUserLocationAndStores() {
LatLng userLatLng = new LatLng(currentLat, currentLng);
googleMap.addMarker(new MarkerOptions()
.position(userLatLng)
.title("You are here")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
for (GroceryStore store : nearbyStores) {
LatLng storeLatLng = new LatLng(store.getLat(), store.getLng());
googleMap.addMarker(new MarkerOptions()
.position(storeLatLng)
.title("Grocery Store")
.snippet(store.getName()));
}
moveCameraToUser(userLatLng);
}
Moving the Camera
private void moveCameraToUser(LatLng userLatLng) {
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(userLatLng, 15f);
googleMap.animateCamera(update);
}
Custom Map Styling
RecipeBox's own theme uses warm, muted colors, and the default Google Maps look can clash with that. The Maps SDK accepts a custom JSON map style (exported from the Google Maps Platform styling wizard) via googleMap.setMapStyle(new MapStyleOptions(jsonString)), letting water, roads, and labels be recolored to match the rest of the app. This is optional polish — the examples above work fine with the default style — but worth knowing about once RecipeBox's map screen needs to feel like part of the same app rather than a plain embedded Google Maps widget.
API key in manifest
from Google Cloud Console
SupportMapFragment
in the layout XML
getMapAsync()
onMapReady(GoogleMap)
Markers + camera
user + grocery stores