name: inverse layout: true class: center, middle, inverse --- # Implementing Location Lauren Bricker CSE 340 Winter 2022 --- layout: false [//]: # (Outline Slide) # Today's Agenda - Administrivia - Lauren out T-F this week (Conference) - Wed OH cancelled - Wed & Friday Lectures Pre-recorded, come to class to work on your final project! - Updates to [Final project spec](/courses/cse340/22wi/assignments/final-project.html) - How to accept the repo with `.gitignore` - Turn in information (all on [Gradescope](https://www.gradescope.com/courses/335435)) - Learning goals - Review of [Sensors](../wk08/sensing.html#3) - Implement location - Time to work on Sensing activity (and turn in screenshot) --- # Do this now If you've already accepted the [sensing exercise](https://gitlab.cs.washington.edu/cse340/exercises/cse340-sensing-and-location), please go into the directory and pull the source code again. There have been changes in the `LocationActivity` to prep for today's in class work. --- # Location - Locations are generally reported as Latitude and Longitude coordinates. - Generally reported using “Global Position System” (GPS) - Can also use cell tower or WiFi localization. - Three ways to do this - [LocationManager](https://stuff.mit.edu/afs/sipb/project/android/docs/training/basics/location/locationmanager.html) - [Fused Location Provider API](https://developers.google.com/location-context/fused-location-provider) - Need to set up [Google Play Services](https://developer.android.com/google/play-services/setup) on the device (including emulators) - Less power consumption - [Google Awareness API](https://developers.google.com/awareness) - Requires Google credits ($$$) --- ## Location: Getting data with LocationManager Declare permissions in `AndroidManifest.xml` ```xml
``` --- ## Location: Getting data with LocationManager `LocationManager` - Main class to access location services - Reference can be obtained by calling ` getSystemService()` in in the `onCreate()` in your `Activity` - Pick a location provider (like `GPS_PROVIDER`) or have the system pick based on criteria such as cost or accuracy. - Check if the provider is available `LocationListener#onLocationChanged` - to get notifications at regular intervals `LocationManager#getLastKnownLocation()` - will get you a snapshot of the last known location `Location` - an actual location --- # LocationManager example ``` Java LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_COARSE); criteria.setCostAllowed(false); String provider = locationManager.getBestProvider(criteria, false); Location location = null; try { location = locationManager.getLastKnownLocation(provider); MyLocationListener mylistener = new MyLocationListener(); if (location != null) { mylistener.onLocationChanged(location); } else { ... } // location updates: at least 1 meter and 500 milli seconds change locationManager.requestLocationUpdates(provider, 500, 1, mylistener); } catch (SecurityException e) { ... } ``` --- ## Location: Getting data with Fused Location Provider - [fused location provider](https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient.html) is another mechanism to get locations - ✅ Faster - ✅ Provides more accurate locations - ❌ Requires Google Play Services installed on your device. - Specify app permissions - Do we need to get the locations in the foreground or background? - Do we want a precise or approximate location? - Create the location services client (a `FusedLocationProviderClient`) and set up a listener to get the location. --- ## Location: Getting data with LocationManager `FusedLocationProviderClient` - Location services client - Reference can be obtained by calling `LocationServices.getFusedLocationProviderClient()` in in the `onCreate()` in your `Activity` `FusedLocationProviderClient#requestLocationUpdates` - to get notifications at regular intervals `FusedLocationProviderClient#getLastKnownLocation()` - will get you a snapshot of the last known location - Need to have an `OnSuccessListener` callback set up. `Location` - an actual location --- ## Location: Getting data with FusedLocationProviderClient First get the `FusedLocationProviderClient` ```java // Initialize Location Services Client for continuous location checking FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(DEFAULT_UPDATE_INTERVAL * 1000); mLocationRequest.setInterval(FAST_UPDATE_INTERVAL * 1000); ``` This will request the location permissions, need to gracefully handle if the user says no --- ## Location: Requestion updates from FusedLocationProviderClient First create a callback to handle the updates: ```java private final LocationCallback mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { List
locationList = locationResult.getLocations(); if (locationList.size() > 0) { // do something with the locations... } } }; ``` --- ## Location: Requestion updates from FusedLocationProviderClient If the user approves location permissions, connect the callback. ```java mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper()); ``` --- ## Location: Stop tracking Location Generally good principle to stop tracking if the app is paused (responding to `onPause`) or the user revokes permissions ```java if (mFusedLocationClient != null) { mFusedLocationClient.removeLocationUpdates(mLocationCallback); ``` --- # Classroom activity .left-column40[ ![:img Location activity solution with a map on the screen, 50%, width](img/location/location-map.png) ] .right-column60[ Add some code in `LocationActivity#displayLocation(Location)` that will get additional information from the Location object and display it on the screen Alternatively add a Map! ] --- # Adding a map using Mapbox [Mapbox](https://www.mapbox.com/) is free to use if your app is under 25,000 monthly active users (no credit card needed to use the service) To use it: * Sign up for an account & verify your email * Create a token for your app * Follow the instructions for [how to install](https://docs.mapbox.com/android/maps/guides/install/) * You may need to upgrade Android studio to 2021.1.1 or higher and the JDK to 11. --- # End of Deck