Mapbox Tutorial For Android: Getting Started

In this tutorial, you’ll learn everything there is to setting up a simple GPS navigation app, using MapBox, by building an app called Where2Go! By Abdalla Ali.

3.8 (11) · 2 Reviews

Download materials
Save for later
Share

Nowadays, many apps have a location function. You use them all the time, whether you’re ordering food delivery, booking a cab, or even doing laundry. Have you ever thought about building a location app of your own? You may think it’s too complicated or may take too much time to build something close to some of the impressive apps with location features that have been built for Android. Well not anymore! Thanks to the Mapbox SDK, you can build a cool Android app with location features. That’s exactly what you’ll do in this tutorial.

Using the Mapbox Android SDK, you’ll build an app using Mapbox Navigation called Where2Go. In this tutorial, you’ll learn how to:

  • Add the Mapbox library to project.
  • Show the user’s current location on the map.
  • Add a marker on the map and navigate turn by turn from the current location to the point where the marker is on the map.

If you want to learn a bit more about Mapbox, you can read more about it at the official website.

Prerequisites: This tutorial assumes that you understand the basics of Android development with Kotlin. If you’re new to Android development, please go through Beginning Android Development with Kotlin to understand the basics. If you’re new to Kotlin, check out this Introduction to Kotlin tutorial.

Getting Started

Before you learn about Mapbox, you have to download the starter and final projects by using the Download Materials link at the top or bottom of this tutorial. Launch Android Studio 3.3 or later, select the Open an existing Android Studio project option, then navigate to and select the starter project folder.

Open Project

Once Gradle build loading is complete, you can build and run the app to see what you have inside the starter project.

Starter Project Running

The first thing you’ll see after running the app is an empty screen and a floating action button. Not too moving. But in a bit, when you implement the navigation using Mapbox, you’ll be able to navigate anywhere you want! :]

Register For an Account with Mapbox

The first thing that you need to do before using Mapbox SDK is to register for an account. Then, once you successfully register, you’ll get an access token. This token is the key that you need to be able to use the Mapbox SDK.

Once you arrive at the Mapbox website, click on the Sign in button as pointed out by the red arrow.

Sign Up for Mapbox

You’ll be directed to another page which has a sign in form. You need to click on Sign up for Mapbox as shown in the red box.

Sign up for Mapbox

Now you need to fill out the sign up form and click Get started.

Mapbox Sign in form

Don’t worry, the registration is free. You can use Mapbox SDK to build a small application. Once your app gets popular, they’ll start to charge you. :]

Pay as You Go

Adding the Mapbox Dependency

First, open the build.gradle (Module:app) file and add compileOptions within android:

compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
}

Second, add the Mapbox and Google Play Service Location library dependencies within dependencies:

implementation 'com.mapbox.mapboxsdk:mapbox-android-navigation-ui:0.26.0'
implementation ('com.mapbox.mapboxsdk:mapbox-android-sdk:6.8.1') {
  exclude group: 'group_name', module: 'module_name'
}
implementation 'com.google.android.gms:play-services-location:16.0.0'

Finally, open the build.gradle (Project) file, and add following lines inside the allprojects right under the jcenter().

mavenCentral()
maven { url 'https://mapbox.bintray.com/mapbox' }

Click Sync now to sync the project, which allows you to use the Mapbox library.

Sync Mapbox Android Project

Working with MapBox

In this section, you’ll learn how to get a MapBox access token, get the user’s current location, and show their location on the map.

Getting a Mapbox Access Token

Once you’ve successfully registered for an account with Mapbox, click your profile picture and choose Account.

Mapbox Choose Account

Inside the Account page is where you’ll create a brand new access token, or you can use the default public token, as you’ll see in this tutorial.

Configuring Mapbox to Show the Map

Open the activity_main.xml file. First, you need to add xmlns:mapbox inside RelativeLayout.

xmlns:mapbox="http://schemas.android.com/apk/res-auto"

Add that tag so you can access Mapbox attributes.

Next, add the following code to show the Mapbox map.

