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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Mapbox Tutorial For Android: Getting Started
25 mins
- Getting Started
- Register For an Account with Mapbox
- Adding the Mapbox Dependency
- Working with MapBox
- Getting a Mapbox Access Token
- Configuring Mapbox to Show the Map
- Detect the User’s Current Location
- Displaying the Location on Map
- Customizing the Map Appearance
- Using the Mapbox Navigation API
- Direct the User Between Locations
- Where to Go from Here?
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.
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.
Once Gradle build loading is complete, you can build and run the app to see what you have inside the starter project.
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.
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.
Now you need to fill out the sign up form and click Get started.
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. :]
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.
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.
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.
@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.
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.
Make sure to select all the members and click OK.
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.
-
onExplanationNeeded
: Provide an explanation to the user for why you need the permission. -
onPermissionResult
: Check whether the permission was granted or not by the user, and how the app will handle that action. -
onLocationChanged
: Monitor user location changes. -
onConnected
: This is where the app is fully connected and is able to receive location updates. -
onMapReady
: The map is ready, and you can perform location related activities. -
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.
- 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.
- These variables are used for Mapbox, and are all related to getting the user’s location.
Next, you need to create 4 methods.
enableLocation
initializeLocationEngine
setCameraPosition
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.
-
enableLocation
: This is where you’ll enable location tracking to locate the user’s current location. -
initializeLocationEngine
&initializeLocationComponent
: These 2 functions are responsible for doing the actual work of locating the user’s location. -
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.
- First, you initialize the
map
variable, because you’ll be using it later. - Initialize
locationRequestBuilder
and pass the location request that the app will use. - Finally, you use
locationRequest
to build location request. Then pass it tosettingsClient
and attach two types of listeners:-
addOnSuccessListener
: When the request is successful, you’ll callenableLocation
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 isLocationSettingsStatusCodes.RESOLUTION_REQUIRED
, then the app should handle that exception by callingstartResolutionForResult
.
-
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. :]
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.