Not too long ago, if you were traveling to a new or unfamiliar place then you had to bring a physical map along with you, or at the very least do some research beforehand and be prepared to ask for directions if you ended up getting lost.
Maps on mobile devices mean that getting lost is rapidly becoming a thing of the past, as not only does your typical smartphone put a map of the entire world at your fingertips, but it can also track and display your current location, so you can always see exactly where you are on that map.
Adding a map to your latest Android app project has the potential to greatly improve the user experience – whether you’re creating a Gallery app that lets the user see exactly where each photo was taken; an exercise app that displays the route you took on your morning run, or a memo app that lets users write themselves reminders that pop up automatically as soon as they reach a specific location.
In this article, I’ll show you how to use the Google Maps API to add maps to your Android applications. These maps are based on Google Maps data, and will have the same appearance and much of the same functionality as the maps you encounter in the official Google Maps for Mobile app.
We’ll start by using Android Studio’s built-in Google Maps template to quickly generate an application that displays a map, before adding localisation awareness so this app is able to track and display the user’s current location.
Create your project
The Google Maps Android API is distributed as part of the Google Play Services SDK, so the first thing you should do is launch your SDK Manager and make sure you have the latest version of Google Play Services installed – if an update is available, then now’s the time to install it.
Next, create an Android Studio project with the settings of your choice, but when you reach the ‘Add an Activity to mobile’ screen, make sure you select ‘Google Maps Activity.’
The benefit of using this template, is that most of the code needed to display a map gets generated automatically – you’ll only need to make a few tweaks and you’ll have an app that’s capable of displaying Google Maps data.
Before we make these changes, let’s take a closer look at this automatically-generated code, as it provides a pretty good example of how you should go about adding maps to your Android applications.
Let’s start with our project’s res/layout/activity_maps.xml file. Open this file and you’ll see that the map element is inserted into your layout via a MapFragment.
MapFragment functions much like your typical fragment – it represents a portion of your user interface, and you can combine it with other layouts to create a multi-pane layout. However, in addition to acting as a container for your map, MapFragment automatically handles all of your map’s lifecycle needs, making it one of the easiest ways of inserting a map into your application.
Your automatically-generated activity_maps.xml code should look something like this:
Declaring your MapFragment via XML may be the most straightforward solution (and it’s the approach I’ll be using throughout this tutorial) but if you need to, you can add a MapFragment programmatically, by creating a MapFragment instance and then adding it to the current Activity, using FragmentTransaction.add:
The other automatically-generated file that’s worth exploring in detail, is your project’s MapsActivity.java file:
As already mentioned, Android Studio does a lot of the hard work for you, but in its current state this project isn’t quite capable of displaying Google Maps data. You still need to make a few tweaks to your code and acquire a Google Maps API key – which we’re going to cover in the next few sections.
Updating Project Dependencies
The first change you need to make, is declaring Google Maps and Google Location APIs as project dependencies. Open your project’s module-level build.gradle file and you’ll see that Android Studio has already added the Google Play Services SDK to the dependencies section:
The problem is that this will compile the entire package of Google Play Services APIs, which can make it more difficult to keep the number of methods in your app under control. Unless you plan on using a long list of features from this package, then it makes more sense to compile the specific parts of the Google Play Services API that you’re actually going to use.
For the sake of a more streamlined project, I’m going to remove this general Google Play Services dependency, and specify that my project uses the Google Maps and Location APIs only:
Note, however you declare your Google Play Services dependencies, you should update their corresponding version numbers every time you download a new version of the Google Play Services SDK.
Get a Google Maps API key
If your project is going to pull data from the Google Maps servers, then it’ll need a Google Maps API key, which you obtain by registering your project with the Google API Console.
Once again, the ‘Google Maps Activity’ template has done a lot of the hard work for you. This template includes a google_maps_api.xml file that contains a URL you can use to generate a unique Google Maps API key. Although you can log into the Google API Console independently and generate API keys outside of this template, the benefit of using this URL is that most of the information about your project is already entered for you. In the interests of saving time, this is the method I’m going to use to generate my API key:
Open your project’s res/values/google_maps_api.xml file.
Copy the URL inside this file, and paste it into your web browser. This will take you directly to the Google API Console.
Make sure ‘Create a project’ is selected from the dropdown menu, then click ‘Continue.’
Check the terms and conditions, and if you’re happy to proceed click ‘Agree and continue.’
When prompted, click the ‘Create API key’ button.
At this point, you can choose between generating a generic API key that has no restrictions and can run on any platform, or a restricted API that can run on the specified platform only. Restricted APIs tend to be more secure, so unless you have a very good reason not to, you’ll typically want to generate a restricted API by clicking ‘Restrict key’ from the popup that appears.
Under the ‘Key restrictions’ section, make sure ‘Android apps’ is selected.
Click ‘Save.’
You’ll now be taken to the ‘Credentials’ section of the Google API Console. Find the API key you just created, and copy it.
Hop back to Android Studio and paste this key into your google_maps_api.xml file, specifically its <string name=”google_maps_key” element.
When you add the API key to your google_maps_api.xml file, Android Studio should automatically copy this key into your project’s Manifest. It’s a good idea to check that this has actually happened, so open your Manifest and make sure the following section is now displaying your unique API key:
Updating your Manifest
While you have your project’s Manifest open, let’s make a few more changes to this file. Firstly, you’ll need to specify the version of Google Play Services that you’re using, for example:
If you’re targeting anything earlier than version 8.3 of the Google Play services SDK, then you’ll also need to add the WRITE_EXTERNAL_STORAGE permission:
Note, if you’re targeting Google Play Services 8.3 or later, then your app won’t need to explicitly request permission to write to external storage.
Next, since the Google Maps Android API uses OpenGL ES version 2 to render its maps, you should make sure your app won’t wind up on a device that doesn’t support OpenGL ES 2, by declaring android:glEsVersion 2 as a required feature:
Most apps that include some form of maps functionality also require the following permissions, so save yourself some time and add them to your Manifest now:
This permission allows your app to check the device’s network status, which means your app can determine whether it can currently download data from Google Maps.
This permission gives your app the ability to open network sockets, so it can download data from the Google Maps servers.
Even though this first version of our app won’t display the user’s current location, we’ll be adding this feature shortly, so you should take this opportunity to add one of Android’s location-based permission requests to your Manifest:
Gives your app the ability to access the user’s approximate location, using the device’s Wi-Fi, mobile cell data, or both.
Gives your app the ability to determine the user’s precise location, using data from all the available location providers, including GPS, WiFi and mobile cell data.
After you’ve made these changes to your project’s Manifest, you’re ready to test your app. Either attach a physical Android device to your development machine or launch a compatible AVD, then select ‘Run’ from the Android Studio toolbar followed by the device you want to use. After a few moments the app should appear onscreen.
While you can interact with this map by dragging onscreen and pinching to zoom in, in its current state this map doesn’t detect your location. Since a map that has no idea where you are in the world isn’t particularly helpful (especially when compared to other location-aware apps), let’s give this project the ability to detect the user’s current location.
Accessing the user’s location
There’s several ways you can add location awareness to your app, but the easiest method is to use the Google Play Services Location API, which is distributed as part of the Google Play Services SDK.
In the following code, I’m still using the same API key and layout resource file, but I’ve updated my project’s MapsActivity.java file to determine the last known location of the user’s device, which most of the time will be roughly equviliant to the user’s current location:
Now it’s time to test your app by installing it on your Android device or a compatible AVD. Launch your app, and it should request access to your device’s location.
Grant this permission request and you should see the map – but this time it’ll be centered over your current location, complete with an accurate location marker.
Other map types
In this example, we set the map type to “normal,” however if you don’t like the look of the map that appears on your Android device, then you can always change it to any of the other maps supported by the Google Maps API:
MAP_TYPE_HYBRID. A satellite map with a transparent layer displaying major roads and feature labels.
MAP_TYPE_SATELLITE. A satellite map with roads, but no labels.
MAP_TYPE_TERRAIN. A topographic map that includes contour lines, labels and perspective shading. Some roads and labels may also be visible.
Summary
In this article, we looked at how to use the Google Maps API to add map content to your application, and how to display the user’s current location on this map, using the new permissions model introduced in Android 6.0. If you’d like to try this project for yourself, you’ll find the full code over at GitHub.