Skip to Content

About: Robert Avalos

Robert Avalos

Recent Posts by Robert Avalos

A quick guide to using Mapbox in Android apps

Introduction

Google maps has been one of the developers’ preferred choices when thinking of adding maps to their applications but as prices increased and a reduction of free API calls took place, developers had to start looking for an alternative that let them work with a cheaper map tool and that’s when Mapbox started to gain popularity.

Mapbox is one of the largest platforms that provide designed maps for websites and mobile applications; according to its documentation, it offers features such as maps, search, and navigation as well as better map customization compared to other options such as LeafLet or OpenLayers (If you want to know how many maps platforms exists you can visits this link). It’s powered by OpenStreetMap, a massive collaborative project to create free, editable maps.

 

What you should already know

This tutorial assumes a basic knowledge of:

  • Kotlin
  • MVVM (Model-View-ViewModel)
  • Android coroutines
  • Android Studio

 

What you’ll learn

In this tutorial, we’ll cover the most common implementations of Mapbox in our applications:

  • Ask for location permissions.
  • Get users’ addresses by their current location (geocoder).
  • Get both latitude and longitude and set a pin on the map by typing an address on a certain radius (reverse geocoder).

 

Overview

You’ll be working on an application that allows you to keep track of the user’s current location by setting a pin over the map. Also, you can search for addresses by using the Places API.

 

Getting started

Download the base code here or you can clone the repository on Github instead.

Note: Since the project you’ll download contains the main view file already made, we’ll just focus on adding the functionality to our application.

 

Dependencies

This project already has added dependencies that we need to work through this tutorial; if you downloaded or cloned the project the build.gradle file has to look like this:

Mapbox dependencies

These dependencies are needed to start working with Mapbox SDK and build our application using view models, remember that we are going to use MVVM as our design pattern.

 

Step 1: Getting Mapbox Access Token

Before coding, we have to get a Mapbox access token; this token allows us to use the SDK on our Android application. According to the official Mapbox documentation regarding access token:

“To use any of Mapbox’s tools, APIs, or SDKs, you’ll need a Mapbox access token. Mapbox uses access tokens to associate API requests with your account. You can find your access tokens, create new ones, or delete existing ones on your Access Tokens page or programmatically using the Mapbox Tokens API.”

To get an access token you need to sign up to your Mapbox account or create a new one if you don’t have it yet. Once you are logged in, go to the dashboard page and copy the default token.

For this tutorial, it’s ok if you use the default token.

Mapbox access tokens

Copy the access token to your clipboard and go to your build.gradle file inside your app folder, here we’ll create a custom field at the end of the defaultConfig block; in this way, you can use this variable in the whole project.

 

Mapbox Access Tokens. buildConfigField

 

Step 2 – Ask for locations permissions

Open your AndroidManifest.xml and add the ACCESS_FINE_LOCATION permission. We’ll use this permission to access the user’s current location.

 

 

Since Android 6 Marshmallow is required to ask for permissions at runtime, we have to write some extra code for doing so, if we don’t do it, the app will crash because access to the current location is dangerous permission that needs to be approved by the user.

In this case, we’ll use PermissionsManager, which is a useful class that helps request permissions at runtime and it’s part of Mapbox SDK, so, you don’t need to add an extra dependency. 

Go to your MainActivity.kt and create a new nullable variable permissionsManager

 

 

Then let’s create a new function on which we’ll do two things; a) create a new instance for permissionManager and b) request for the current user location.

 

 

enableLocationComponent(loadedMapStyle: Style) is a function that will be called whenever our map it’s ready to be used, and we’ll pass the map style as a parameter, but we’ll see that later on.

PermissionsManager.areLocationPermissionsGranted(this) is a method that will verify if the user has already granted the location’s permissions. If those permissions haven’t been granted yet, we have to create a new PermissionManager instance and then request for those permissions; this process will display a dialog asking the user if he wants to allow the Mapbox App access to the location.

 

Mapbox App access

 

When the user hits on either DENY or ALLOW, the system invokes onRequestPermissionsResult() method, passing it the user response. Here, we would have to know whether the user accepted the permissions or not, but since we’re using PermissionManager, we don’t have to do that, the only thing for us to do is calling onRequestPermissionsResult() method from the permissionManager instance.

Override onRequestPermissionResult() method under onCreate() method

 

 

Finally, the last thing for us to do is adding PermissionListener to MainActicvity class and implement the two functions required: onExplanationNeeded and onPermissionResult

 

 

