Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Apr 29, 2024

Work with maps

Install Amplify-MapLibre adapter

Add the following dependency to your build.gradle (Module :app) file and click "Sync Now" when prompted:

dependencies {
implementation 'com.amplifyframework:aws-auth-cognito:ANDROID_VERSION'
implementation 'com.amplifyframework:aws-geo-location:ANDROID_VERSION'
// Add this dependency to integrate MapLibre into your app
implementation 'com.amplifyframework:maplibre-adapter:ANDROID_VERSION'
}

Note: the minimum API level required for the UI components is 21.

Display a map

First, ensure you've provisioned an Amazon Location Service Map resource and configured your app using the instructions in either Configure maps or Use existing resources guide.

Select your user interface

There are two UI components available to render maps on an Android app, the MapLibreView and the AmplifyMapView. The MapLibreView is an extension of the standard Android MapLibre MapView that is integrated with the Amplify.Geo APIs, while the AmplifyMapView is a wrapper with built-in location search, map controls, markers and a few standard UX interactions.

MapLibreView vs AmplifyMapView

If the goal is to customize the UI, the MapLibreView provides a plain map that allows you to build and integrate your own controls and flow. If the goal is to use the map to search and select places, with a standard UI, then AmplifyMapView is a good choice.

Note that even though the extensibility of AmplifyMapView is limited, you have access to the wrapped MapLibreView through the mapView property (getMapView() on Java). So any API available to MapLibreView is also available on AmplifyMapView.

MapLibreView

The MapLibreView is an extension of the standard MapView provided by the MapLibre library. The implementation adds the Amplify.Geo integration behind the scenes to enable developers to focus on their UI instead of the library integration. That also means all MapLibre APIs are available and will work as expected. Check the official MapLibre SDK for Android documentation for the API reference and guides.

Add a map to your app

  1. Navigate to your app's src/main/res/layout directory in Android Studio

  2. Create a new layout named activity_main.xml, or use an existing layout of your choice, and add the following:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.amplifyframework.geo.maplibre.view.MapLibreView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

Initialize the MapLibreView

  1. Navigate to your app's activity (e.g. MainActivity)

  2. Add an import statement for MapLibreView at the top of your app's activity:

import com.amplifyframework.geo.maplibre.view.MapLibreView;
import com.amplifyframework.geo.maplibre.view.MapLibreView
  1. Declare the view instance variable at top-level of the activity:
private MapLibreView mapView;
private val mapView by lazy {
findViewById<MapLibreView>(R.id.mapView)
}
  1. Interact with the map in the Activity's onCreate:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Note: make sure you configure Amplify before calling setContentView
// See the Getting Started instructions
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
// now you can interact with the mapView, see examples below
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Note: make sure you configure Amplify before calling setContentView
// See the Getting Started instructions
setContentView(R.layout.activity_main)
// now you can interact with the mapView, see examples below
}

Interact with the map

The map needs to be loaded in order to interact with it. You can use either getMapAsync that is called when the map is ready or getStyle that is called when both the map and its style are ready. Some APIs, like the SymbolManager, require the style to also be loaded so you can draw markers and other symbols on the map, that's when getStyle comes in handy.

Update the map center

import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
mapView.getMapAsync(map -> {
LatLng seattle = new LatLng(47.6160281982247, -122.32642111977668);
map.setCameraPosition(
new CameraPosition.Builder()
.target(seattle)
.zoom(13.0)
.build()
);
});
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.geometry.LatLng
mapView.getMapAsync { map ->
val seattle = LatLng(47.6160281982247, -122.32642111977668)
map.cameraPosition = CameraPosition.Builder()
.target(seattle)
.zoom(13.0)
.build()
}

Updating cameraPosition moves the camera to the passed coordinates without any animation. If animation is needed, use map.animateCamera() instead. See the official reference for more details.

Add markers to your map

The MapLibre SDK for Android relies on the MapLibre Annotation Plugin in order to display markers on a map.

import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions;
mapView.getStyle((map, style) -> {
LatLng spaceNeedle = new LatLng(47.6205063, -122.3514661);
mapView.symbolManager.create(
new SymbolOptions()
.withIconImage("place")
.withLatLng(spaceNeedle)
);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(spaceNeedle, 16.0));
});
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions
mapView.getStyle { map, style ->
val spaceNeedle = LatLng(47.6205063, -122.3514661)
mapView.symbolManager.create(
SymbolOptions()
.withIconImage("place")
.withLatLng(spaceNeedle)
)
map.animateCamera(CameraUpdateFactory.newLatLngZoom(spaceNeedle, 16.0))
}

Notes:

  • The mapView.symbolManager is a built-in reference of SymbolManager from the MapLibre Annotation Plugin with some standard configuration.
  • If customized icons or render other types of shapes and layers are needed, an instance of SymbolManager can be created and used to manage the different types of custom use-cases.

MapLibreView configuration parameters

The MapLibreView has several configuration parameters that are not present in the official guides yet. For a complete list, refer to the source xml file.

Also, check the official MapView API reference for the available public API documentation.

AmplifyMapView

The AmplifyMapView provides a default search field, place markers, visualization modes (map or list) and map controls. It can be used to easily embed a place picker into any app. To use the search functionality of AmplifyMapView, provision a search index resource using the instructions in either Configure Location Search or Use existing Amazon Location Service resources.