<com.mapbox.mapboxsdk.maps.MapView
  android:id="@+id/mapbox"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  mapbox:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"/>

Mapbox has different StyleUrl attributes, which you can use to change the overall map appearance. The one that you’ll use is mapbox_style_mapbox_streets. This style is a plain styling of roads and transit networks.

Now open the AndroidManifest.xml file and add the following permissions.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

Add the android.permission.ACCESS_FINE_LOCATION permission so that Mapbox SDK can detect your location and show it on the map. As for the android.permission.FOREGROUND_SERVICE permission, this is needed when you want to start the turn by turn navigation.

Next, open the MainActivity.kt file, add the following code before the call to the setContentView function:

Mapbox.getInstance(this, "Your Mapbox access token")

Bear in mind, you need to replace the string text with the actual Mapbox access token.

Since you’ll be using Kotlin Android Extensions, you can easily reference views by their id attributes defined in the XML. To initialize the mapbox view, add this code below the setContentView line:

mapbox.onCreate(savedInstanceState)

Handling the Mapbox lifecycle is really important, so add the following code below the onCreate function to complete the initialization and cleanup process:

@SuppressWarnings("MissingPermission")
override fun onStart() {
  super.onStart()
  mapbox.onStart()
}

override fun onResume() {
  super.onResume()
  mapbox.onResume()
}

override fun onPause() {
  super.onPause()
  mapbox.onPause()
}

override fun onStop() {
  super.onStop()
  mapbox.onStop()
}

override fun onDestroy() {
  super.onDestroy()
  mapbox.onDestroy()
}

override fun onLowMemory() {
  super.onLowMemory()
  mapbox.onLowMemory()
}

override fun onSaveInstanceState(outState: Bundle?) {
  super.onSaveInstanceState(outState)
    if (outState != null) {
      mapbox.onSaveInstanceState(outState)
    }
}

Mapbox has its own lifecycle methods for managing an Android openGL lifecycle. You must call those methods directly from the containing activity.

Note: You need to add @SuppressWarnings("MissingPermission") above onStart and the other methods, because these methods require you to implement permission handling. However, you don’t need that here because Mapbox handles it for you.

Build and run the app to see the result.

Mapbox Android App Running

Detect the User’s Current Location

Open the MainActivity.kt file and change the class declaration to make it implement the following interfaces.

class MainActivity : AppCompatActivity(), PermissionsListener, LocationEngineListener, OnMapReadyCallback

You need to use PermissionsListener to handle the location permission for devices running Android Marshmallow and later, while you need to use LocationEngineListener to locate the user’s location. Finally, you need OnMapReadyCallback, because this where you’ll include PermissionsListener and LocationEngineListener to begin locating where the user is and show that location on the map.

Android Studio will now complain with errors telling you to add the required imports. Hover your mouse over the error and choose Implement members.

Implement android member functions for Mapbox project

Make sure to select all the members and click OK.

Select all members

Android Studio will automatically include the following code inside MainActivity.kt.

//1
override fun onExplanationNeeded(permissionsToExplain: MutableList<String>?) {
        
}
//2
override fun onPermissionResult(granted: Boolean) {
        
}
//3
override fun onLocationChanged(location: Location?) {
        
}
//4
@SuppressWarnings("MissingPermission")
override fun onConnected() {
        
}
//5
override fun onMapReady(mapboxMap: MapboxMap?) {
        
}
//6
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {

}

Let’s go through this code together.

  1. onExplanationNeeded: Provide an explanation to the user for why you need the permission.
  2. onPermissionResult: Check whether the permission was granted or not by the user, and how the app will handle that action.
  3. onLocationChanged: Monitor user location changes.
  4. onConnected: This is where the app is fully connected and is able to receive location updates.
  5. onMapReady: The map is ready, and you can perform location related activities.
  6. onRequestPermissionsResult: Override this extra method, because it’s the one that handles all the permissions related work.

Now let’s add the required variables. You can add them at the top, before the onCreate function.