onExplanationNeeded() method will be called when the user has previously denied the permission and we have to show an explanation asynchronously without blocking the main thread. After the user sees the explanation, we can request the permissions again.

onPermissionResult() method will be called when the user denies or accepts the permissions; here, we’ll show a message when permissions have been denied, otherwise we’ll get the user’s current location.

Once you’ve finished adding permissions, your MainActivity class has to look like this:

 

MainActivity class

 

Step 3 – Setting up Mapbox

Next, we have to create variables that will handle the instance of our map:

 

 

Once you are done adding the lines of code above, you will see that getMapAsync(this) is throwing a complaining error, this is due to a listener that we don’t have implemented on MainActivity class yet; to solve this problem let MainActivity implement interface OnMapReadyCallback.

 

OnMapReadyCallback.

 

onMapReady() is a method that will trigger every time when our map is ready to be used, here is when we have to set the map style and assign the value of our mapboxMap variable.

Inside of the onMapReady() method add these lines of code:

 

 

setStyle() method needs two parameters, the style of our map and a callback that will tell us when the style is already available for use.

The available Mapbox styles are listed below; you can use your favorite style or the one that fits your project’s preferences. Also, if none of the default styles are what you need, you can create a custom style from the Mapbox dashboard.

  • MAPBOX_STREETS
  • OUTDOORS
  • LIGHT
  • DARK
  • SATELLITE
  • SATELLITE_STREETS
  • TRAFFIC_DAY
  • TRAFFIC_NIGHT

 

Also, the Mapbox map has its own lifecycle the same as an activity, it’s important to add it because by doing this, we avoid any error or memory leaks on our application when using the map. 

We have to set up the Mapbox lifecycle by adding the next methods just under onCreate() method

 

 

We need to add just one more thing to run the application and see the map in action. To do so, Mapbox has to be initialized before getting it started, we can accomplish it by setting the next line of code before setContentView(R.layout.activity_main). This is important because if we don’t do that, we’ll get a RunTimeException

 

Mapbox.getInstance

 

Once you’ve added this line, you may run the application. You have to see something like this:

 

Mapbox

 

Step 4 – Get the user’s current location

In order to enable the user’s current location, we’ll use Mapbox’s locationComponent method; this method can be used to display the user’s location on the map.

Go to enableLocationComponent(loadedMapStyle: Style) and set this locationComponent configuration under the if which we use for asking for permission.

 

 

activateLocationComponent method initializes the component and needs to be called before any other operations are performed.

We used locationComponent?.isLocationComponentEnabled method for enabling location updates.

locationComponent?.cameraMode camera mode determines how the camera will track the user’s current location, in this case, we set it not to track the user’s location, that way we set CameraMode.NONE. If you need another mode for your camera, you can visit the official documentation here, where the different modes for the camera are shown.

locationComponent?.renderMode we finally have the renderMode method, which is how the user’s current location will be rendered on the map.

We have already set the configurations for enabling the location component to our map, now we’re going to get the last known location and move the camera to it.

Add these lines of code just below the locationComponent?.renderMode = RenderMode.COMPASS line

 

 

With the code above, we’re getting the user’s location and creating a CameraPosition.Builder that we’ll use to move the camera map to the location found. Now, run the project again to see how this works!

 

Mapbox

 

Step 5 – Searching addresses

Note: For this step of the tutorial, we won’t explain how coroutines work and the way they were implemented. We’ll only see how to search for addresses and how to handle the Places API response.

First, let’s create the variables that we’re going to need; add them above of onCreate() method

 

 

Inside of onCreate() method, create the instance for the mainViewModel and then, let’s define our observe method as well.

 

 

Also, let’s create the adapter’s instance that will handle the address found.

 

 

The way the application works is as follows: on every character the user is typing, a new request has to be triggered in order to get the addresses that match with that letter or word; in that way, the Places API can give us results matching with the string that is being added by the user.

 

 

afterTextChanged(s: Editable?) is the function that we’ll use to send a request on every character typed by the user. There are two things that are inside this function

  1. Cleaning the search adapter when there isn’t any text on the edit text and hiding the addresses list.
  2. Starting the request using the string on edit text in conjunction with centerLocation.

 

afterTextChanged

 

When a user clicks on etAddress, we have to get the location that the camera is pointing at.

Let’s add a touch listener to the Edit Text so when a user clicks on the address field we’ll get the values of centerLocation.

 

 

Now, you are ready to run the application and start looking for addresses.

 

Mapbox looking for addresses

 

