180 likes | 446 Views
CIS 470 Mobile App Development. Lecture 13 Wenbing Zhao Department of Electrical Engineering and Computer Science Cleveland State University wenbing@ieee.org. Location-Based Services. Displaying Google Maps in your Android application Displaying zoom controls on the map
E N D
CIS 470Mobile App Development Lecture 13 Wenbing Zhao Department of Electrical Engineering and Computer Science Cleveland State University wenbing@ieee.org CIS 470: Mobile App Development
Location-Based Services Displaying Google Maps in your Android application Displaying zoom controls on the map Switching between the different map views Retrieving the address location touched on the map Performing geocoding and reverse geocoding Obtaining geographical data using GPS, Cell-ID, and WiFi triangulation Monitoring for a location CIS 470: Mobile App Development
Displaying Maps When creating an app, need to select “Google Maps Activity”.Create an app and name it LBS CIS 470: Mobile App Development
Displaying Maps Also need to obtain the Maps API key (after you created your app) To get a Google Maps key, open the google_maps_api.xml file that was created in your LBS project Within this file is a link to create a new Google Maps key Copy and paste the link into your browser and follow the instructions Replace the YOUR_KEY_HERE placeholder in the google_maps_api.xml with your Google Maps key <resources><!--TODO: Before you run your application, you need a Google Maps API key. To get one, follow this link, follow the directions and press "Create" at the end: https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=AD:71:B7:6F:62:AA:7E:A6:30:10:AC:DC:CF:36:36:2C:9D:A7:C1:CB%3Bcom.wenbing.lbs Once you have your key (it starts with "AIza"), replace the "google_maps_key" string in this file. --><string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyCHapqQ2PtdWBdKwhHX8RmLlrkzaWb7rdE</string></resources> CIS 470: Mobile App Development
Zoom Control In activity_maps.xml, add maps:uiZoomControls=“true” <fragment xmlns:android="http://schemas.android.com/apk/res/android"xmlns:map="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/map"android:name="com.google.android.gms.maps.SupportMapFragment"android:layout_width="match_parent"android:layout_height="match_parent"map:uiZoomControls="true"tools:context="com.wenbing.lbs.MapsActivity" /> CIS 470: Mobile App Development
Changing Views By default, Google Maps is displayed in map view. You can change to satellite view programmatically by setting the map type: mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); CIS 470: Mobile App Development
Navigating to a Specific Location Programmatically show the map around a specific location using moveCamera() method public void onMapReady(GoogleMapgoogleMap) {mMap= googleMap;// Add a marker in Sydney and move the cameraLatLngsydney = new LatLng(-34, 151);mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));// mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); CIS 470: Mobile App Development
Getting the Location that was touched To get the latitude and longitude of a point on the Google Map that was touched, you must set a onMapClickListeneron mMap in onMapReady() method mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {@Overridepublic void onMapClick(LatLng point) {Log.d("DEBUG","Map clicked [" + point.latitude+ " / " + point.longitude+ "]"); Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());try { List<Address> addresses = geoCoder.getFromLocation(point.latitude,point.longitude,1); String add = "";if (addresses.size() > 0) {for (inti=0; i<addresses.get(0).getMaxAddressLineIndex(); i++) add += addresses.get(0).getAddressLine(i) + "\n"; }Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show(); }catch (IOException e) {e.printStackTrace(); }LatLng p = new LatLng(point.latitude, point.longitude);mMap.moveCamera(CameraUpdateFactory.newLatLng(p)); }}); CIS 470: Mobile App Development
Geocoding and Reverse Geocoding Knowing latitude and longitude of a location, you can find out its address using a process known as reverse geocoding Google Maps in Android supports reverse geocoding via the Geocoder class The Geocoder object converts the latitude and longitude into an address using the getFromLocation() method CIS 470: Mobile App Development
Geocoding and Reverse Geocoding If you know the address of a location but want to know its latitude and longitude, you can do so via geocoding using getFromLocationName() method Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault()); try { List<Address> addresses = geoCoder.getFromLocationName( "empire state building", 5); if (addresses.size() > 0) { LatLng p = new LatLng((int) (addresses.get(0).getLatitude()), (int) (addresses.get(0).getLongitude())); mMap.moveCamera(CameraUpdateFactory.newLatLng(p)); } } catch (IOException e) { e.printStackTrace(); } CIS 470: Mobile App Development
Get Location Data Three means: GPS Cell tower triangulation WiFI In Android, use LocationManager Add permission in manifest To simulate GPS data received by the Android emulator, you use the Location Controls tool on the right-hand side of the emulator After starting the app, observe that the map on the emulator now animates to your current location. This indicates that the application has received the GPS data <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> CIS 470: Mobile App Development
Get Location Data import android.support.v4.app.FragmentActivity;import android.os.Bundle;import android.util.Log;import com.google.android.gms.maps.CameraUpdateFactory;import com.google.android.gms.maps.GoogleMap;import com.google.android.gms.maps.OnMapReadyCallback;import com.google.android.gms.maps.SupportMapFragment;import com.google.android.gms.maps.model.LatLng;import com.google.android.gms.maps.model.MarkerOptions;import android.location.Address;import android.location.Geocoder;import android.widget.Toast;import java.io.IOException;import java.util.Locale;import java.util.List;import android.support.v4.app.ActivityCompat;import android.content.pm.PackageManager;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.content.Context; CIS 470: Mobile App Development
public class MapsActivityextends FragmentActivityimplements OnMapReadyCallback {final private intREQUEST_COURSE_ACCESS = 123;booleanpermissionGranted= false; LocationManagerlm; LocationListenerlocationListener;private GoogleMapmMap;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_maps);SupportMapFragmentmapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map);mapFragment.getMapAsync(this); }@Overridepublic void onMapReady(GoogleMapgoogleMap) {mMap= googleMap;lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);locationListener= new MyLocationListener();if (ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED&& ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_COURSE_ACCESS);return; }else{permissionGranted= true; } CIS 470: Mobile App Development
@Overridepublic void onMapReady(GoogleMapgoogleMap) {// continue from previous slide if(permissionGranted) {lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); }// Add a marker in Sydney and move the cameraLatLngsydney = new LatLng(-34, 151);mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {@Overridepublic void onMapClick(LatLng point) {Log.d("DEBUG","Map clicked [" + point.latitude+ " / " + point.longitude+ "]"); Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());try { List<Address> addresses = geoCoder.getFromLocation(point.latitude,point.longitude,1); String add = "";if (addresses.size() > 0) {for (inti=0; i<addresses.get(0).getMaxAddressLineIndex(); i++) add += addresses.get(0).getAddressLine(i) + "\n"; }Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show(); }catch (IOException e) { e.printStackTrace(); } } }); } CIS 470: Mobile App Development
@Overridepublic void onPause() {super.onPause(); //---remove the location listener---if (ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED&& ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_COURSE_ACCESS);return; }else{permissionGranted= true; }if(permissionGranted) {lm.removeUpdates(locationListener); } }@Overridepublic void onRequestPermissionsResult(intrequestCode, String[] permissions, int[] grantResults) {switch (requestCode) {case REQUEST_COURSE_ACCESS:if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {permissionGranted= true; } else {permissionGranted= false; }break;default:super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } CIS 470: Mobile App Development
private class MyLocationListenerimplements LocationListener {public void onLocationChanged(Location loc) {if (loc != null) {Toast.makeText(getBaseContext(),"Location changed : Lat: " + loc.getLatitude() +" Lng: " + loc.getLongitude(),Toast.LENGTH_SHORT).show();LatLng p = new LatLng( (int) (loc.getLatitude()), (int) (loc.getLongitude()));mMap.moveCamera(CameraUpdateFactory.newLatLng(p));mMap.animateCamera(CameraUpdateFactory.zoomTo(7)); } else {System.out.println("loc is null"); }Toast.makeText(getBaseContext(), "onLocation"+loc, Toast.LENGTH_SHORT).show(); }public void onProviderDisabled(String provider) { }public void onProviderEnabled(String provider) { }public void onStatusChanged(String provider, intstatus, Bundle extras) { } }} CIS 470: Mobile App Development
Monitoring a Location Do something when the user (who carries the Android phone with the app) is getting close to a location using the addProximityAlert() method import android.app.PendingIntent; import android.content.Intent; import android.net.Uri; //---use the LocationManager class to obtain locations data--- lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); //---PendingIntent to launch activity if the user is within some locations--- PendingIntentpendingIntent = PendingIntent.getActivity(this, 0, new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://www.amazon.com")), 0); lm.addProximityAlert(37.422006, -122.084095, 5, -1, pendingIntent); CIS 470: Mobile App Development
Homework#17 Refactor the demo app: Add two buttons for the map view and satellite view Add another button for displaying current location When clicking a location on the map, add a marker and move the camera to that location Add a EditText view and a button such that when you enter a valid address, the camera will move to that location CIS 470: Mobile App Development