[MUSIC] A few years ago, my family spent some time in Montreal, Canada. And right as we arrived it began to snow, and snow, and snow. And of course, we quickly found out that my two daughters had forgotten to pack their snowboots. So, we needed to buy boots, and we needed to buy them from a store that was close to us. So I whipped out my mobile phone, and I ran a search for boots in the local area. The application came back with a list of shoe stores plotted on a map. The application also allowed me to get directions from my current location to the stores. We followed those directions, bought some boots and saved our vacation. Now I'm sure many of you could recount similar experiences. Sometimes the information we need depends critically on where we are at the time we need that information. To help out in these situations Android includes support for location and maps. In todays lesson, I'll talk about some of the support. I'll talk about what location information is. And I'll go over the classes that your applications will use to get that information. I'll talk about maps, which allow you to take location information. And display it visually to your users. And I'll finish up by going over the classes that Android provides to let you display and customize Map. So, generally speaking, mobile applications can benefit from being location-aware. That is knowing where they and other things are at a, at a particular moment in time. And so Android allows applications to determine and manipulate location information. Now earlier, I gave an example of using location capabilities to find stores near my current location. And then to get directions from my current location to one of those stores. In addition, applications can also use these capabilities to do things like define a geographical area, or geofence. And then to initiate actions when the user enters, or exits the geofence. Android provides several support classes to make all of this possible. One of those classes is the location class. A location represents a position on the earth. A location instance contains information such as latitude. Longitude, a timestamp, and optionally, an estimated accuracy, altitude, speed, and bearing. Location information comes from LocationProviders and devices can have access to multiple LocationProviders. Now the actual data may come from sources such as GPS satellites, cellphone towers, and WiFi access points. Specifically, applications can request information from the network provider, the GPS provider, and the passive provider. Let's look at each of these one at a time. The network provider determines location based on cell tower and WiFi access points. And if you want to use this provider then you must declare. Either the access_coarse_location permission or the access_fine_location permission. The GPS provider gets its location information from GPS satellites. To use this provider you must declare the ACCESS_FINE_LOCATION permission. The passive provider doesn't actually turn on any devices. It just returns locations that happen to have been calculated through the requests of other application. So using this provider, require that you declare the ACCESS_FINE_LOCATION permission. Now, why you can get location information from each of these different sources, each on offer a different set of trade off with respect to cost. Accuracy, availability and timeliness of the data it provides. Let's look at some of the providers available in Android. The GPS provider relies on communicating with a satellite. And, so, this provider is generally the most expensive, but gives the most accurate readings. It also takes the longest amount of time to provide that very accurate reading. And the user needs to have a clear view of the sky when they're communicating with a GPS satellite. The network provider is cheaper than the GPS provider. But it may give less accurate readings. It takes less time to return location information, but it's only useful when you're in the range of a cell tower or Wi-Fi access point. The passive provider is the cheapest to use. You're essentially just reusing measurements that've already been taken. So it's fast, but it may turn out that there are no recent readings when your application asks for that information. One way to access location information is to use the location manager class. A location manager is a system service for accessing location data. You acquire a reference to the location manager by calling the context classes get system service method, passing in an ID for the service, context.location_service. Once you have a reference to the location manager. You can use it to get and use location information. For instance you can determine the last reading taken by a particular provider. You can register for location updates to find out when new location information is acquired. And you can also register to receive intents. When a device nears or moves away from a given geographic region. If you want to be informed when new locations are determined you can implement and use a location listener. The location listener interface defines the callback methods that are called when location changes. Or when the status of a location provider changes. A location listener interface includes the following methods. onLocationChanged, which gets called when a new location is determined. onProviderDisabled and onProviderEnabled, which are called when a user disables enables a particular provider. And onStatusChanged which is called when a provider's status changes. If your application can't get a recent reading from the system it will then need to acquire its own reading. And to do this, your application will normally perform the following steps. First we'll start listening for updates from location providers by registering a location listener. Next it should maintain an update, a current best estimate as it begins to receive location updates. And as this process unfolds the application should determine when the current best estimate is good enough. And at that point it should stop listening for location updates by unregistering the location listener. And finally it can use that best estimate as the current location. Now when you're determining whether your location is good enough, there are several factors that you might want to consider. For example, for how long should you keep measuring. For instance, a navigation system might need continuous measurement. While a restaurant finder application might just need a single measurement. Another question is how accurate a measurement do you actually need? And again, a navigation system needs to know your location to say within ten meters or so. A restaurant application might just need to know what city you're in and in that case it only needs to know your location to say within a kilometer or maybe even less. And, of course, the choices you make here clearly impact battery usage. The example application is called LocationGetLocation. This application first acquires and displays a la, last known location from all the providers on the device. If these readings are too old, or have too low accuracy. Then application acquires and displays new readings from all the providers on the device. Let's give the application a run. Now I'll start the Location, Get Location application. When the application starts up, it displays the best previous location estimate from the device. This information is then displayed using red text. Since this reading is either not resent enough, or doesn't have enough accuracy, the application goes on to acquire new location estimates. And, you can see that these new readings are displayed using grey text. Let's look at the source code for this application. So here's the application open in the IDE. Now, I'll open up the main activity. And let's scroll down to the on create method. And here, we see that the code acquires a reference to the location manager. Next it calls a method called best, last known location. This method will find the last known location from every location provider, and then we'll return the most accurate of these measurements but also meets certain criteria. If no reading meets those criteria, then the method returns null. Next, the code displays information about the last reading. After this, the code continues by defining a location listener. Again, the listener's on-location change method, the code determines whether the new location is better than the current best estimate. If so, the code then updates the best estimate and then updates the display. Now if the accuracy is less than min_accuracy, then the current location is considered good enough. And so the code unregisters the location listener. Now scrolling down, we see the onResume method. This method checks to see whether the current best estimate is of low accuracy or was taken more than two minutes ago. If so the code registers listeners for both the network provider and for the GPS provider. After that, the code schedules are runnable that will unregister the listeners after a fixed period of time. The code will also unregister the location listener if the activity's on pause method is calm. Here's some tips you can use to save battery power when you're creating location aware applications. First, always check the last known measurement. If that's good enough then there's no need to take new measurements. Return updates as infrequently as possible and limit the total measurement time. Some applications, such as an application that tracks a jogger need to update more frequently. And need to keep measuring while the application is running, because the user's location is changing. Applications like the one we just saw, though, only need a single good measurement. So they can measure infrequently and for less time. Use the least accurate measurement necessary. And only use GPS if you really need to. Turn off the updates in onpause.