Step 6 – Looking for addresses near the user’s current location

If you run the application and look for an address, you can see the response is returning addresses far from your location or even from another continent; this behavior is completely fine and it’s because we haven’t configured the Places API, which just looks in a certain area by default.

Go to the MainRepository class, then navigate to the getMapboxGeocoding() method, here we’re creating a MapboxGeocoding object needed to search for addresses; this object must have two required parameters, the Mapbox access token, and the location query. 

To start looking for addresses near the user’s location you can use the proximity() method, passing in the user’s location as a Point object to bias results to around the location.

First, let’s validate if centerLocation isn’t null, to prevent the application from crashing due to a NullPointerException.

 

 

Your getMapboxGeocoding() function has to look like this:

 

getMapboxGeocoding() function

 

Step 7 – add a marker

Once we get the list of addresses, we’re going to print a marker over the map when a user clicks on an address. 

On the latest version of Mapbox, for drawing any visual property over the map, we have to create them as Annotations.

According to Mapbox’s documentation, Annotation simplifies the way to set and adjust the visual properties of annotations on a Mapbox map;  “annotations” means circles, polygons, lines, text, and icons that we, as developers, can draw over the map.

For this tutorial, we’ll use the Symbol annotation. First, in order to create a new symbol, let’s create a symbol manager, add this line just above the onCreate() method.

 

 

This manager will let us create symbols over the map with specific methods and properties that we can use to configure every symbol.

Next, let’s create a new function in which we’ll create the instance of symbolManager.

 

 

Now, go to the onMapReady() function and inside the setStyle block add initMarkerIconSymbolManager function. When the map is ready to be used, a new SymbolManager instance will be created, and we’ll be allowed to set symbols on that new map instance.

 

map instance

 

Next, create an addMarker() function that will receive a Point object as a parameter; inside this function, we’re creating a new SymbolOption object, this object will let us define the new symbol that will be created.

 

 

Also, add this function, it will work to hide the keyboard once the user selects an address from the list.

 

 

Finally, override the onSelectAddress() method of the SearchListener that belongs to the SearchAdapter.

 

 

And that’s it! Now, run your application, search for an address, and select one of the options on the list.

 

Mapbox gif

 

EOF

You just learned the basics of adding Mapbox to your project! I hope that you enjoyed this tutorial as much as I did. I invite you to share this tutorial so more people understand Mapbox. If you have questions, suggestions or you think something is missing in this tutorial, or you just want to share your thoughts, leave a comment below, I’d appreciate the feedback. Happy coding!

 

Cover image: Bobby Sudekum

 

0 0 Continue Reading →

6 reasons why you should stop using Java and use Kotlin instead

 

As an Android developer who started working with Android 4 years ago, I had to learn Java in order to create native applications. For the first two years, I learned a lot about Java and I started to feel that I was getting good at it. During this period, I heard you could use Kotlin to create Android apps but I always thought “There’s no way Google would deprecate Java, it’s their main language.”

A year passed, and first-class support for Kotlin was announced at Google I/O 2017. In 2018 Kotlin was voted as the second most loved programming language (StackOverflow).

 

Most Loved, Dreaded, and Wanted Languages

StackOverflow. (2018). Developer survey 2018. [Image]. Retrieved from https://insights.stackoverflow.com/survey/2018

 

Additionally, according to Pusher in “The state of Kotlin 2018”, after the official announcement, the Android community has been migrating from Java to Kotlin rapidly.

 

Kotlin’s growth
Pusher. (2018). The state of Kotlin 2018. [Graphic]. Retrieved from https://pusher.com/state-of-kotlin

 

A few months after Google I/O 2017, I was still using Java because I thought Google would not deprecate it, and you could still use it to make apps, so I thought Kotlin was in its “baby steps”.

Even when I kept thinking I should wait a little bit more, I did not want to lose an opportunity to learn a new programming language, so I decided to experiment a bit. I started reading articles, blog posts, and following tutorials. After a while, I started to get bored because I was only doing tutorials or easy examples of Kotlin. Following tutorials are a good start, but it only shows you the basics of a certain topic, and I really wanted to apply all the new things that I had been learning to a real project. My prayers were heard and I was assigned to a new project in which I had to start from scratch, so I took the risk to use a new language in a real project and learn on the way.

To my surprise, learning Kotlin was unexpectedly easy thanks to my Java background. If you’re asking yourself, “Should I use Kotlin instead of Java?” Well, yes, you should! But, why?

 

Here are some advantages of Kotlin over Java that to consider:

 

