Tutorials
beginner
Java

First steps with the Mapbox Maps SDK for Android

Prerequisite
Completion of the Mapbox Maps SDK for Android installation process and familiarity with Android Studio and Java.

The Mapbox Maps SDK for Android is our vector maps library for Android. This guide will walk you through installing the Mapbox Maps SDK for Android with Android Studio, loading a map, changing the map's style, and placing a pin on it.

map with marker on an Android device

Getting started

Here's what you'll need to get started:

  • A Mapbox account and access token. Sign up for an account at mapbox.com/signup. You can find your access tokens on your Account page.
  • Android Studio. You can download Android Studio for free from Google. Before you can install the Mapbox Maps SDK for Android, you need to download Android Studio and create a project with an empty activity.
  • An Android device (physical or virtual). You will need either a physical Android device or an emulated Android device to preview the store finder.
  • Google Play Developer Account (optional). If you want to publish your app to Google Play, you'll need a Google Play developer account. Without one, you'll still be able to preview the app on an Android Virtual Device (AVD) or install the app on a physical device.

Create an Android Studio project

Familiarize yourself with Android Studio. You'll need to create a new project with an empty activity. Use the following options when creating a new Android Studio project:

  • Under Select the form factors your app will run on, check "Phone and Tablet."
  • For minimum SDK, select API 14: Android 4.0.0 (IceCreamSandwich). (This is the lowest API level supported by Mapbox Maps SDK for Android.)
  • Click Next to advance to the activity selection screen.
  • Select Empty Activity and click Next.
  • Accept the default Activity Name and Layout Name and click Finish.

If you need help installing Android Studio or creating your first project, see the Android Studio documentation.

Set up a virtual device

With Android Studio, you can set up virtual Android devices on your computer to test your app while you develop. To set up a virtual device, click on the Android Virtual Device (AVD) Manager icon icon for AVD in the Android Studio interface, then click the Create Virtual Device button. You can also get to the manager via Tools > Android > AVD Manager in the toolbar. From the Phones category, select Nexus 5X and click Next. Select the release you would like to test against (this guide uses API level 26).

Learn more about setting up an AVD in the Android Studio documentation.

Install the Mapbox Maps SDK for Android

Before you begin building your app, install the Mapbox Maps SDK for Android by following our installation guide. The installation guide assumes that you have already downloaded Android Studio and created a new project. You'll make changes to four different files within your project to install the Mapbox Maps SDK for Android. The four files you'll be working with include:

  • build.gradle (Module:App): Android Studio uses a toolkit called Gradle to compile resources and source code into an APK. This plain text file is used to configure the build and list dependencies, including the Mapbox Maps SDK for Android.
  • AndroidManifest.xml: This is where you'll describe components of the application, including Mapbox-related permissions.
  • MainActivity.java: This is a Java file where you'll specify Mapbox classes and methods.
  • activity_main.xml: This is where you'll set the properties for your MapView and add a marker.

Once you've completed all the steps in the installation guide, the four files below should include the following:

build.gradle (Module:App)
// in addition to the rest of your build.gradle contents
// you should include the following repository and dependency

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:7.4.0'
}
Manifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="0dp"
android:layout_height="0dp"
mapbox:layout_constraintBottom_toBottomOf="parent"
mapbox:layout_constraintEnd_toEndOf="parent"
mapbox:layout_constraintStart_toStartOf="parent"
mapbox:layout_constraintTop_toTopOf="parent"
mapbox:mapbox_cameraTargetLat="41.885"
mapbox:mapbox_cameraTargetLng="-87.679"
mapbox:mapbox_cameraTilt="60"
mapbox:mapbox_cameraZoom="12" />
</android.support.constraint.ConstraintLayout>
MainActivity.java
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
public class MainActivity extends AppCompatActivity {
private MapView mapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Add the marker image to map
style.addImage("marker-icon-id",
BitmapFactory.decodeResource(
MainActivity.this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("source-id", Feature.fromGeometry(
Point.fromLngLat(-87.679, 41.885)));
style.addSource(geoJsonSource);
SymbolLayer symbolLayer = new SymbolLayer("layer-id", "source-id");
symbolLayer.withProperties(
PropertyFactory.iconImage("marker-icon-id")
);
style.addLayer(symbolLayer);
}
});
}
});
}
// Add the mapView's own lifecycle methods to the activity's lifecycle methods
@Override
public void onStart() {
super.onStart();
mapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
mapView.onStop();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
help
Troubleshooting Android Studio errors

If you run into other Android Studio errors unrelated to Mapbox, we recommend referring to the Android Studio documentation or searching for error messages on StackOverflow.

Configure your MapView

You can configure many of your map's characteristics, including starting camera position or the compass' location on the screen, in your activity's layout file. Replace the code you added to the activity_main.xml file in the installation flow with the following to recenter the map on Chicago, change the pitch, and increase the zoom level:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="0dp"
android:layout_height="0dp"
mapbox:layout_constraintBottom_toBottomOf="parent"
mapbox:layout_constraintEnd_toEndOf="parent"
mapbox:layout_constraintStart_toStartOf="parent"
mapbox:layout_constraintTop_toTopOf="parent"
mapbox:mapbox_cameraTargetLat="41.885"
mapbox:mapbox_cameraTargetLng="-87.679"
mapbox:mapbox_cameraTilt="60"
mapbox:mapbox_cameraZoom="12" />
</android.support.constraint.ConstraintLayout>

The Mapbox Maps SDK for Android comes bundled with a handful of map styles. You can find a list of the current bundled styles with constants found in the Mapbox SDK's Style class. In this example, you'll use the Mapbox Light style.

You must the map style programmatically using the MapboxMap class' setStyle(); method. Run mapboxMap.setStyle() within onMapReady(). The second parameter to pass through setStyle() is the style loaded callback which is when the map is ready to receive map-related code:

mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
      @Override
      public void onStyleLoaded(@NonNull Style style) {
        // Map is set up and the style has loaded. Now you can add data or make other map adjustments
      }
    });
    }
});

