Google Maps for Android Pt 2: User Location

In the previous article of this series, I covered how to set up Google Maps for Android, allowing you to display a map in your application that focused on a specific location. While that tutorial covered the important steps behind configuring Google Maps and getting it working in your app, it didn’t cover creating anything very exciting. In this tutorial we’re going to use the previous example as our starting point and take the next step towards something a little more interesting: tracking location so that the map displayed makes sense contextually for your user.

Adjusting to the User’s Location

While Sydney (our current default camera location) is probably a lovely city, the first thing we’ll do is figure out where the user is and focus the camera on them. In order to get the user’s location, we will need to add a permission to the AndroidManifest.xml file within the manifest tag. We have two options here: we can request coarse location information, which is based on wifi and cellular data, or we can get fine location information based on a device’s GPS, in addition to the other two sources. For this example, let’s stick to fine location.

After declaring the required permission in the manifest file, we’ll need to explicitly request it in our application for devices running Android Marshmallow and above. Returning to MapsActivity.kt, go into the onMapReady() function. We’re going to update this function to check wether or not the user has already granted location permissions. If they have, enable showing their location. If they haven’t, you can prompt them to grant the permission here.

You’ll notice that we have a parameter being passed into requestPermission() called LOCATION_PERMISSION. This is a value that you will set in your application to keep track of the requested permission.

private val LOCATION_PERMISSION = 42

If the user has already granted the location permission, then you can call a new method named initMap(), which will contain all of your initial map logic.

If your user hasn’t granted the location permission yet, then they will be forwarded to the onRequestPermissionResult() method, where you can check if they approved or denied it, and react accordingly.

Automatically Respond to Changes

So far we’ve made good progress in showing the user’s location on the map, but it still requires the user to actively press a button in order to center the camera on them. We can work around this by adding the location package from Google Play Services in our application. Start by going into your module’s build.gradle file and adding the following line under the dependencies node:

implementation 'com.google.android.gms:play-services-location:16.0.0'

Returning to MapsActivity.kt, create a member variable for the FusedLocationProviderClient, which is how we’ll tie into Android’s location system.

Now you can remove the code in initMap() involving the marker and camera in Sydney and replace it with this code that will listen to the FusedLocationProviderClient and center the camera on the user’s currently known location.

After running your app, you should see that the camera automatically focuses on your location at a set level of zoom. This would be a good time to play with the zoom level and see what would work best for your use cases. For example, while a level of 15.0f is fairly close to the user’s location,

3.0f zooms out enough to show a massive portion of the Earth.

You’ll also notice that more detailed information about the user’s surrounding area comes up at closer zoom levels. In the next tutorial, we’ll cover the map’s camera in more detail.

Continuously Updating Location

One tricky thing with this setup is that the location doesn’t update as the user moves. To get around this, we can listen to a LocationCallback in order to continuously update the user’s position. At the top of MapsActivity.kt, add a new member variable for the callback

private lateinit var locationCallback: LocationCallback

This value will be initialized and applied every time we want to start listening to the user’s location, like so:

You’ll notice that we aren’t just creating the callback, but we’re associating it with the FusedLocationProviderClient while also requesting updates at the end of the above function.

In order to start listening to this location updater, we will need to call our new method initLocationTracking() in both initMap() and onResume(). The reason we’re requesting locations in onResume() is we will want to stop listening for locations when the user backgrounds the app, but will also want to restart them as soon as the user returns.

With how this code is currently written, the camera will always refocus on the user when resuming the app or receiving a location update. This may not be the desired functionality for your own apps, so it’s worth mentioning that you can respond to changes in the user’s location in any way that makes sense for your own projects.

Conclusion

In this article you’ve learned how to update your Google Maps applications on Android to include location data about the user. By being able to show the user where they are in the world, and what’s around them, you’ll be able to give them more value from your application and help them achieve their goals. In the next article you will learn about the Google Maps camera, as well as new ways for your user’s to interact with the map. You can find the source code for this project on GitHub.