Lecture 13Mobile Programming
Google Maps Android API
Agenda
● Generating MD5 Fingerprint
● Signing up for API Key (as developer)
● Permissions
● MapView and MapActivity
● Layers
● MyLocation
Important!!!
These lecture slides are based on Google Maps Android API V2.V1 has been deprecated but if you are interested you can find the tutorials here
Google Maps API Key
● In order to use the Google Maps API, you first need to obtain an API key and configure your app
● Google Maps Android API V2 requires the installation/configuration of the Google Play Services SDK○ Installed Using the SDK Manager○ Available in the
extras/google/google_play_services/libproject/google-play-services-lib folder of your SDK directory
○ To test using the emulator it must be using Google API version 4.2.2 or later or 2.3 for a physical device
Google Maps API - Dependencies
● Add to build.gradle: compile 'com.google.android.gms:play-services-maps:11.8.0'
● If you are unsure of which version #, there is another way!○ Right-click your project and select Open Module Settings or
press F4 (Windows/Linux)○ Select the Dependencies tab○ Click the plus symbol and select Library dependency○ Enter play-services-maps and click search○ Select newest version ○ Click OK
Google Maps API - Google Play Services
After adding the library reference to your app, add the following to the AndroidManifest.xml file <application> node<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Getting Google Maps API Key
● Need to create API key for Google Maps
● Three methods:a. Fast - Using Android Studio
b. Less Fast - Also using Android Studio
c. Full form - Complete form
Getting Google Maps API Key - Fast method
● Create Google Maps app using Android
Studio
● This generates google_maps_api.xml file
● Open file, copy URL into browser, and click
Create New App -> authenticate
● Copy given API key
Getting Google Maps API Key - Less fast method
● Create Google Maps app using Android
Studio
● Copy credentials from google_maps_api.xml
● Open Google Developer Console
● Create new app in Console using credentials
● Copy given API key
Getting Google Maps API Key - Complete full form
● Create Google Maps app (or start from
scratch) using Android Studio
● Open Google Developer Console
● Create new Android app in Console
● Enable Google Maps API
● Copy given API key
Getting the MD5 Fingerprint (Optional)
● To register for a Maps API Key, you need to provide an MD5 fingerprint of the certificate that you will use to sign your application
● Navigate to C:\Documents and Settings\<User>\.android● Run the following commandkeytool -list -alias androiddebugkey -storepass android -keypass android -keystore debug.keystore
● Copy the text that comes after Certificate fingerprint (SHA1):○ Also it is important to make a note of the package name
for your application as you will need this to create the API key
● Go here and follow the instructions on creating a new API project and obtaining a Google Maps API Key
● Save the generated API key
Add the Maps API Key to Your App
● When creating your Android project, you need to choose one of the "Google APIs" options as your SDK target
● Add the following to the manifest file as a child of the application node<meta-data android:name=”com.google.android.geo.API_KEY”
android:value=”@string/google_maps_key” />
Add the Maps API Key to Your App
● We do not want to actually create @string/google_maps_key. Why?
● Instead, add key to gradle file, let gradle add API to app● Add the following to the gradle.properties file
○ GOOGLE_MAPS_API_KEY=<API-KEY>
● Add the following to app/build.gradle○ resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
● This dynamically creates string in strings.xml ○ i.e. <string name=”google_maps_key”>$GOOGLE_MAPS_API_KEY</string>
Example AndroidManifest...
<application …><meta-data
android:name="com.google.android.gms.version"android:value="@integer/google_play_services_version" />
<!-- The API key for Google Maps-based APIs. →<meta-data
android:name="com.google.android.geo.API_KEY"android:value="@string/google_maps_key" />
</application></manifest>
Permissions
To use the Google Maps API, you need
● android.permission.INTERNET● android.permission.ACCESS_NETWORK_STATE
And of course, GPS or NETWORK provider permissions if you're going to use location-based services
Add the Maps to Your App
● The easiest and recommended method of adding Google Maps support to your application is by using a MapFragment
● Add the following to your XML layout file
<fragment android:id="@+id/map"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:name= "com.google.android.gms.maps.SupportMapFragment" />
MapView
● You can also use a MapView in your application instead of a MapFragment
● You MUST forward all the lifecycle from the containing Activity or Fragment to the corresponding ones in the MapView class○ onCreate(Bundle)○ onResume()○ onPause()○ onDestroy()○ onSaveInstanceState()○ onLowMemory()
Google Maps - GoogleMap
● To interact with the map, you will need to get a handle on the GoogleMap object from your MapView or MapFragment
● You can do this with a call to the getMap() method
e.g.
GoogleMap map = ((MapFragment)
getFragmentManager().findFragmentById(
R.id.map)).getMap();
GoogleMap - Center and Zoom
If you want to be able to have the map centered on a specific location call
map.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(lat, lng)));
To center and zoom call
map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), zoomLevel));
GoogleMap - Center and Zoom
● By default the zoom controls are enabled on the map
● To set them specifically enabled/disabled callmap.getUiSettings().setZoomControlsEnabled(enable
d)
where enabled is a boolean value
Layers - Overlay Classes
● Right now your Map looks bare and boring. ● At some point you may want to add some
small icons to your map● You can do this by adding overlays that will
hover above the map itself. This is where things can get messy
Layers - Overlay Classes
● The overlay options vary by the type of overlay being added○ GroundOverlay (GroundOverlayOptions)○ Marker (MarkerOptions)○ TileOverlay (TileOverlayOptions)○ Circle (CircleOptions)○ PolyLines and Polygons○ …
● For a full list see the Android developer documentation on the GoogleMap object
Layers - Overlay Classes
● Let's look at our MapActivity.onCreate()
Layers - Ground Overlay
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
GoogleMap map = mapFragment.getMap();
GroundOverlay overlay = mMap.addGroundOverlay(new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android_developers))
.anchor(0, 1)
.position(classLocation, 8600f, 6500f));
map.addMarker(new MarkerOptions().position(classLocation).title("Marker in Love 103"));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(classLocation, 18));
}
● Add image to location Map
Layers - Marker Overlay
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapFragment mapFragment = (MapFragment)
getFragmentManager().findFragmentById(R.id.map);
GoogleMap map = mapFragment.getMap();
map.addMarker(new MarkerOptions()
.position(new LatLng(30.446142, -84.299673))
.title(“Hello”)
.snippet(“Welcome to the Mobile Lab!”)
.icon(BitmapDescriptorFactory.fromResource(
R.drawable.mobile_logo)));
map.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(30.446142, -84.299673), 17.0f);
}
● Add marker to location on Map
Layers - Polylines Overlay
@Override
public void onMapReady(GoogleMap map) {
Polyline polyline1 = map.addPolyline(new PolylineOptions().clickable(true).add(
new LatLng(-35.016, 143.321),
new LatLng(-34.747, 145.592),
new LatLng(-34.364, 147.891),
new LatLng(-33.501, 150.217),
new LatLng(-32.306, 149.248),
new LatLng(-32.491, 147.309)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4));
// Set listeners for click events.
map.setOnPolylineClickListener(this);
map.setOnPolygonClickListener(this);
}
● Add marker to location on Map
My Location
● You may want to show the user their location on the map
● How can you do this?
My Location
● The Maps API provides an easier way, by using a MyLocationOverlay○ This is handled in the background by the GoogleMap
object
My Locationpublic class MyLocationMapExample extends Activity {
GoogleMap map;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
map = mapFragment.getMap();
map.getUiSettings().setCompassEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
}
}
My Locationpublic class MyLocationMapExample extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServices.OnConnectionFailedListener {
LocationClient client;
GoogleMap map;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
map = mapFragment.getMap();
map.getUiSettings().setCompassEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
}
}
This will show a compass when we add this Overlay to the map
My Locationpublic class MyLocationMapExample extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServices.OnConnectionFailedListener {
LocationClient client;
GoogleMap map;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
map = mapFragment.getMap();
map.getUiSettings().setCompassEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
}
}
This will enable the My Location Button
My Locationpublic class MyLocationMapExample extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServices.OnConnectionFailedListener {
LocationClient client;
GoogleMap map;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
map = mapFragment.getMap();
map.getUiSettings().setCompassEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
}
}
This will enable the MyLocation overlay in the GoogleMap object
Satellite Mode
● Google Maps on the desktop allows you to view the map in satellite view
● You can do this using the Maps API also● Just call setMapType() on your
GoogleMap object○ Type can be either
■ GoogleMap.MAP_TYPE_SATELLITE■ GoogleMap.MAP_TYPE_HYBRID■ GoogleMap.MAP_TYPE_NONE■ GoogleMap.MAP_TYPE_NORMAL■ GoogleMap.MAP_TYPE_TERRAIN
Customize Map Style
● Can customize map colors/content○ e.g. Only display roads and bodies of water
● Create/Modify json style file○ https://mapstyle.withgoogle.com/○ HIGHLY customizable
● Add json file to res/raw● Apply file using GoogleMap.setMapStyle()
Customize Map Style Example@Override
public void onMapReady(GoogleMap googleMap) {
…
try { boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(this, R.raw.map_style));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
…
}
Finding out where was clicked
● When the user clicks on one of your Overlay items, you don't need to perform any complex calculations to determine where on the Canvas was clicked○ This information is readily available
● Additionally the location on the map that was clicked can be obtained by setting the OnMapClickListener of the GoogleMap object
Finding out where was clickedmap.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker arg0) {
LatLng position = arg0.getPosition();
Toast.makeText(getApplicationContext(),
“Lat: “ + position.latitude + “, Lng: “ + position.longitude,
Toast.LENGTH_LONG).show();
return true;
}
});
map.setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng arg0) {
Toast.makeText(getApplicationContext(),
“Lat: “ + arg0.latitude + “, Lng: “ + arg0.longitude,
Toast.LENGTH_LONG).show();
return true;
}
});
Finding out where was clickedmap.setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng arg0) {
Point screenLocation;
screenLocation = map.getProjection().toScreenLocation(arg0);
Toast.makeText(getApplicationContext(),
“Lat: “ + arg0.latitude + “, Lng: “ + arg0.longitude
+ “; x: “ + screenLocation.x + “, y: “ + screenLocation.y,
Toast.LENGTH_LONG).show();
}
});
The LatLng object corresponding to the location that was clicked on the map
Finding out where was clickedmap.setOnMapClickListener(new OnMapClickListener() {
@Override
public void onMapClick(LatLng arg0) {
Point screenLocation;
screenLocation = map.getProjection().toScreenLocation(arg0);
Toast.makeText(getApplicationContext(),
“Lat: “ + arg0.latitude + “, Lng: “ + arg0.longitude
+ “; x: “ + screenLocation.x + “, y: “ + screenLocation.y,
Toast.LENGTH_LONG).show();
return true;
}
});
Use a projection to get the screen location of the clicked location on the map
Showing a Popup instead of Toast
● In Google Maps for Android, when you click on an OverlayItem, it doesn't display a Toast, but it shows a popup that doesn't disappear○ This is done by default in Google Maps Android API
V2■ To override this default behavior implement your
custom listener and return true
References
● Android Developers● The Mobile Lab at Florida State University