Lecture 13 Mobile 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-pla y-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 command keytool -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.newlat Lng(new LatLng(lat, lng))); To center and zoom call map.animatecamera(cameraupdatefactory.newlat LngZoom(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 call d) map.getuisettings().setzoomcontrolsenabled(enable 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 Add image to location Map @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));
Layers - Marker Overlay Add marker to location on Map @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);
Layers - Polylines Overlay Add marker to location on Map @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);
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 Location public 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 Location public 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 Location public 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 Location public 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 clicked map.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 clicked map.setonmapclicklistener(new OnMapClickListener() { @Override public void onmapclick(latlng arg0) { The LatLng object Point screenlocation; corresponding to the location screenlocation = map.getprojection().toscreenlocation(arg0); that was clicked on the map }); } Toast.makeText(getApplicationContext(), Lat: + arg0.latitude +, Lng: + arg0.longitude + ; x: + screenlocation.x +, y: + screenlocation.y, Toast.LENGTH_LONG).show();
Finding out where was clicked map.setonmapclicklistener(new OnMapClickListener() { @Override public void onmapclick(latlng arg0) { Point screenlocation; screenlocation = map.getprojection().toscreenlocation(arg0); }); } Toast.makeText(getApplicationContext(), Use a projection to get the Lat: + arg0.latitude +, Lng: + arg0.longitude screen location of the clicked location on the map + ; x: + screenlocation.x +, y: + screenlocation.y, Toast.LENGTH_LONG).show(); return true;
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