Mbile/Wireless Systems Using Ggle Map in Andrid Yanyan Zhuang Department f Cmputer Science http://www.cs.uccs.edu/~yzhuang UC. Clrad Springs
Setup Install the Ggle Play services SDK Tls > Andrid > SDK manager 2
Create a Ggle Maps prject Select Ggle Maps Activity in the 'Add an activity t Mbile' dialg When build finished, Andrid Studi pens ggle_maps_api.xml and MapsActivity.java ggle_maps_api.xml cntains instructins n getting a Ggle Maps API key befre yu try t run the applicatin. 3
Get a Ggle Maps API key Apps need an API key t access Ggle Maps servers The key is free. Yu can use it with any f yur applicatins that call the Ggle Maps Andrid API, and it supprts an unlimited number f users 1. Cpy the link in ggle_maps_api.xml, paste it int brwser 2. Fllw the instructins t create a new prject n the Ggle API Cnsle r select an existing prject 3. Create an Andrid-restricted API key fr yur prject 4. Cpy the resulting API key, g back t Andrid Studi, and paste the API key int the <string> element in ggle_maps_api.xml May use the same key fr mre than ne app 4
Run the app By default, the XML file that defines the app's layut is at res/layut/activity_maps.xml The simplest way t see yur app in actin is t cnnect an Andrid device t yur cmputer Yu can use Andrid Emulatr t run app When chsing an emulatr, use Andrid 4.2.2 r higher, and be careful t pick an image that includes the Ggle APIs, r the applicatin will nt have the runtime APIs in rder t execute 5
Run the app (2) Yu shuld see a map with a marker psitined ver Sydney, Australia If yu dn't see a map, check that yu've added an API key as described Check the lg in Andrid Studi's Andrid Mnitr fr errr messages abut the API key Different ways t get the API key https://develpers.ggle.cm/maps/dcumentatin/andridapi/signup 6
Understand the cde AndridManifest.xml <meta-data andrid:name="cm.ggle.andrid.ge.api_key" andrid:value="@string/ggle_maps_key" /> (generated fr yu) activity_maps.xml <fragment> element t yur activity's layut file Defines a SupprtMapFragment t act as a cntainer fr the map and t prvide access t the GgleMap bject <fragment name="cm.ggle.andrid.gms.maps.supprtmapfragment" andrid:layut_width="match_parent" andrid:layut_height="match_parent"/> 7
Understand the cde What is a fragment? A Fragment represents a behavir r a prtin f user interface in an Activity Can cmbine multiple fragments in a single activity t build a multi-pane UI and reuse a fragment in multiple activities Can think f a fragment as a mdular sectin f an activity, which has its wn lifecycle, receives its wn input events, and which yu can add r remve while the activity is running } srt f like a "sub activity" that yu can reuse in different activities 8
Understand the cde MapsActivity s ncreate() @Override prtected vid ncreate(bundle savedinstancestate) { super.ncreate(savedinstancestate); // set the layut file as the cntent view setcntentview(r.layut.activity_maps); // get a handle t the map fragment SupprtMapFragment mapfragment = (SupprtMapFragment) getsupprtfragmentmanager().findfragmentbyid(r.id.map); // use getmapasync() t register fr map callback (when map is ready) mapfragment.getmapasync(this); } 9
Understand the cde Implement OnMapReadyCallback interface & verride nmapready(): set up the map when GgleMap bject is available public class MapsActivity extends AppCmpatActivity implements OnMapReadyCallback { // OnCreate() methd here: as described n last slide @Override public vid nmapready(gglemap gglemap) { // Add a marker in Sydney, Australia, and mve map's camera LatLng sydney = new LatLng(-33.852, 151.211); gglemap.addmarker(new MarkerOptins().psitin(sydney).title("Marker in Sydney")); gglemap.mvecamera(cameraupdatefactry.newlatlng(sydney)); } } 10
Understand the cde By default, the Ggle Maps API displays the cntent f title when the user taps a marker gglemap.addmarker(new MarkerOptins().psitin(sydney).title("Marker in Sydney")); There's n need t add a click listener fr the marker if yu re happy with the default behavir 11
Summarize The basic steps fr adding a map 1. (Yu nly need t d this nce) Get Ggle Play Service SDK, btain a key and add the required attributes t Andrid manifest 2. Add a <fragment> element t the layut file fr the Activity 3. Call getmapasync() n the fragment t register the callback 4. Implement the OnMapReadyCallback interface and use the nmapready(gglemap) callback t get a handle t the GgleMapbject 12
Map Types Nrmal Hybrid Terrain Satellite Nne GgleMap map;... // Sets the map type t be "hybrid" map.setmaptype(gglemap.map_type_hybrid); 13
Markers Yu can custmize markers by changing the default clr, r replacing the marker icn with a custm image Inf windws can prvide additinal cntext t a marker Markers are bjects f type Marker Added t map with the GgleMap.addMarker(markerOptins) methd Receive click events by default, and are ften used with event listeners t bring up inf windws Previus example } gglemap.addmarker(new MarkerOptins().psitin(sydney).title("Marker in Sydney")); 14
Markers Sme ther examples Marker marker = gglemap.addmarker(new MarkerOptins().psitin(new LatLng(-34, 151))); marker.revmte(); Setting a marker t be invisible, and transparency Marker marker = gglemap.addmarker(new MarkerOptins().psitin(new LatLng(-34, 151)).visible(false).alpha(0.8f)); 15
Markers Once a marker is created, yu can change its prperty marker.setalpha(1.0f); marker.setvisible(true); marker.setpsitin(new LatLng(-34, 151)); Why marker visibility? Faster t make an invisible marker visible, than creating a new marker Shw infrmatin gglemap.addmarker(new MarkerOptins().psitin(sydney).title("Sydney").snippet( Ppulatin: 4.5 millin in 2015 )); 16
Markers Respnd t click events Activity must implement GgleMap.OnMarkerClickListener Set a listener fr marker click } @Override public vid nmapready(gglemap gglemap) {... mmap.setonmarkerclicklistener(this); } Implement callback functin nmarkerclick() 17
Markers Respnd t click events Implement callback functin nmarkerclick() } @Override public blean nmarkerclick(final Marker marker) { if (marker.equals(mymarker)) { Tast.makeText(this, marker.gettitle() + " has been clicked!", Tast.LENGTH_LONG).shw(); } return false; } 18
Tasts A tast prvides simple feedback abut an peratin in a small pp-up Only fills the amunt f space required fr the message and the current activity remains visible and interactive Tasts autmatically disappear after a timeut Instantiate a Tast bject with maketext() methd 3 parameters: the applicatin Cntext (usually this), the text message, and the duratin fr the tast Tast.LENGTH_SHORT and Tast.LENGTH_LONG 19
Tasts Example Cntext cntext = getapplicatincntext(); CharSequence text = "Hell tast!"; int duratin = Tast.LENGTH_SHORT; Tast tast = Tast.makeText(cntext, text, duratin); tast.shw(); Tast.makeText(cntext, text, duratin).shw(); 20
Tasts Psitining yur Tast A standard tast ntificatin appears near the bttm f the screen, centered hrizntally Yu can change this psitin with the setgravity(int, int, int) methd: a Gravitycnstant, an x-psitin ffset, and a y-psitin ffset If the tast shuld appear in the tp-left crner } tast.setgravity(gravity.top Gravity.LEFT, 0, 0); } If yu want t nudge the psitin t the right, increase the value f the secnd parameter. T nudge it dwn, increase the value f the last parameter 21
Select Current Place Create a Ggle API client Als knwn as the Ggle API client: cnnect with fused lcatin prvider and Ggle Places API } private GgleApiClientmGgleApiClient; 22
Select Current Place Build a Ggle API client Request the fused lcatin prvider (LcatinServices.API) and the tw parts f the Ggle Places API fr Andrid (Places.GEO_DATA_API and Places.PLACE_DETECTION_API) mggleapiclient = new GgleApiClient.Builder(this).enableAutManage(this /* FragmentActivity */, this /* OnCnnectinFailedListener */).addcnnectincallbacks(this).addapi(lcatinservices.api).addapi(places.geo_data_api).addapi(places.place_detection_api).build(); mggleapiclient.cnnect(); 23
Select Current Place Cannt reslve LcatinServices and Places Add dependencies in build.gradle (Mdule: app) cmpile 'cm.ggle.andrid.gms:play-services-lcatin:10.2.0' cmpile 'cm.ggle.andrid.gms:play-services-places:10.2.0 Sync Then we can imprt classes fr LcatinServices and Places 24
Select Current Place Call back functins f mggleapiclient.cnnect() @Override public vid ncnnected(bundle cnnectinhint) {... } /* Handles failure t cnnect t the Ggle Play services client. */ @Override public vid ncnnectinfailed(@nnnullcnnectinresult result) { Lg.d(TAG, "Play services cnnectin failed: CnnectinResult.getErrrCde() = " + result.geterrrcde()); } /* Handles suspensin f the cnnectin t the Ggle Play services client. */ @Override public vid ncnnectinsuspended(int cause) { Lg.d(TAG, "Play services cnnectin suspended"); } 25
Lcatin Services API Enables r disables the my-lcatin layer mmap.setmylcatinenabled(true); While enabled and the lcatin is available, the my-lcatin layer cntinuusly draws an indicatin f a user's current lcatin and bearing, and displays UI cntrls that allw a user t interact with their lcatin In rder t use the my-lcatin-layer feature yu need t request permissin fr either ACCESS_COARSE_LOCATION r ACCESS_FINE_LOCATION 26
Lcatin Services API Enables r disables the my-lcatin buttn mmap.getuisettings().setmylcatinbuttnenabled(true) The my-lcatin buttn causes the camera t mve such that the user's lcatin is in the center f the map. If the buttn is enabled, it is nly shwn when the my-lcatin layer is enabled By default, the my-lcatin buttn is enabled 27
Lcatin Services API Get the best and mst recent lcatin f the device (may be null in cases when a lcatin is nt available) mlastknwnlcatin = LcatinServices.FusedLcatinApi.getLastLcatin(mGgleApiClient); Set the map's camera psitin t the current lcatin f the device and zm in if (mlastknwnlcatin!= null) { mmap.mvecamera(cameraupdatefactry.newlatlngzm( new LatLng(mLastKnwnLcatin.getLatitude(), mlastknwnlcatin.getlngitude()), DEFAULT_ZOOM)); } 28
Place Detectin API Get an estimate f the place where the device is currently lcated PendingResult<PlaceLikelihdBuffer> result = Places.PlaceDetectinApi.getCurrentPlace(mGgleApiClient, null); Generates a PlaceLikelihdBuffer based n device's last estimated lcatin Returned values may be btained by means f a netwrk lkup: results are a best guess and nt guaranteed t be crrect Requires ACCESS_FINE_LOCATION permissin Access t this methd is subject t quta restrictins 29
Place Detectin API Ppulate place infrmatin result.setresultcallback(new ResultCallback<PlaceLikelihdBuffer>() { @Override public vid nresult(@nnnull PlaceLikelihdBuffer likelyplaces) { mlikelyplacenames = new String[mMaxEntries]; fr (PlaceLikelihd placelikelihd : likelyplaces) { // Build a list f likely places t shw the user. Max 5. mlikelyplacenames[i] = (String) placelikelihd.getplace().getname(); } // Release the place likelihd buffer, t avid memry leaks. likelyplaces.release(); } }); 30
Setting an AlertDialg fr Users t Pick AlertDialg lets users t interact with the app AlertDialgdialg = new AlertDialg.Builder(this).setTitle("pick a place").setitems(mlikelyplacenames, listener).shw(); Syntax: use AlertDialg.Builder s methd setitems (CharSequence[] items, DialgInterface.OnClickListener listener) } Set a list f items t be displayed in the dialg as the cntent } Cde will be ntified f the selected item via the supplied listener } Implement the listener 31
Setting an AlertDialg fr Users t Pick Listener DialgInterface.OnClickListener listener = new DialgInterface.OnClickListener() { @Override public vid nclick(dialginterface dialg, int which) { // The "which" argument cntains the psitin f the selected item. LatLng markerlatlng = mlikelyplacelatlngs[which]; String markersnippet = mlikelyplaceaddresses[which];... // Add a marker fr the selected place, with an inf windw w/ infrmatin abut that place mmap.addmarker(new MarkerOptins().title(mLikelyPlaceNames[which]).psitin(markerLatLng).snippet(markerSnippet)); } }; // Psitin the map's camera at the lcatin f the marker. mmap.mvecamera(cameraupdatefactry.newlatlngzm(markerlatlng, DEFAULT_ZOOM)); 32