//1
val REQUEST_CHECK_SETTINGS = 1
var settingsClient: SettingsClient? = null

//2
lateinit var map: MapboxMap
lateinit var permissionManager: PermissionsManager
var originLocation: Location? = null

var locationEngine: LocationEngine? = null
var locationComponent: LocationComponent? = null

Let’s go through the code above and get to know those variables.

  1. You’ll use SettingsClient API to show an AlertDialog box where you’ll ask the user to turn on GPS to locate the user’s location.
  2. These variables are used for Mapbox, and are all related to getting the user’s location.

Next, you need to create 4 methods.

  1. enableLocation
  2. initializeLocationEngine
  3. setCameraPosition
  4. initializeLocationComponent
//1
fun enableLocation() {
        
}
//2
@SuppressWarnings("MissingPermission")
fun initializeLocationEngine() {
        

}

@SuppressWarnings("MissingPermission")
fun initializeLocationComponent() {
        
}

//3
fun setCameraPosition(location: Location) {

}

Let’s go through the code above.

  1. enableLocation: This is where you’ll enable location tracking to locate the user’s current location.
  2. initializeLocationEngine & initializeLocationComponent: These 2 functions are responsible for doing the actual work of locating the user’s location.
  3. setCameraPosition: This function handles zooming in on the user’s location in the map.

Add the following code inside the onCreate function.

mapbox.getMapAsync(this)

This is a callback which will be triggered when the Mapbox map is ready.

Next you need to initialize SettingsClient API.

settingsClient = LocationServices.getSettingsClient(this)

Now you need to add the following code inside onMapReady.

//1
map = mapboxMap ?: return
//2
val locationRequestBuilder = LocationSettingsRequest.Builder().addLocationRequest(LocationRequest()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY))
//3
val locationRequest = locationRequestBuilder?.build()

settingsClient?.checkLocationSettings(locationRequest)?.run {
  addOnSuccessListener {
    enableLocation()
  }

  addOnFailureListener {
    val statusCode = (it as ApiException).statusCode

    if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
      val resolvableException = it as? ResolvableApiException
      resolvableException?.startResolutionForResult(this@MainActivity, REQUEST_CHECK_SETTINGS)
    }
  }
 }

The code above is all related to SettingsClient API, so let’s go through it step by step.

  1. First, you initialize the map variable, because you’ll be using it later.
  2. Initialize locationRequestBuilder and pass the location request that the app will use.
  3. Finally, you use locationRequest to build location request. Then pass it to settingsClient and attach two types of listeners:
    • addOnSuccessListener: When the request is successful, you’ll call enableLocation to initiate location tracking.
    • addOnFailureListener: When the request fails, check to see the reason why by looking at the exception status code. If the exception is LocationSettingsStatusCodes.RESOLUTION_REQUIRED, then the app should handle that exception by calling startResolutionForResult.

Next, you need to handle the exception result by overriding onActivityResult. Add the following code below onCreate.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  super.onActivityResult(requestCode, resultCode, data)

  if (requestCode == REQUEST_CHECK_SETTINGS) {
    if (resultCode == Activity.RESULT_OK) {
      enableLocation()
    } else if (resultCode == Activity.RESULT_CANCELED) {
      finish()
    }
  }
}

First, check if the requestCode is correct and if resultCode is equal to Activity.RESULT_OK. Then, you call the enableLocation method to initiate location tracking.

If resultCode is equal to Activity.RESULT_CANCELED, the user has cancelled the request and you call finish() to close the whole app.

The reason you call finish() is because the app needs the user to turn ON GPS. If the user fails to do so, the app won’t work, so it’s best to close the app.

Now it’s time to see some progress, so build and run the app. :]

mapbox android project prompting for GPS permission

If GPS is not turned ON in your device, the app will prompt you with the AlertDialog telling you to turn it ON. Once you tap on OK, the device GPS will turn ON. Otherwise if you tap on the NO, THANKS button, the app will close.

If GPS in your device is ON, the app will not prompt you with AlertDialog.