Android Studio Tutorial - Build a GPS App
Key Takeaways
Builds a GPS Android app using Android Studio, covering topics such as FusedLocationProviderClient and Google Play services
Full Transcript
Hey, welcome to a series here on Android Studio. We're going to build an application that will demonstrate the GPS features of your phone. So, you can see the app in this condition here. The latitude and longitude is registered, the altitude and the accuracy and the speed and also the address at which you're located. There'll be a few switches here so we can turn the service off, turn it back on, switch it from the less precise to the most precise GPS settings. So, that's just a head. So, in this application, here are some of the things that we're going to learn. We're going to be working with something called a fused location provider client. The fused idea is that there are multiple sources that you can get a location service. So, not just GPS, you can use your Wi-Fi, you can use the towers, and if other applications on your phone are getting location services, your app can piggyback off of their work. In this tutorial, we'll show how to get permissions so that your users do not have to provide the GPS location if they don't want to. We're going to work with a class called location request. And so, this will set the preferences for how accurate and how often you want your GPS service to be tracked. We're going to install the Google Play services and we'll talk about what's required in making this phone application work. Uh this will not work in places like China, but it will work in the rest of the world where Google Play services are allowed. The application will rely on an event listener called on success listener. So, success means successfully located myself. And whenever that happens, we will update the UI or the user interface on the application. We'll set up a method that will start and stop the location tracking service. And then finally, we'll work with geocode, which is the ability to translate an a latitude and longitude coordinate into a postal mailing address, a street address. So, here's a preview of what it's going to look like when we're done. A fused location provider will give us these coordinates and the rest of the data and your ability to control them and how precise they are. So, the first step is to create a layout. So, I don't want to spend a lot of time working on this layout. So, take a Look at what it is here, all the controls and their names. I will provide you with an XML file that you can copy and paste or you can build it on your own. But, the point of this activity is not so much about the user interface as it is the more complex tools that are behind it. So, let's get started with making a new project. I have Android Studio, it looks like version 361 is the current for right now. So, let's get started with a empty activity. So, I'm going to give my application a name, something like GPS tracking demo. So, for my location, I'm going to put in the domain name that I work at. So, I'm at edu.gcu, which is Grand Canyon University, and then the name of my app. So, I'll let the uh build process settle down and then I'm ready to go. So, let's start with the XML activity and I'm going to the uh text view for this. So, where did they put the text view? It seems like they changed it on this version. So, if I go to right click and choose go to XML, I get the XML feed. Now, I'm copying and pasting in all of the code that I'm going to be including in this new version of the app. So, let's see what happens if I click on the view to go back to the uh uh graphical user interface view, I I get this. See, you'll notice that for each of these items here, I have set a specific naming convention. So, SW stands for switch, TV stands for text view. And let's see, is there anything else? It looks like TVs and SWs are the only thing I have in this version. But you can see the constraints are all properly set so that the layout is nice. So you can use my XML file if you like. I'll put it in the comments below. So it would be nice to see all of the UI elements in the code side by side. So instead of switching back and forth between these two tabs, I'm just going to split them. So I'm going to right-click up here and choose split. Let's try vertically. And so you can see that I now have two two windows to work with. So I've got XML on this side and I can switch to Java on this side. So this way I can get all of these references quite quickly. So first of all, I'll put all the text views into place. So I'm going through each item that is not a label. So TV lat, TV lon, altitude, accuracy, speed, sensor, updates, and address are the ones I'm looking for. And I ignore everything that says label. Now just a reminder of what all of these things are, that everything that has a zero in it right now is considered a text view. Everything that just has the word listed over on the left side is considered a label. So we can ignore the labels, they're static. Now the two switches that I'm programming here are the switch for the location updates and also the switch called GPS. The next part is to go inside of the on create method. So remember on create is what's called the first time that this activity is opened. So we need to give all of these variables an actual ID number. And so those ID numbers are found in the XML file. So we're going to let the find view by ID function work for each of these. So remember to do lat, lon, altitude, accuracy, speed, sensor, updates, address, GPS, and the location updates. Uh so this is kind of a tedious process, but you got to go through it to make sure that all of these things work. So this would be a good time to test your app to make sure that we haven't mistyped any of these values. So let's run the app. All right. So if you get the app to run correctly, that's probably a good start. So we can test it out. There is no activity yet, of course. We've just got the controls and their values set up. But if you have a an app crash here, then double check all your work. So all of that is ahead in just a moment. For right now though, let's pause and take a break and we'll be right back. Hey, welcome to part two of our application that we're building called the GPS Tracking Demo. You can see the app on the right. We are going to configure some of the dependencies that are required to make GPS work on your phone. All right. Before we continue on any programming, there's some important facts that we should look at regarding the API that we're about to use. So there are three sources of data that your phone can get its location from. The most obvious one is the GPS satellite location. That's the one that, of course, works from space. Cell tower locations are also accurate. If you have a triangulation system, they can use trigonometry to figure out how far away you are from each tower. And concentric circles are the idea that you can measure distances from three points and triangulate with pretty good accuracy where you might be. Also, Wi-Fi locations can be used since they are known G- GPS locations and you can find locations if you're connected to a Wi-Fi with a fairly good accuracy. All three of these are fused together into a class that we're about to use called the Fused Location Provider. And so, we're going to build that in just a minute. So here's some code that we're about ready to type. We're going to create a Fused Location provider class in our app and it has two different uh functions that are going to be chained together. So, you can see this one called get last location and add on success listener. So, if a location is found, then the success listener will create another trigger to another anonymous function it's called. And so, these nested functions will provide most of the work that our application is going to do. So, fortunately a lot of the class has its uh work done for us. We don't have to determine which of the three services that we want to connect to. We can give it a general idea to say be super accurate or be super conservative with the power and this class will do the work for deciding which service is in action at the moment. So, we're going to be configuring a class called location request in just a minute and we are going to be specifically telling it if we want the priority to be high accuracy and how often we want to get the location updates. So, here is what the code is going to look like. We're going to initiate a location request. We're going to set its interval. We'll set its fastest interval so that way it's if there's no concern about power, we'll update every 5 seconds instead of every 30. And then we'll set it to high accuracy. So, there's different ways that you can configure this and uh you've got them all listed right here in front of you. Also, in just a moment we're going to have to install the Google Play services. So, this will be a dependency in our uh Gradle dependency list. So, what is Google Play services? It's far more than just the Google Play Store or games. As a matter of fact, it's Google's attempt to regain control of an open-source operating system. So, even though it technically anyone in the world can use Android freely, only the um official Google Play services that are installed give you the functions that most phones really require. For example, you want your app to work with Google sign-in, to work with locations, to work with maps, to play games, to work with the instant messaging systems. There's a lot of services that are built into Google Play such as showing ads and doing some security work. If you don't have Google Play services on here, you really don't have a full-functioning Android operating system. And so, it's not available in China due to trade restrictions and the whole business of relationships with governments. And so, if you are building an app that is for the Chinese market, then you probably don't want to rely on Google Play services. Really, the only company that this affects is Huawei. And so, if you want to work with you Huawei, they have an alternative Google Play services and you can see it here at the link below. So, now I need to go find the dependencies that are going to make this GPS service work. So, I just Googled this. It says Android location services and Gradle, which is the dependency manager. And we'll pick the first link. So, about halfway through the list, I find Google location and activity recognition. So, I want to copy this link here. It looks like version 17 is the current. And we're going to put this into our dependency manager. So, I copy this link and switch back into Android Studio. So, the place that I need to put dependencies is in the section called Gradle scripts. Let's open the first one and see what it says. So, this is some dependencies and the note says, "Don't place anything here." Any individual application dependencies belong in the other file. So, let's go to the second file. And here they are. So, the dependencies that we're allowed to add are down here at the bottom of the list. So, I'm going to press enter and paste in the location services 17.0. I can't just paste in some string here. I have to put in the word implementation beforehand. So, I'm going to paste in implementation and then put in the little quotation marks before and after this. And then at the top of the screen it says you must sync. So, I will choose sync now. And let's see what happens. I got a configuration successful. So, that's great. Hopefully, yours worked as well. If not, then you might have to rebuild or clean your project or restart Android Studio. Sometimes that occurs. But, we got a success on mine, so we're going to keep going. Now, let's switch back into main activity. We're going to be able to use a new class. It's going to be called fused location provider client. And you can see that it's providing me some type ahead here. So, I'm going to choose this. And it automatically imported something up here on line number nine. It says it came from uh the Google GMS location service. So, I'm just going to put in the word fused location provider client as the name. So, I'll just put in a note here so it's stresses the importance that the fused location provider client is the heart and soul of this application. The majority of the app's features depend on this. This would be a great time to check to see if the application still works. So, I'm going to click the run button and see if there are any errors with this new class. Hey, it looks like it launched successfully. So, I couldn't ask for anything more than that. So, let's keep going. The next class that I'm going to import is called a location request. So, the location request is a config file, really. It's a class that has lots of properties that will influence the way that the fused location provider works. So, at this point, we're just going to declare that we have a new class a new instance of this class. Now that we've declared it in the top level of our app, we're going to do the initiation down here after we've gotten all of the values of the UI settings. The first two things I'm going to set up are called the set interval. And we're going to set this to 30,000 milliseconds. And then the second item is called set fastest interval. Which means if we are using maximum power and maximum accuracy, how often do we want to update? An alternative to putting 30,000 in here would be to put in a thousand times 30. Just makes it more obvious. Now, just for showing a good programming practice, I'm going to change these values from hard-coded in this part of the function to a constant. So, I will refactor, choose extract, and constant. And both of these can be set at the top of the page then. So, after I've extracted these two, I should be able to find what I put in up here. Yeah, so we've got ourselves the default update interval and the fast update interval is 30 and 5. So, if I have to make any changes later, this is a convenient location to find these values. The next item that I'm going to choose is called set priority. And in set priority, I have to specify location request. And I can see some other constants that are available to me. balanced power accuracy. That's probably what I want to choose. High accuracy and low power and low power are other choices that we can use here. So, so far we've seen several things in this video. We've imported the location request service, and we've done some configuration here. So, in the next video, we're going to configure these buttons here that say location service updates and the GPS and Wi-Fi options. And so, that'll be coming up in the next video. Hi, in this video, we're going to do some more work on our GPS tracking app. This is the third one, and we are going to start configuring these buttons here that allow us to switch from cell phone tower accuracy to the GPS accuracy. And then maybe we'll actually see some events here happen with our location services. So, that's coming right up. So, in this part of the video, we're going to start attacking this button right here that says GPS and save power, which is the ability to switch between the GPS service and the cell phone tower tracking. So, let's put in a click listener for this guy. So, to put in a click listener, we go ahead and type in the name of our switch, which is SW_GPS. And then inside the parentheses of our event listener, we're going to add a new click listener. So, now let's do the code for the inside of our switch. So, we're going to check to see if the switch is checked. So, checked means it's turned on. If that's turned on, then we want to be setting this to use the GPS sensors, or we call that priority high accuracy in the vernacular of this function here. So, we're going to use the constant called location request.priorityhighaccuracy. Then we're going to update the text view called sensor. And sensor tells us which service that we're currently using. And so, we're using GPS sensors. And of course, then else is going to do the opposite to say, "Hey, we're not going to use the high accuracy. We're going to do a balance between power accuracy and the the priority of getting more accurate results." And then we're going to tell it that the sensor is using the towers or Wi-Fi. It's a good time to check to see if it actually works. So, let's turn it on and run it. So, we've got ourselves power and GPS down at the bottom, and you can see that the the label is set correctly, and we hope that inside the internals that the variable is also being set correctly, but we won't know that until we get a few more lines of code. All right, so now we're going to create another method. And uh I just want to mark the end of our on create method here because it's going to get longer and longer here. So, I'm just going to put in a comment. So, the new method is called update GPS, and it does several things. First of all, its goal obviously is to update the GPS location. So, we'll have to ask for permission from the user before we can make this work, and then we'll get the current location from the uh the fused client, and then we'll finally update the UI or the uh text views so that'll display all the values on the screen. So, you can see we're getting closer to actually making this app work. So, the first thing that we have to do is invoke a variable that was declared at the very top of the application. So, it's fused location provider client. Remember, this is the heart and soul of how this application works. So, now we're going to actually assign a value to it. It comes from something called location services. dot, and we're going to get the location provider client, and that is associated with a context. And so, we can either put in the word this or main activity. this. So, the first thing we start with is the permissions issue. So, I'm going to put an if statement to say if the activity compact, that's the that's the class that is our application, if that is going to get a permission check to say were the grant permissions granted for access fine location? That's the if question. Do we have permissions? If we do, then we'll continue on to get those locations. If we don't have permissions, then we need an else statement, and we're going to have to go request those. So, that's some things yet to do. So, let's assume that we have permissions from the user. So, we're going to now call our fused location provider client and use the method called get last location. So, whether that's 5 seconds ago or 30 seconds or 10 hours, we're going to take whatever it has in its memory. And then we're going to use an on success listener. So, we're chaining these things together with dots. And then inside of there, we're going to have another on success listener item. So, this will eventually feed us to a variable called location. So, the location uh variable that you see in this parameter will contain lots of things like latitude and longitude and altitude and speed and the other things. And so, we'll be able to take that location class and update our text views. So, we'll do that in the just a minute. That's still a to-do. So, now let's do the work for getting the permissions. So, first of all, there's a catch here. You have to check to see if the value of your current Android operating system is sufficient. So, we need to be at build number 23 or higher. And so, the build code for 23, as you can see, is the letter M. Now, if we have the correct version of an operating system, then we can go ahead and get the permissions. So, we're going to use the request permissions command. And then request permissions comes in the form of an array, and the first item of the array is the location or the the the type of permission, which is access fine locations. And then we need to provide it some other number. So, we could use a number one or two or three, whatever. We're going to make a constant. We're going to call it permission fine locations. Now, you can see that we have several things that are underlined in red. So, So are errors that we must resolve. So, for the first one to resolve, I forgot to put in SDK underscore int. So build version integer is got to be greater than 23. Okay, my mistake. Then the other record goes away, and then finally this permissions fine is not set. So we need to make this into a constant. So we have an a choice. It says make this a constant. When I make it a constant, it shows up at the top here and we have to provide it a value. So let's create something. I'm going to call it 99. You can use any arbitrary number you want. Well, now we're going to have to have another method here that will actually go and request these permissions. So let's go up to the top of the screen and we're going to override a method that comes with our activity. So finding line number 20, which is our activity. So app compact activity is the base class that where our main activity is based on. So I'm going to right click on it. And I'm going to choose generate. And this time I'm going to choose override methods. Now, there's lots of methods that can go into a main activity as you can see here. So many to choose from. What do we want? So what I'm looking for is the on request permission result. And what that does is it tells the program to trigger a method after permissions have been granted. So let's see what comes in the form of this new method that just showed up here on line 92. So the key part to recognize in the permission request with result is that there's a request code, which is going to be the number 99 that I had assigned earlier. And then the permissions, which is which thing did we actually get permission for, and then the results. All right, so let's get on with the code inside of this function. So, first of all, the uh request code is important. So, there could be many different requests that we've gotten, and we're only interested in number 99. So, in our switch statement, we're going to say check the case for permissions, fine location, or we could type 99. Either one will work. Now, if the request was from that permission, then we are going to update the GPS. So, that's the function that we just got done coding a minute ago. And then, if uh if they didn't give us permission, if they denied them, then we'll just give them a toast message and exit the program. So, let's scroll down to uh where the update GPS function is. So, we didn't do anything here once we got permissions. So, this is a whole bunch of stuff to do. We could code everything right here. We could just update all the text views. However, I'm going to provide this as a a separate function, just to keep things a little bit more compact. So, the new method pops into existence down at the bottom of the list. So, it's rather arbitrary where it goes, but that'll work. And uh I'm going to put in a comment to see what the purpose of this function is, this method. So, we're going to update all of the text view objects with a new location. So, where's the location at? So, what I need is a parameter. So, I'm expecting to get a location from the other function. So, let's uh put in the parameter here, and then go back and patch up the other reference. So, it says you want to do uh update values. So, you're missing something, you're missing a location. Well, do we have a location? Yes, that's what this variable above us gives us. Location is given here. So, location, location, location. Okay, so I'm going to save that. And then, um let's see. I don't see any more errors. So, this is some to-do work that we'll have to come back to in just a moment. But, don't forget that just because we asked for permissions here, uh they're not yet defined. We have to go into our manifest to fix those. So, let's go and look in the manifest. So, I'm just going to type in uses and then magic It seems to know what I want to do. Uses permission. And then the name of the permission we're looking for is access fine location, and then we close the tag off. So, we can close it as you've seen it written here, or I could put in just a {slash} close, and that's a self-closing tag. So, either one of those will work. Okay, so that's the permissions. I probably don't need to see the manifest anymore, so I'll close it. Now, let's just finish off what we're we started here. We're supposed to update the UI values. So, let's go add those now. So, what I'd like to do is set the text for TV lat. So, remember text view latitude is what I'm talking about. And I want to get it from the location. {dot} get latitude. You would think that would work. Well, things aren't always that easy. So, the problem is get latitude is going to return to us an integer, and set text doesn't automatically convert from integer to string. So, I've got to go in here and parse it. So, the way to parse an integer into a string is to use the string method called value of, and we'll surround the integer that we're trying to get. So, I'm going to do two others that are fairly similar, so I'll just copy and paste. So, the second one is get longitude, and so we'll just change a few text items here, and we got longitude. The third one is accuracy. Also is just an integer that we're going to display as a value of how accurate the computer knows its accuracy is. Now, the next item that I'm going to accomplish is the altitude. And it seems like not every phone has the ability to get the altitude. So, we have to check to see if it has an altitude. They actually made a function called has altitude. If it's set to true, then we'll get it. If it's not set to true, it means or it's probably null, then we will just say it's not available. The same kind of thing holds true for speed. If your phone can calculate the speed, then we'll display it. If it is not set, it is not a value, it'll be null, and so we'll just say not available. So, we've got ourselves this final product almost. We've got ourselves the update val- uh UI values, and that was called from this method called update GPS. So, we could have put all of that code in a inside here and up- update values. But, we might want to use that again somewhere else. So, that's why I separated it into a separate function. But, hey, if you want to put it all together, it'll still work. Now, we got to use this function. So, I've created the update GPS, but have we actually called it anywhere? I don't think so. So, a good place to call that would be right at the end of our on create method because everything's been set. Now, we're ready to do update GPS. So, I'm going to save this, and let's see if it'll work. I'm going to run it. All right, so you should get permissions to show up. I've already run mine once, and so they're not there. Uh but I di- I did give it permissions. And you can see I have a GPS location here. So, this is the the default location that is found in the settings of my virtual phone. If you put this on a real phone, you'll get the location where you're at. And so, it appears that mine's working. So, location updates on off is not doing anything yet. We still got that to go. The second switch is theoretically working. However, I really can't test it on this phone because it's a virtual phone. But, that your real phone, you can check this out. So, we've got ourselves a one-time update. It is just checking when the app launches. That's pretty good, but we want to have the app to be able to turn this service on and off, which is this switch. And we also want to be able to track this as it's turned on, so every 30 seconds or every 5 seconds. And so, that's still some work to go, but we'll fix that in the next video. So, stick around and we'll refine our application to be even more useful than it is now. Hi, welcome to part four of our GPS tracking demo. You can see the app on the screen has got a GPS location. In this video, we're going to be able to turn this service on, turn it off, and to be able to configure how often it runs. And so, we've still got some refining to do, but we'll finish this up in just a moment. All right, so we have to go and program this button here that is the turn on and turn off. So, that's a click listener. Let's go into our code and see if we can put that in our our on on create method. So, we'll create a click listener. And then inside there, we'll add a new anonymous function or an inline function called on click listener. So, when the on click item occurs, we will ask the question, is this check switch checked? If it's checked, then we want it turned on. If it's not checked, if it's turned off, then of course, turn off tracking. So, I'm going to once again create helper functions. So, in this function, I'm going to say, let's let's make a new one called start location updates, which will turn on a bunch of things. And then, we'll also have the equivalent turn off thing, so we'll stop location updates. So, we got to create these functions separately. So, let's go and see if we can get some code helping. I'll click on the first item and we'll choose generate a new method and we'll put it in the main activity and we'll do the same thing for the stop location updates. So, we should see two new methods in our program. So, let's make this obvious. Let's put in a statement to say update at one of the text views. It's called TV updates. And its status is to say, "Hey, we're being tracked or we're not being tracked." So, we'll put that in. That doesn't actually change anything. It just tells the user what's going on. Now, the second statement in this method should be called fused location update client dot and then we're going to request location updates. And this method requires three parameters. First of all, it says "Give me your location request." Remember, that's all of the parameters such as how often this is occurring and how accurate it should be. So, we defined that a long time ago. The second item is called a location callback and we have not created this yet. This is going to be yet another method that will trigger every time this location changes. And then the third thing is called a looper variable. And uh honestly, we're just going to put the word null in and I got that from the the instructions in the guide of how this is supposed to happen. So, this might be a good time to show you where some of this information that I'm putting on the screen is coming from. So, I'm getting this from the uh Google documentation and their tutorials. So, you can see that I'm at the page that says we're looking at get the last known location. Let's see if we've done any of this already. So, it says, "You must uh specify your app permissions." And sure enough, we did that right here. We accessed uh They told us to use coarse location. I used fine, but uh mine's a little more accurate than theirs. Then we've got ourselves a on create. We created a location service. So, we did that a while ago. We had this same function called get the last known location. So, so far, so good. Of course, that's just part of their instructions. Let's click on the next and let's see what comes up. So, this says how to configure your location settings. Let's see what they've got. They said, "Oh, don't forget to ask for permissions." And then down here, it says set up a location request. And if you look at the code here, this should look familiar. We created things that look like this here. We have ours is 30,000, which is 30 seconds, or 5,000 for the most accurate. And so, we've got one of these things already configured. So, so far, so good. So, here's another page that now we're going to get some information from that'll help us. So, we're going to get the location updates. So, not just when we launch the app, but every period of time. So, it says here, "Make sure that you got permissions." That seems to be a theme in their locations. Okay, then we have a location request. So, let's let's take a look here what they're asking us to make. So, create something called a location callback. And then, when you have that going, we're going to have a function that goes inside there. So, we're going to kind of use this as their model. So, let's return to our code, and we need to make a location callback. So, that has to be declared somewhere. Let's go to the top of our app, and let's put it in here in the list of things that are kind of global to our app. So, now inside of the on create method, we're going to create a new method that is configured here. So, that is the location callback. It is a new location callback. And I'll put in some notes here that say that this event is triggered whenever the update interval is met. So, this is 5 seconds or 30 seconds in our case. So, let's see what's available that we can do inside of the location callback. So, I'm going to click on the name, right click it, choose generate, and override methods. So, this will tell me everything that you can do inside of here. The two at the top are the ones that are interesting to me. So, on location result is the one that we're going to implement and location availability would probably tell you whether or not this is actually working. So, I'm going to just choose the first one. There it is. So, now we have on location result. And we should get the location results right here in this variable. So, now I'm going to treat this location result as a new value that we can update our app with. And so, I'm going to save it in a variable called location. And then I'm going to pass that on to the update UI values method. So, that will just redisplay all the newest values. Now, if you look at this, you're going to say, "Hey, why did you save that as a separate variable in location? You could have just called it inside of the parentheses." Certainly could have. So, let's see if we can make this code a little bit shorter. So, I'm going to copy this and overwrite location. And then we can delete this entire thing. So, we could make it down to one line. Whichever you like. All right. So, that should work. Let's go look at one more case when we had the we asked to turn off the GPS tracking. So, we should update a few things here. So, this part of the program here is to stop the location updates. And so, we're going to set the all the properties of all the text values to show location is not being tracked. So, that is for the latitude, the longitude, the speed, the address, the accuracy, the altitude, and even the sensor. And finally, at the very end, we're going to say fused location provider. Remove location updates. So, this is going to say, "Hey, no longer are we interested in doing the location callback functions." So, take that out. Oh my goodness, I'm looking at my program and I did it exactly the opposite way that I intended to. You notice here? This is called stop location updates and this one's called start. And the code inside is totally the opposite. So, oh my goodness. How could I be so dumb? Let's Let's copy this out of here and put it down below. And then copy this and replace the stuff that's up above. And let's see. Then we can delete this here. So, I think that's a little bit better. Okay, so stopping says no no tracking, starting says yes, we are being tracked and then we should update the GPS. Oh my goodness. Well, let's see if that works. All right, it looks like it's running. So, we have a GPS location and let's check this switch that says, "Hey, nothing's working." So, all they all go back. We'll turn it back on and we got more locations. So, we have one more part that's not seems to be working here. It says the address. And so, maybe we'll leave that for the next video, but that will be to check to see what's the street address is based on these locations above here. So, we'll come up for that in a moment. Hi. In this video, we're going to update our GPS tracking demo to include the address of a location. So, right now, we don't have a street address. By the end of this, you will. So, the key to make this address thing work is we're going to use a service provided by Google, which will automatically translate things for us. It's quite simple, actually. So, I'm going to embed a little more code inside of this section called update UI value. So, what we're going to include now is called the geocoder. So, it's a class that's provided to us in Android. So, geocoder is a new geocoder and it needs some kind of a context. So, let's put in main activity.this. Now, this isn't guaranteed to work. So, we're going to have to insert a try and a catch. So, if there's an error, our program won't crash at least. So, the geocoder is going to provide us theoretically with a list of most recently seen addresses. And so, we're going to define a list of type address. So, we're going to do location. And we have to provide it a location. So, we know a location. It's in the location variable. And we'll do get latitude and get longitude. And you can see that the parameter is asking for the maximum results and we only care about one, the most recent one. So, we'll get one. Now, I've never actually been able to get more than one address. So, I'm not quite sure how the geolocator actually provides a list of things. But anyway, I only care about the one that was most recently seen. So, then the next job is to provide a text update. So, we have a text view called address and we'll set the text. So, we'll get the address number zero. So, the first one in the list. So, that's item zero. And then, as you can see that there are lots of pieces to that address. So, we could get the county, the city, we could get the zip code, we could get all those things. For right now, I'm just going to get the street address. But go ahead and experiment with the others if you want to add more than just the address line. If for some reason this whole thing fails, I'll just say set text and we'll point to the user to say, "Hey, didn't work." Now, we could do the capture of the exception and send it off to another level, but let's leave this as a simple app. Let's see what happens when I run it now. So, you can see that I have the same GPS coordinates, the latitude and longitude, but the location is actually found in Seattle. Now, you can guess I'm probably not in Seattle right now. I teach at Grand Canyon University here in Phoenix, Arizona. So, if you want to adjust your virtual phone to go somewhere else, you can. There's a settings button down here. There's three dots here, and it allows you to adjust. So, Seattle, as you can see, is the default location. If I want to search for somewhere else, let's go to London, and let's go to UK. So, we're in downtown London somewhere. Let's save the point and click okay. So, I have this other point. Now, I'm going to choose set location. So, that will, supposedly, set the location inside of my phone. So, do I have to wait for it to update? Let's see if I change the number of seconds that it's being updated at. Uh let's see if that does anything. Let's turn it off and start again. And there it is. Okay, so now I got a new location. So, try it on your real phone. You'll probably get better results than a virtual phone. But, you can move around the world at light speed if you want to, using your virtual phone. Okay, so that gives us a pretty good starting point for building any kind of a GPS application. So, this will save a location. Now, think about how you would build a real app. You might have a list of recent locations. We'll do another tutorial that will actually put up a map on the screen, and you can show the locations and save them as you go. So, you could likely breadcrumbs. So, and more to come, but for right now, this will get you to the basics of how to get this fused location service working and to get permissions. So, I hope you had fun. This will be another tutorial in the coming minutes here about working with more GPS apps. In this tutorial, we're going to extend a an existing application, and we're going to show maps. So, in a previous version of this GPS application, we had an ability to capture all of these attributes of our location. We were able to turn off and turn on the location updates, set the settings for precision, so it could use GPS or the Wi-Fi towers. In this version of the application, we are going to have the ability to show a list of all of the places that we visited, and then we're going to be able to show a map that will point a pinpoint where each of those locations is. And then finally, we have a button at the bottom that says drop breadcrumb, which means wherever the current location is, we're going to add a new pin to the map and a new item to the list. And so, that's what we're going to do in the next few videos. Now, if you haven't already completed this application as the GPS demo, then you need to back up and there were like five different videos that will show you how to create this. So, we're on video number six right now. So, I'm transitioning back to the version of the application that was at the end of last tutorial. So, at this version, we just had latitude, longitude, speed, accuracy, and the address. We were able to turn on and turn off all of the different options. And so now, we're going to add those abilities to have the list of things that we've breadcrumbed, and also have a list on our map with pinpoints. So, that's what we're going to start with now. So, step one here is I'm going to show you how to add a global address list, so that way every activity in the in the program can see the list. So, what we need to do is extend the application class and make a place where we can put global variables. So, let's add that class now. So, I'm going to switch over to the folders where we have all of our Java applications. And uh let's see, what I'm looking for is where we have our main activity. Yeah, so this is the place This is the folder that I'm looking for. So, I'm going to right-click and add a new Java class. And we're going to call this thing my application. So, I'm going to extend the superclass as application, which is going to allow us to do choose this global list. So, you'll see how this works in a minute. Okay, so you can see that I'm using GitHub, so I'm getting this error that says, "Hey, you just added something. Do you want to add it to your repository?" You might not see that. All right, so here is our new class. We have main activity, which is what we've been working on, and now we have my application. So, my application extends the application class. The first thing we have to do is set this up as a singleton. A singleton means that there's only one instance allowed, and we can create the instance the first time we call this object, but after that, we're going to make sure that there is only one. So, a singleton is a is a standard kind of programming method. So, if you Google it, you'll find other examples in other languages. But, we need to have a proper or method called get instance. And then we're going to assign it this this property called singleton, which is instance of itself, my application. Then, if we go to the on create method, so when this thing is first made, we are going to refer to the singleton as this, which is this class. So, this here is the properties for a singleton. Now, after we have the singleton created, we can add some variables that will be treated as singleton variables. Again, they will be kind of like globals. Now, the global list that we're interested in maintaining here is a list of locations. So, you remember from the previous view of this app, we're going to have a list of locations or location breadcrumbs. And so, the list type that we're looking for is of type location. So, we'll just name it my locations. Then we're going to generate getters and setters, so that way we can get the list, and we can set the list, or we can add items to it. But, the point is that this list will be a single source of where we've been, where we dropped our breadcrumbs. So, one activity can see this as well as another. Now, we have to make sure that this list is initialized, so the on create method seems to be the right place for this. We will create a new array list, and it can be empty. So, at least it's not null. So, let's return to the main activity, and we're going to add a new button called drop breadcrumbs. So, let's come into here where the all the controls are, and let's put in a couple of text items and then a button. So, first of all, I'm going to put in a label and then a text view that will count the number of breadcrumbs that we've dropped. So, we could call these breadcrumbs or waypoints. They're kind of used interchangeably here. So, the first one is a label. So, I'm just going to call this text as waypoints, and we're going to set the constraints that it'll fit here below the sensor, and it'll stick to the left side of the screen. Then the next text view will actually be the number of waypoints that we're going to collect or count. And so, this guy here will have the text of zero, and we'll make sure that it's uh constraints are stuck to the top of the uh previous label and right to the edge of it. So, now we've got ourselves two labels, or we've got two text views. One's a label, and one's a number zero. So, what what are you going to do with those? Well, now we're going to count the number of items that we've dropped as breadcrumbs. Well, now we need to create that button so we can do the dropping. So, I'm going to drag a new button in. So, this next new button that we're going to put is called the new waypoint button. So, let's set the constraints so that way it is just below the label and the number that we've we've created. Let's set the width so that it extends to the left and to the right of the screen, and the constraints will make it the full width. Then for the button name, of course, let's create a button that's called the uh new waypoint. That'll be a good ID for the button, and that'll also be good text. Let's create another button below that and we'll call that show waypoint list. So once again, we'll set the constraints so that it fills up the entire width of the screen and fits nicely below the previous button. And then a good name for the idea on this button should be like show waypoint list and that could be a good name for the text as well. All right. So now we've got ourselves two buttons. One of them is new waypoint and that will save the current location into the list and the second one is show the waypoint list and we'll probably get to that one in the next video. But now we want to start programming these buttons. So the new waypoint button is our first target. So let's go into the main activity and start doing the code. So main activity needs to have a reference to this. So let's get to the top of the screen where you have the references. So I'm going to add two new button variables here. The first one is for the waypoint. So new waypoint is the ID that I used and the second one is show waypoint list and both of these have the prefix of BTN. In the on create method for this activity, we need to then assign these values to the variables. So we'll use find view by ID for each of these guys, assign them and so that now the button variables have been configured and initialized correctly. So now let's go ahead and program the button listener for this button. So we will do the set on click listener and we will add a new button click listener. Inside the method called on click, let's put some comments to see what we're up to. So first of all, we're going to get the GPS location, the current thing that we're talking about and then we're going to add that to a global list. So really that's the focus of this video here is we're trying to capture a list of items called breadcrumbs or waypoints. Now I want to create two class level level variables. So, let's scroll up to the top here. And the first one that I'm going to create is a variable, we'll call it current location. And so, we'll update this variable every time the GPS is updated from the uh callback methods. So, this will be an easy accessible um variable that all activities can get to. Then, we will have a list of saved locations. So, this will be a list and it'll be a type location. And the uh saved locations is a good name for it. Now, you're wondering, what is this location thing again? This is the class that is used by Android um maps and GPS. A location contains a bunch of things, the latitude, the longitude, the altitude, the speed if it's available. And so, it's a class that contains a lot of information about a GPS point. All right. So, where would be a good place to update this thing called current location? Well, I think there was a callback method that we created in the previous videos. And let's see if we can find it. So, down below, way down here, we have update GPS. And this looks like the thing. So, this function here, or this method called update GPS, has the listener in it. So, we have the uh get last location going on here. And let's go see if we can put this into our uh current location. So, we're doing update UI values. Let's also put the current location here as this value called location with a lowercase L. So, this guy here is the current location. So, let's just save him to a a variable that's further out. All right. So, let's go find the uh click button that we were already programming earlier. This is the new waypoint. So, in the comments, in the on click, it says get the GPS location. So, there should be one in that variable called uh current location. Then, the second is add it to the global list. So, this might look a little strange, but we're going to try to get access to this global class called my application. So, let's create a reference to it. And then, all we have to do to get this variable uh assign the value is to call get application context and cast it to my application. All right. So, that should provide an access to that class. Now, if I want to do the saved locations, I'm going to be able to get that from my application, and we should say there is a getter in that class, get my locations. Perfect. Okay. So, saved locations now is the little global list. Now, the last step is to take the saved locations, and we're going to add an item to it, which is the current location. All right. So, we have this global list of locations, and when we click the button, uh we're going to add a new item to it. Now, this will still cause an error. We have to do one more step that I'll have to uh show you in a minute. We have to change something in our manifest. But, the uh the general idea should work. Now, I'm going to borrow these uh two lines here and reuse them in the UI. So, let's go down to the class that says uh where we're going to update the UI values, right? So, in this location, I'm trying to update the uh number of items in the list of waypoints. So, I need to add a text view, and what was it called? Waypoints count or something? Doesn't look like I've added that yet. So, let's let's go back and fix that problem. So, I got to go to the very top here and add another reference to an item in my layout. So, I forgot to do that earlier. So, let's go to to text view items, and let's call this thing way point counts. Uh don't I don't know if that's the actual name for it, but we can use that. And then down here in the list of assignments, we can do this text view way point counts. Okay, I called it count of crumbs. That's the actual name. So, we'll use that. Count of crumbs. Okay. Now, let's go back down to the area where we're doing the updates on the UI. So, near the end of the program. So, what did I want to do? I wanted to say way point counts and set the text. So, the goal here is to show the number of items that are in my list. So, let's do the uh uh saved locations.size. And don't forget that we have to convert this into a string, so I'm going to use the integer.toString method and then we should have an actual string that we can assign to the text. So, that should update the UI. All right, so I told you there was one more thing that I have to fix. So, I'm going to run the program and it should crash. All right, just as I predicted, the application crashed. Let's go look at the log cat and see if we can understand where the error is because for sure you're going to see one of these items when it comes your way if you're using this global class. All right, so I got way too much stuff here. I'm just going to click on the trash can and let's see I'll re- relaunch the app and maybe we can get a message that I can find here. Okay, so we got the app running again and it crashed the second time. Now, here is the error. It says application cannot be cast to this thing called my application. So, there it is on line 262. This thing here doesn't work. Now, I promised you it would and let's see if there is any helpful hints on it. All right, so there are no helpful hints to know what you're supposed to do here. But I'll tell you what what the problem is. Let's go into the manifest as I promised. And what we need to do is we need to give the application a name. So let's go into the properties and we're going to call this thing name at Android colon name. And there it is. It's suggesting my application. There it is. That's the problem. Isn't that a weird kind of a thing, but anyway, that will cause the error to disappear. And let's see if we can get the app up and running now. Okay, there we go. So the uh location is right now at building 84. There are zero waypoints. Let's choose new waypoint. And let's see the uh UI has not been updated. So let's just shut this off and turn it back on and there we go. One waypoint. Let's do another one. So every time the app updates and gets a new location, the UI should also update. So I think that happens about every 30 seconds right now. So I'm don't want to wait 30 seconds, so I'm just going to shut it off, retrigger it. Okay, so we got two waypoints. Now in the next video, we're going to show that list. And then the video after that, we're going to create a new button and we'll show them on a map. So we're getting closer. So what we got here was the ability to save a waypoint in a global list. We'll see you in a minute in the next video. Hey, welcome back to another Android video for GPS. We're in the middle of a process of creating an application that does GPS tracking and a demo. So we created this waypoint button in the last video, which allows us to add a new waypoint. And so you can see that now we have three waypoints. Now in this video, we're going to do show waypoint list and that will show all of the items that we've saved. All right, so let's get to this point here where we can make this button active and show the list. So, let's do a intent. We'll make a listener on this button and create an intent to go to a new page. So, I might as well stop the app here and let's go and create that new page first of all. So, let's go into the folder where our Java stuff is. I'm going all the way down to activity and let's choose an empty activity. So, empty means, you know, obviously we can start from scratch. So, I'll try to name this as well as possible so it says show saved locations list. And that should give us a pretty good description of what its job is. So, show saved locations list is going to be very simple. Let's go to its layout and then we're going to add only one item. We're just going to add a list view. So, here it is. We've got an empty screen. And I'm going into the legacy area and choosing list view. Dragging that out. Let's just change the ID here. Let's just call it LV_waypoints so we know what what's in there. All right, so let's just leave that alone. And I think we should probably do the constraints. So, let's see if we can pin that to the top. And let's pin it to the side and to the right side. Now, I'm going to intentionally leave no constraint at the bottom so it can fall off the edge of the screen because it's going to be scrollable. All right, so that is the entire layout. It's going to be the simplest thing possible and the only way to to return to the main screen is to click the back arrow. So, we don't have to create a button to go back. But, we do have to create a button to get here. So, let's go back to our main activity and let's add some items to this button here. We're going to make this thing a new button listener. So, show waypoint list is the ID number. Let's go program it. So, back into main activity and let's go find a good place to put this. So, I'm thinking near the top of the screen is probably a good location. So, let's go and add our new button listener. So, button show waypoint list is the name and we will set a click listener on it and add a new click listener. Now, inside of on click, we're going to have a simple program. We're going to say give me an intent to go to another screen. So, this intent should be pretty simple. As you might remember from previous lessons, an intent needs a couple of things. It needs to have the context. So, the context is coming from main activity. that this and then it has to have the name of the class that we're trying to show. And so, the class name is show saved locations list. We just created that a second ago. And then we just have to tell it to start the activity. We don't have to send any data. We're using a global lists that we've saved and we're going to access that in a minute. All right, so there we go. We got ourselves the button listener. Let's see if it works. And if it works, then we can start programming the list. All right, it looks like we got ourselves the application running. Let's save a waypoint. Let's do a show the list and see if this works. All right, so it shows an empty list and I can return to the main program. So far, so good. Now, when we go to this list here, let's actually populate it with the items that we've saved. So, as we did in a previous video, we're going to have a global access to this list. So, I need to get a reference to my application. So, my application comes from this function called get application context and then we cast it into this class called my app. Then, once we have that, we can get the saved locations using the getter. So, get my locations. Remember, this is a static class or this is a singleton, so that way we can get it from anywhere in the application. Now the next thing we're trying to do is add this list to the list view that's supposed to be on this page. So let's create some variables to access the list view. So let's create a variable at the top level and we'll call it lv_savedlocations. That might or might not be the exact name I used in the layout. Then in the on create area, we're going to go find this item in the view or find view by ID. And it looks like I called it lv_waypoints. So the names don't match exactly, but they'll still function correctly. So now all we have to do is connect our list called saved locations to the list view. And the absolute simplest way to do this is with what's called a simple list adapter. And it's not fancy, but it is all we need for right now. If you want to create a more fancy version with graphics and everything, go see another tutorial on creating a custom list adapter. So then what are the parameters inside of this array adapter? There are three of them. The first one is the context. So the context is just the reference to this activity. So I'll just call it this. And then the second item is what layout or what type of adapter are you using? So I'm going to choose a predefined one. And you can find this in android.r.layout. And you can see there are multiple different types of layouts that are predefined for us. Now the one I'm going to choose is the only one that I actually have any experience with is simple list item one. And it will take whatever object you're doing and make a two string out of it. So it's not fancy, but it will show the data. Now the last item in the list is the list itself. So saved locations is what we're looking for. So that should assign all of the items in saved locations to this list. Let's run the app again and let's see if it works. Okay, looks like the app is up and running. I'm going to choose new waypoint, and then show the waypoint list. And sure enough, you can see that there is a location that is there. Let's go back and add another waypoint, and choose show the list. So, we can see one there, and one there. So, there are two now. So, we've got ourselves a successful list. Now, as you could have probably argue, this is a very useless list. What can I tell from it? All I can tell is that I have a whole bunch of data that relates to a GPS location. I have latitude and longitude. The point is that I now can see which waypoints I've saved. Now, in the next video, instead of showing a list, we're going to put these on a map. And that will be a whole lot more graphical and understandable. But for right now, we've got ourselves the goal that we met here of adding this button called show waypoint list, and that's exactly what it does. So, we'll see in the next video, where we create a map and show all the pins on the map. Hey, welcome back to another in our series on our GPS tracking demo. In this video, we're going to add a new button that says show map, and it will show all of the waypoints that we've saved, and put them as pins on a Google map. So, let's get started right away by putting a button on this screen, and then we'll create a new activity that will have the map. So, let's get into our main activity area, and let's go ahead and add this new button. So, this is a pretty standard button. We're going to put the anchor points in, so that it falls next in line. So, there'll be three buttons in a row. Then, let's set an ID called button show map, with the constraints, of course, and let's do the full width of the screen, and then for the text, let's put in show map. Now, let's go into main activity and program this. So, we need to give a reference to it at the top of the screen and then program it. So, here we go with a reference. So, after the reference variable is defined at the top, then we need to give it a value in the on create method. We've got a whole list of things that are already being created. And so, let's choose a new one, find view by ID, and it looks like BTN show map is the correct value from the layout. So, now we've got ourselves a reference to the button. Now, we have another button that's almost doing the exact same thing that this one is, the show waypoint. This one here. So, we're going to use this as a model. So, let's go ahead and add a new button listener. So, all the code will look pretty much like we did on the previous function. So, we're going to have a set on click listener, a new click listener. We're going to put inside an intent in there. So, the intent is going to say what is the context, which is main activity. this. And then we have a problem because we don't have the new activity that we're trying to get to yet. So, this is supposed to be called maps or something like that. But, we'll have to leave it blank and we'll go create the map and then we'll come back and finish off this button click listener. All right, so let's create the map. So, we are going to have to leave this little error and it says that we're expecting an expression. So, let's go create the name of the class that will actually get to in a minute. So, let's go up to the Java folder, right click, and we're going to add a new activity this time. And let's go to the gallery. Let's see what's in our gallery. So, you can guess that we're going to do an Android maps activity. Let's choose next. We'll just leave it as maps activity as a good enough name and finish. Okay, so we got this map activity going. And it says here we've got some to-do's before we can get anywhere anywhere close to using the maps. So, it says you need to have a Google Maps API key. So, you have to register your application with Google in order to make it work. Well, they make it so simple. They have this link here. You just copy the link and bring it into your browser. So, let's bring up a new browser here and paste that link. And let's see what comes up. So, we're going to have a registration process. So, if you don't have a Google account uh you don't have Gmail, well, you have to get something like that. So, we have uh create a project here is our option and let's just choose continue. And this will register a key name for us that we can copy and put into our project. So, if you have to go through the registration process of setting up a Google API, that's another issue. But, um you're trying to get to this screen here. All right. So, it says your API is enabled. Create the API key. And uh let's see what comes up. Oh, perfect. Okay, so now I have an API key. I'm going to copy that. So, there's a little copy icon. And now I'll just switch back into my application. So, I'm switching back and now it says this place called your key here. So, I'm just going to paste that. Now, your key is going to be different than mine. So, obviously, don't use the one that I'm using on the screen cuz it'll probably go away. All right. So, we got this first step involved. We got an API key created. Now, we're ready to go ahead and do some programming. Well, where is this uh new class? It's called Maps Activity. And they've already given us some code. How nice. Tells us that we have an on create method. And we've got ourselves a sample of this uh function here. They've put some data in for us. And they've added Sydney. Isn't that nice? So, Sydney is located at -34.151 on the uh GPS coordinates. That's the latitude and longitude. So, there is a class called lat long. Okay? And they put a marker on this thing called marker in Sydney, and then they and they move the camera. Let's see if this actually does anything. So, let's go back into main activity. And now we can add the reference to our new guy. So, it was called maps maps activity. Come on. Maps activity.dot.class. All right. So, now the intent seems to be happy. Let's see if we can get to our new map and see what Sydney looks like on the map. Okay, the app is up and running. Let's just go straight to the show map button. And there it is. We have a map. And sure enough, it looks like Sydney. So, I'm going to try to zoom in as best I can with this emulator. It's a little bit odd. Now, we're going to instead of putting Sydney on the map, we're going to put the points on that we've plotted using our GPS tracker. So, let's go do that next. So, let's go back into our map program. So, maps activity. And instead of showing the marker here for Sydney and for this guy, let's just comment them out because we might want to see them as an example, but we want to use our own. So, the first thing I want to do is create a variable called saved locations. Let's put it at the very top as a class variable. And we can assign and read from that as we need to. So, we got saved locations as type list. Then, let's go into the on create method and let's go and assign that to the global list that we've been working with. So, we're going to create two lines that will get us access to that list. So, my application is the first variable we need to create. And we get that from our get application context command. Then, the next line down is we're going to do saved locations equals and we will get the locations from the global list. So now saved location should have data in it. Now once we have saved locations, we can go ahead and add them to our map. So now I'd like to create a for each loop and go through the items in the saved locations. So when I type for each, um, the IDE helps me out with some code typing. So it looks like in Java we have to do a colon. And that's how the for each loop works. So we have for the first item is the counter variable or the each variable. So it's type location is what we're expecting. And then the list is after the colon. So it's saved locations. Now I'm going to look at the example that we used for Sydney. So Sydney used a type called lat long. And so that's what we're going to create as well. So we'll create a new lat long variable. And it is going to need the GPS locations from our location item. So location.getLatitude, location.getLongitude will give us exactly what we want. So now I'm going to create a new map marker. And let's take a look back at what they gave us for the Sydney example. So we're going to we're eventually going to call add marker. That's the name of the function. But inside the parentheses you can see that there is a variable called marker options. So let's create a new marker options to start with. And the marker options allow us to create a position property. So marker options. position and we have the lat long available. Now I'd also like to add a title to it. Instead of saying the marker in Sydney for the text, I'm going to create a new text and we have the lat and long so I'm just going to use that as the title. So that way when we show the variable or when we show the pin on the map, it'll show us the location and um we we could have put some other thing in there but this works as well as anything for a title. Finally, we do the map, mmap, and add the marker. And so this should add a new item to the list. Let's go ahead and launch this and see if it works. We might have to refine it, but I think this will work. Okay, the app is up and running. And uh we're let's going to add a new waypoint. And then let's go show the map. So, the map shows up. And we have Do we have a waypoint? There it is. It looks to me like it is in Arizona, which makes sense. That's where Grand Canyon University is. Now, let's uh let's go back here. And let's add another location. So, as you recall, we can set our location uh on the GPS for our phone emulator to any place we want. So, let's let's go ahead and put in something in London. And let's see what happens if we save a point here. And I'm going to call this thing London. So, then I got London in my list and I'm going to set the location. All right. So, it's just like my phone went at light speed and is on the other side of the world now. So, if I turn the GPS off and on, uh it still says Grand Canyon University. That's not what I meant. So, let's go and use this, set the location, come back. And let's see what happens here. Do we have Do we have a new location at London? Okay, let's turn this off, turn it back on. Let's see if we can get this to save. So, in a real phone, this actually works better. So, let's go and look at the list. And you can see now the last item in the list is a different location. So, that that looks good. Now, let's go look at the map. And we should see something up there's one tagged in London. And there's something over here in Arizona. So, yes, we do have two locations now. And the list seems to be working. So, this is a lot more fun with a real phone. If you go out and you follow your phone around, you can track and place little breadcrumbs where you've been. And so this gives you an idea of how to track and put a pin on an item on your map. Now we're going to make another video that will show us how to click those buttons on the map and we could create some interaction with the map as well. But for right now, we got ourselves a map that shows our list. So that's good progress. One more video and we will show a little bit more interactivity. See you soon. Hey, welcome back to another video in our Android app with GPS. In this video, we're going to take our map and make it a little bit interactive. So when we show the map of where we've placed our pins, if I click a pin, we can actually do something with it. I'll show you how to make interaction. Okay, so this should be a pretty quick video. It's not really that complex of what we have to do. So the activity that we're going to work on is the maps activity and we are going to program inside of the just the Java code. All right, so let's let's do two things here. We're going to do a zoom in on the last pin that was dropped and then we're also going to add the ability to click on those pins. So let's come in to the place where we're putting the pins on the map. That was on the map ready. So I'm going to have a new variable and we'll call that the last location. So this variable that I'm going to assign is called last location placed. And for the initial value, we'll just set it to whatever Sydney was. And then after we've got this defined, I'm going to redefine it inside the loop. So the last location placed is going to be important because it's where we're going to zoom in on the map. And so every time we place an item in our for loop, I'm going to update the last location placed as lat long, which is exactly this one point. All right, so when I get to the end of the loop outside of of little curly bracket, I want to zoom in on that last location. So, the method to do that is called animate camera. As you can see, there's several options for animate camera. So, I'm just going to choose animate camera. Now, inside of there, I need to have something to actually configure that. So, the item that I'm looking for is called a camera update factory, okay? So, it's a factory design pattern. Go look up factory design patterns if you want to know what that's all about. And then, if you look at the uh options here, I have the first one called the new lat long zoom. And you can see that the parameter says I can have a lat, a long, and then a float value. So, the float value is the zoom value. So, the lat long value is pretty easy. I have that already decided. All right. So, the parameters I'm looking for inside of the new lat long zoom is the last location that was placed. So, that's the coordinates that we're going to. And then, a zoom value. I think you can go from anywhere from like two to 20 or some range like that. So, I'm going to pick a medium zoom, like 12. And I have to make sure that it's in a float float value, so let's put a 12f. This might be a good place for a constant value, but let's just put in 12 for now. Okay, I'm going to relaunch the app and see if it'll zoom in on the last location that I clicked. Okay, the app is up and running. I'll show my waypoint list. And it should show empty. Okay, so I don't have any items. Let's add a new waypoint. And let's see if it's in the list. Sure enough, we have something. I think that's London. That's what it says here anyway, right here in Trafalgar Square. And now, let's go show the map. So, it brings up the map, and sure enough, it zooms in, and we're right there in London. Perfect. Now, let's see if we can configure a new waypoint. So, let's go back to Grand Canyon University entrance. Set the location. Okay, so it's now set there. Close here. And this should update. All right. so I'm just going to wait it out. I'm going to see if we can get the location to update. It's supposed to update. Okay, so it takes a few minutes maybe, but as you can see, I now have Grand Canyon University. So, like I said, in a real phone it would work better. Okay, so it looks like I finally figured I got two different locations. This one's at 33, this one's at 51. We got two different spots. So, let's go ahead and chose the map. And the second one that I chose was in in Arizona. Okay, so if I zoom out a bit, you should be able to see London as well. And let's see, did I have something set in London? It looks like I did. Okay, so go around your neighborhood and set these pins and they automatically should zoom in on you. All right, there's one more cool thing I'd like to show you. It's the ability to click on a pin. So, let's go back and add a new item here. So, let's type in mmap.set. And you can see that there's a new option called set on marker click listener. That sounds cool. That means we're going to be able to use those pins as buttons. So, the click listener item that we're looking for is something called googlemap.onmarkerclicklistener. So, I choose new and goo and you get the help typing ahead and there it is. All right, so now we have a new method called on marker click and it has a marker. Now, the return false here is kind of a strange thing. It's just something we have to add at the end. I think it tells the computer or tells Android that we're we haven't actually consumed this click. It's It's going to be used again later. I'm not quite sure what that is, but we'll leave return false as is. So, I'm going to create a very simple routine here. I'm just going to count the number of times that this button is clicked, this pin is clicked. You could set it to do other more interesting things, but this just gives you a demo of how clicking works. So, we're going to utilize a property in a marker called a tag. Now, tag is kind of a universal flexible type of field. You can stick anything in it until you want. You can put in an integer, strings, objects. We're going to just use an integer. So, I'm going to say if assign this value called clicks to be whatever it was in get tag. Now, you can see that there's a problem here. It says you don't know really what get tag is, but if you cast it, you will now have an integer as a promise. So, if it doesn't work, let's check on the second line to say if clicks turns out to be absolutely null. I mean, it didn't get work. It didn't get anything. The the tag is empty. So, if the tag is empty, then let's set the value of clicks to zero. After we set it to zero, then let's increment it. So, we'll do a plus one, and then we will set the tag to whatever new variable it is. So, it might be one. It might be 10. Whatever, how many clicks it was. So, the next goal is I'm going to have a toast that will tell us how many times that the marker was clicked. So, I will put in a string for the text that says marker, and we'll get the title, was clicked, and then how many times it was clicked is from the tag. So, this should tell us a new number every time we click it. All right, let's run the application again, and let's go ahead and set a new waypoint, and let's show the map. All right, here is our marker. And if I click it, and let's see if the click works. There it is. So, at the bottom I have a toast that says your marker was clicked three times, and four times. Now, there's all kinds of things you can do with markers. You can set their colors, you can change them to different styles other than these generic pins. You can draw circles, you can draw lines. Maps have a lot of options. You can do heat maps, you can do guided tours. So, we're just barely getting started on the maps. And so, since this is an Android class, I wanted to show you how to get into these different classes, but look at the documentation to see what the full potential is. So, this extends our GPS demo and allows you to add waypoints, save them as a list, show them as a map, and navigate between a few screens. So, very basic, of course, but it's a great doorway opening to whatever apps and imagination that you can think of. So, good luck with your apps and Android and maps.
Original Description
Learn how to create a GPS Android App. You will learn how to use FusedLocationProviderClient, Google Play services, Location Provider, and other parts of a GPS-aware application.
💻 Starting XML file: https://github.com/shadsluiter/gpsDemoStarting/blob/master/activity_main.xml
✏️ Course developed by Shad Sluiter. Check out his channel: https://www.youtube.com/user/shadsluiter
--
Learn to code for free and get a developer job: https://www.freecodecamp.org
Read hundreds of articles on programming: https://freecodecamp.org/news
❤️ Support for this channel comes from our friends at Scrimba – the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from freeCodeCamp.org · freeCodeCamp.org · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
React: Production Server Setup Part 2 - Live Coding with Jesse
freeCodeCamp.org
cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
freeCodeCamp.org
Browser history tutorial - Beau teaches JavaScript
freeCodeCamp.org
Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
freeCodeCamp.org
React: Parameterized Routing with Next.js - Live Coding with Jesse
freeCodeCamp.org
React: Dealing with jQuery Issues - Live Coding with Jesse
freeCodeCamp.org
setInterval and setTimeout: timing events - Beau teaches JavaScript
freeCodeCamp.org
Browser and Device Testing - Live Coding with Jesse
freeCodeCamp.org
Last Minute Updates - Live Coding with Jesse
freeCodeCamp.org
Post Launch Updates - Live Coding with Jesse
freeCodeCamp.org
React: Setting Up Google Analytics - Live Coding with Jesse
freeCodeCamp.org
React: Masonry Layout - Live Coding with Jesse
freeCodeCamp.org
Load Balancing Digital Ocean Droplets - Live Coding with Jesse
freeCodeCamp.org
try, catch, finally, throw - error handling in JavaScript
freeCodeCamp.org
Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
freeCodeCamp.org
Graphs: breadth-first search - Beau teaches JavaScript
freeCodeCamp.org
React: Masonry Layout Part 2 - Live Coding with Jesse
freeCodeCamp.org
React: WordPress API Live Search - Live Coding with Jesse
freeCodeCamp.org
Creating WordPress Custom Post Types - Live Coding With Jesse
freeCodeCamp.org
Dates - Beau teaches JavaScript
freeCodeCamp.org
Miscellaneous Front End Updates - Live Coding with Jesse
freeCodeCamp.org
Merging a Pull Request from GitHub - Live Coding with Jesse
freeCodeCamp.org
React + Prettier + Standard JS - Live Coding with Jesse
freeCodeCamp.org
React: Sortable Responsive Table - Live Coding with Jesse
freeCodeCamp.org
Geolocation Sorting by Distance - Live Coding with Jesse
freeCodeCamp.org
Tradeoff Matrix - Agile Software Development
freeCodeCamp.org
The Definition of Ready - Agile Software Development
freeCodeCamp.org
Getting first React job without experience - Ask Preethi
freeCodeCamp.org
React: Google Analytics Click Tracking - Live Coding with Jesse
freeCodeCamp.org
Submitting a PR to an Open Source Project - Live Coding with Jesse
freeCodeCamp.org
Should I go back to school to get CS degree? - Ask Preethi
freeCodeCamp.org
Hero Section CSS Changes - Live Coding with Jesse
freeCodeCamp.org
Working Agreement - Agile Software Development
freeCodeCamp.org
A day at Pennybox with Co-Founder Reji Eapen
freeCodeCamp.org
React: Sorting and Filtering Data - Live Coding with Jesse
freeCodeCamp.org
React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
freeCodeCamp.org
React: Building a New UI - Live Coding with Jesse
freeCodeCamp.org
Definition of Done - Agile Software Development
freeCodeCamp.org
Getting started with jQuery (tutorial) - Beau teaches JavaScript
freeCodeCamp.org
Making a React Blog with WordPress Content - Live Coding with Jesse
freeCodeCamp.org
React, NextJS, CSS - Live Coding with Jesse
freeCodeCamp.org
jQuery events - Beau teaches JavaScript
freeCodeCamp.org
React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
freeCodeCamp.org
React: Working with API Data - Live Coding with Jesse
freeCodeCamp.org
React: Refactoring Components - Live Streaming with Jesse
freeCodeCamp.org
jQuery effects - Beau teaches JavaScript
freeCodeCamp.org
More React Refactoring - Live Coding with Jesse
freeCodeCamp.org
animate in jQuery - Beau teaches JavaScript
freeCodeCamp.org
"Finishing" My React Site - Live Coding with Jesse
freeCodeCamp.org
Starting a New React Project (P2D1) - Live Coding with Jesse
freeCodeCamp.org
React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
freeCodeCamp.org
The Agile Manifesto - Agile Software Development
freeCodeCamp.org
jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
freeCodeCamp.org
React Project 2 Day 3 - Live Coding with Jesse
freeCodeCamp.org
The INVEST approach to product backlog items
freeCodeCamp.org
React Project 2 Day 4 - Live Coding with Jesse
freeCodeCamp.org
Chickens and Pigs - Agile Software Development
freeCodeCamp.org
React Project 2 Day 5 - Live Coding with Jesse
freeCodeCamp.org
jQuery: add and remove DOM elements - Beau teaches JavaScript
freeCodeCamp.org
React Project 2 Day 6 - Live Coding with Jesse
freeCodeCamp.org
More on: AI Pair Programming
View skill →Related Reads
📰
📰
📰
📰
We Taught Machines to Talk. We Forgot to Teach Ourselves to Listen.
Medium · AI
Is the AI bubble about to burst? A data scientist’s honest take
Medium · AI
Is the AI bubble about to burst? A data scientist’s honest take
Medium · Machine Learning
Is the AI bubble about to burst? A data scientist’s honest take
Medium · Data Science
🎓
Tutor Explanation
DeepCamp AI