1. Say goodbye to NullPointerException

The NullPointerException is the most common exception for a Java developer that Kotlin wants to eliminate by using Nullable types. A nullable type is an object that can be either null or not, and it is defined by the question mark (?). 

If you try to access some property of a certain String, e.g., the length of b, the Kotlin compiler won’t allow you to compile your code because it detects a prominent NullPointerException (NPE). In order to know the length of a nullable string, you have to tell the compiler that it can access that property only if it is different from null by adding the question mark.

The main benefit of using nullable types is that they give us the chance to avoid an unexpected NPE before our app crashes in runtime.

Nullable types provide this benefit due to Kotlin, which detects a possible NPE and Android Studio won’t let us compile our code until we fix it, ensuring that our application is null-safe. However, you may keep in mind that Kotlin does not solve the NPE issue, but it forces you to prevent this exception when your app is running.

 

2. Extension functions

An extension function is a way in which you can add new functionality to an existing class without having it inherit from the class. For example, if you want to remove the last character of a String:


3. Reduce boilerplate 

Boilerplate is the repetitive code that you see in almost every place of your project. A really cool example to identify a repetitive code is a POJO class in Java.

You can create the same POJO class in Kotlin by defining a data class. 


4. Data class

The example above is using a data class; we can use a data class when the main purpose of the class only holds data. Likewise, it gives us the chance to avoid adding unnecessary code to every class we need.

 

5. Interoperability

Kotlin can work with Java in the same project without any trouble because both languages have similar bytecode structure. If you are migrating your app or you want to add a feature (built with Kotlin) in your existing Java application you can do it.

 

6. Android Studio IDE

Android studio has grown a lot, and its compatibility with Kotlin is excellent. Also, it has a feature which lets you convert Java code into Kotlin code by just doing a simple copy/paste, or with a few clicks. This is a useful advantage if you are considering migrating your Java app, but keep in mind that you have to be careful because you are going to use Android Studio to migrate your full code. I prefer to use this feature only to convert little pieces of code.

 

It’s not all a bed of roses.

Kotlin is not a perfect language. In fact, it has cons that you may be interested in knowing before choosing it as your main language to develop Android applications.


Learning curve if you are not a Java developer

I mentioned that if you are a Java developer, the learning curve is effortless but, it may be difficult if you are learning on your own without having an expert Kotlin developer helping you or without any Java experience.

Speed compilation
When we talk about speed in compilation time, Kotlin seems to be slower than Java in some cases when trying to perform clean builds.

Find a Kotlin expert
There are a lot of Kotlin developers available in the market, but if you want to find an experienced mentor that helps you improve your skills, it may be a difficult task.

A few learning resources
As I mentioned before, the Kotlin community has been growing fast, but even so, finding a good learning resource could be difficult if we compare it with Java.

If you are interested in learning Kotlin but you don’t know how to start or where to start, you can visit these links to learn more about it:

  • The official Kotlin page is the official documentation that Kotlin gives us. It is easy to read and it has a lot of good examples.
  • Android code labs are a bunch of awesome tutorials made by Google developers.
  • Android Weekly is a free newsletter that helps you to stay cutting-edge with your Android Development skills. Every week you will receive an email with several topics, tutorials, and posts about Android development.

 

Conclusion

Everything about Kotlin has been fascinating. I have encountered zero issues with this language or any implementation that I want to add to my projects. I have been able to solve every challenge I have faced by using Kotlin, without the necessity of adding any Java to my code. 

I do recommend you look for guides when starting to use Kotlin, especially if you’re not a Java developer. Getting help could fast track your learning. Receiving tips, getting feedback, or maybe being told the solution you implemented is not the best; every padawan always needs a Jedi that guides them to the light side of the force. 

If you are still using Java, my suggestion is to try Kotlin. If you have been following Google’s I/O since 2017, you have noticed all examples about new implementations and tools are using Kotlin. If you are a beginner and looking for a language to learn, choose Kotlin and do not worry; there is a lot of good information about how to start. 

 

https://pusher.com/state-of-kotlin#adoption
https://kotlinlang.org/docs/reference/android-overview.html
https://kotlinlang.org/docs/reference/data-classes.html
https://kotlinlang.org/docs/reference/extensions.html
https://insights.stackoverflow.com/survey/2018
https://www.netguru.com/blog/kotlin-java-which-one-you-should-choose-for-your-next-android-app

0 7 Continue Reading →

 

Recent Comments by Robert Avalos

    No comments by Robert Avalos