Add a map to your app

  1. Navigate to your app's src/main/res/layout directory in Android Studio

  2. Create a new layout named activity_main.xml, or use an existing layout of your choice, and add the following:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.amplifyframework.geo.maplibre.view.AmplifyMapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

Initialize the AmplifyMapView

  1. Navigate to your app's activity (e.g. MainActivity)

  2. Add an import statement for AmplifyMapView at the top of your app's activity:

import com.amplifyframework.geo.maplibre.view.AmplifyMapView;
import com.amplifyframework.geo.maplibre.view.AmplifyMapView
  1. Declare the view instance variable at top-level of the activity:
private AmplifyMapView amplifyMapView;
private val amplifyMapView by lazy {
findViewById<AmplifyMapView>(R.id.mapView)
}
  1. Interact with the map in the Activity's onCreate:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Note: make sure you configure Amplify before calling setContentView
// See the Getting Started instructions
setContentView(R.layout.activity_main);
amplifyMapView = findViewById(R.id.mapView);
// now you can interact with the mapView, see examples below
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Note: make sure you configure Amplify before calling setContentView
// See the Getting Started instructions
setContentView(R.layout.activity_main)
// now you can interact with the mapView, see examples below
}

Place select

The main API provided by AmplifyMapView is an event listener that is called when a place is selected on the map, either by clicking on the mark or the item on the list.

import android.util.Log;
amplifyMapView.setOnPlaceSelectListener((place, symbol) -> {
// place is an instance of AmazonLocationPlace
// symbol is an instance of Symbol from MapLibre
Log.i("MyAmplifyApp", "The selected place is " + place.getLabel());
Log.i("MyAmplifyApp", "It is located at " + place.getCoordinates());
});
import android.util.Log
amplifyMapView.onPlaceSelect { place, symbol ->
// place is an instance of AmazonLocationPlace
// symbol is an instance of Symbol from MapLibre
Log.i("MyAmplifyApp", "The selected place is ${place.label}")
Log.i("MyAmplifyApp", "It is located at ${place.coordinates}")
}

AmplifyMapView configuration parameters

The view can be initialized with the following configuration parameters:

PropertyTypeDescriptionDefault
map:map_centerLatitudeFloatThe initial center latitude0.0
map:map_centerLongitudeFloatThe initial center longitude0.0
map:map_minZoomLevelIntegerThe minimum zoom level (min is 0)3
map:map_maxZoomLevelIntegerThe maximum zoom level (max is 22)18
map:map_showCompassIndicatorBooleanWhether the compass should be displayed or nottrue
map:map_showZoomControlsBooleanWhether the zoom controls should be displayed or notfalse
map:map_zoomLevelIntegerThe initial zoom level (between 0 and 22)14

Example:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.amplifyframework.geo.maplibre.view.AmplifyMapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:map_zoomLevel="12"
map:map_centerLatitude="47.6160281982247"
map:map_centerLongitude="-122.32642111977668"
map:map_showCompassIndicator="true"
map:map_showZoomControls="true"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

Display different map styles

The getAvailableMaps API fetches information for all maps that are available to be displayed.

This is useful if you would like to give your users a variety of map styles to choose from.

Amplify.Geo.getAvailableMaps(
result -> {
for (final MapStyle style : result) {
Log.i("MyAmplifyApp", style.toString());
}
},
error -> Log.e("MyAmplifyApp", "Failed to get available maps.", error)
);
Amplify.Geo.getAvailableMaps(
{
for (mapStyle in it) {
Log.i("MyAmplifyApp", mapStyle.toString())
}
},
{ Log.e("MyAmplifyApp", "Failed to get available maps.", it) }
)
try {
val result = Amplify.Geo.getAvailableMaps()
for (mapStyle in result) {
Log.i("MyAmplifyApp", mapStyle.toString())
}
} catch (error: GeoException) {
Log.e("MyAmplifyApp", "Failed to get available maps.", error)
}
RxAmplify.Geo.getAvailableMaps().subscribe(
result -> {
for (final MapStyle style : result) {
Log.i("MyAmplifyApp", style.toString());
}
},
error -> Log.e("MyAmplifyApp", "Failed to get available maps.", error)
);

You can set a different style to your map using setStyle method from the adapter:

With MapLibreView:

// where mapStyle is a reference to the selected style from Amplify.Geo.getAvailableMaps
mapView.setStyle(mapStyle, style -> {
Log.i("MyAmplifyApp", "Finished loading " + mapStyle.getStyle());
});

With AmplifyMapView:

// where mapStyle is a reference to the selected style from Amplify.Geo.getAvailableMaps
amplifyMapView.getMapView().setStyle(mapStyle, style -> {
Log.i("MyAmplifyApp", "Finished loading " + mapStyle.getStyle());
});

With MapLibreView:

// where mapStyle is a reference to the selected style from Amplify.Geo.getAvailableMaps
mapView.setStyle(mapStyle) { style ->
Log.i("MyAmplifyApp", "Finished loading ${mapStyle.style}.")
}

With AmplifyMapView:

// where mapStyle is a reference to the selected style from Amplify.Geo.getAvailableMaps
amplifyMapView.mapView.setStyle(mapStyle) { style ->
Log.i("MyAmplifyApp", "Finished loading ${mapStyle.style}.")
}