You can also use mapboxMap.setStyleUrl() outside of the onMapReady() method:

mapView.getMapAsync(new OnMapReadyCallback() {
  @Override
  public void onMapReady(MapboxMap mapboxMap) {
      MainActivity.this.mapboxMap = mapboxMap;
  }
});

The MapboxMap object near the top of your MainActivity is equal to the MapboxMap object that's returned once the map in your XML layout is ready. Now you can run mapboxMap.setStyle() anywhere else in your MainActivity's code.

help
Creating your own styles

You can create custom styles with Mapbox Studio and then add them to your app. To programmatically add one of your custom styles to your mapboxMap, head to your styles page, copy your style's style URL, and then add it to your mapboxMap object with setStyleUrl();:

mapboxMap.setStyle(new Style.Builder().fromUrl("mapbox://styles/your-mapbox-username/your-style-ID"), new Style.OnStyleLoaded() {
  @Override
  public void onStyleLoaded(@NonNull Style style) {

  }
});

See the Mapbox Maps SDK for Android documentation to view all the XML attributes that you can set for a MapView. Customize your map to your heart's content!

Import classes

When you've finished entering the above code, you will likely see some red warning text from Android Studio. This is because you haven't yet imported some of the classes that you're referencing in MainActivity.java.

You can automatically import these classes by pressing Alt+Enter (Option+Return on a Mac computer). Alternatively, you can manually add the following to the top of your MainActivity.java file, anywhere above the line that reads public class MainActivity extends AppCompatActivity:

MainActivity.java
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
public class MainActivity extends AppCompatActivity {
private MapView mapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Add the marker image to map
style.addImage("marker-icon-id",
BitmapFactory.decodeResource(
MainActivity.this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("source-id", Feature.fromGeometry(
Point.fromLngLat(-87.679, 41.885)));
style.addSource(geoJsonSource);
SymbolLayer symbolLayer = new SymbolLayer("layer-id", "source-id");
symbolLayer.withProperties(
PropertyFactory.iconImage("marker-icon-id")
);
style.addLayer(symbolLayer);
}
});
}
});
}
// Add the mapView's own lifecycle methods to the activity's lifecycle methods
@Override
public void onStart() {
super.onStart();
mapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
mapView.onStop();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}

Click the Run 'app' button icon for running the app in Android Studio(or Control+R on a Mac computer) to build your app.

Android Studio will take a few seconds to build, and if it finishes without errors, you'll be able to test drive it in the emulated Android device that you set up earlier. Regardless of the approach you take, the result should be the same — you should see the initial map style replaced with the Mapbox Light style.

screenshot of a virtual Android device displaying a map using the Mapbox Light style

Add a marker

Next, you'll add a marker to your map. In your MainActivity.java file, add the following code immediately after mapView.onCreate(savedInstanceState);, but still within public void onStyleLoaded(@NonNull Style style) { ...});. This will wait until the map has loaded, and then add a single marker displayed at the specified coordinate.

Once the style has been to set to Mapbox Light, you will add an icon image to the map and then use that icon when you add a SymbolLayer to the map.

MainActivity.java
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
public class MainActivity extends AppCompatActivity {
private MapView mapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Add the marker image to map
style.addImage("marker-icon-id",
BitmapFactory.decodeResource(
MainActivity.this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("source-id", Feature.fromGeometry(
Point.fromLngLat(-87.679, 41.885)));
style.addSource(geoJsonSource);
SymbolLayer symbolLayer = new SymbolLayer("layer-id", "source-id");
symbolLayer.withProperties(
PropertyFactory.iconImage("marker-icon-id")
);
style.addLayer(symbolLayer);
}
});
}
});
}
// Add the mapView's own lifecycle methods to the activity's lifecycle methods
@Override
public void onStart() {
super.onStart();
mapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
mapView.onStop();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}

Rerun your application and a red marker should appear.

map with marker on an Android device

Final product

MainActivity.java
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
public class MainActivity extends AppCompatActivity {
private MapView mapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Add the marker image to map
style.addImage("marker-icon-id",
BitmapFactory.decodeResource(
MainActivity.this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("source-id", Feature.fromGeometry(
Point.fromLngLat(-87.679, 41.885)));
style.addSource(geoJsonSource);
SymbolLayer symbolLayer = new SymbolLayer("layer-id", "source-id");
symbolLayer.withProperties(
PropertyFactory.iconImage("marker-icon-id")
);
style.addLayer(symbolLayer);
}
});
}
});
}
// Add the mapView's own lifecycle methods to the activity's lifecycle methods
@Override
public void onStart() {
super.onStart();
mapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
mapView.onStop();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}

Next steps

You built a small Android app with Mapbox! You can now create an Android Studio project, install the Mapbox Maps SDK for Android, and change the map style. Here are a few resources to keep you up-to-date with Mapbox:

You can also download and explore our Android demo app to see all the ways that you can use Mapbox in your Android project.