Google Maps SDK for Android with Kotlin | Masterclass | Stevdza - San | Skillshare

Google Maps SDK for Android with Kotlin | Masterclass

Stevdza - San, Android Developer & UX/UI Designer

Google Maps SDK for Android with Kotlin | Masterclass

Stevdza - San, Android Developer & UX/UI Designer

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
64 Lessons (7h 29m)
    • 1. Introduction

      2:51
    • 2. Create Android Studio Project

      14:52
    • 3. Connect the Project with Google Cloud Platform

      11:57
    • 4. Get Coordinates Information

      4:16
    • 5. Controls and Gestures

      11:32
    • 6. Map Padding

      5:33
    • 7. Change Map Type

      6:18
    • 8. Change Map Style

      5:54
    • 9. About Camera Position

      3:38
    • 10. Show Buildings in 3D on the Map

      7:36
    • 11. Change ZOOM levels and Set Max/Min ZOOM level

      4:23
    • 12. Update Camera Position

      6:11
    • 13. Setting Boundaries on the Map

      5:18
    • 14. Restrict User from Scrolling

      2:04
    • 15. Animate Camera Movement

      7:05
    • 16. Single/Long Click Events

      3:30
    • 17. About Markers

      3:03
    • 18. Store Data Object in a Marker

      3:55
    • 19. Enable Marker Dragging

      2:43
    • 20. Marker Customization

      13:41
    • 21. Marker's Z Index

      3:11
    • 22. About InfoWindow

      4:42
    • 23. InfoWindow Customization

      8:37
    • 24. Introducing to Polyline

      9:11
    • 25. Introducing to Polygon

      11:49
    • 26. Introducing to Circle

      4:16
    • 27. Shape Customization

      10:20
    • 28. Ground Overlays

      10:34
    • 29. My Location Layer

      11:38
    • 30. Create the New Project

      5:51
    • 31. Implement Navigation Component

      5:38
    • 32. Design PermissionFragment Layout

      7:11
    • 33. Check & Request FINE_LOCATION Permission

      16:32
    • 34. Add Google Maps API Key

      4:55
    • 35. Design MapsFragment Layout

      10:15
    • 36. Enable My Location Layer

      8:55
    • 37. Request BACKGROUND_LOCATION Permission

      10:05
    • 38. Implement the Countdown

      7:44
    • 39. Introducing with Services

      5:34
    • 40. Create TrackerService class

      6:59
    • 41. Create Notification

      11:48
    • 42. Start Foreground Service

      7:37
    • 43. Start Location Updates

      8:02
    • 44. Update and Observe Location List

      6:06
    • 45. Draw a Polyline

      6:06
    • 46. Stop Foreground Service

      6:21
    • 47. Calculate Elapsed Time

      6:41
    • 48. Calculate the Distance

      4:06
    • 49. Show Bigger Picture

      4:06
    • 50. Create MapsBindingAdapter

      7:30
    • 51. Update Notification Periodically

      3:34
    • 52. Design ResultFragment Layout

      5:42
    • 53. Display Results

      12:28
    • 54. Share Results

      4:05
    • 55. Map Reset

      7:53
    • 56. BottomSheet Round Corners

      3:29
    • 57. Add Markers

      9:09
    • 58. SphericalUtil

      2:26
    • 59. GEOJson

      11:32
    • 60. Marker Clustering

      8:20
    • 61. HeatMap

      14:34
    • 62. Final Word

      1:20
    • 63. Dependency Update & Deprecated Code cleanup

      2:30
    • 64. jcenter() Migration, Easy Permissions, Dependency Update

      3:31
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

64

Students

--

Projects

About This Class

Hello there and welcome to my course, In this course I'm going to teach you how to implement Google Maps SDK for Android using the power of Kotlin programming language.

We are going to start this course by introducing with Google Maps SDK, you will first learn how to connect your Android Studio project with Google Cloud Platform. After that we will go through the process of generating Debug and Release API Keys in order to enable Google Maps SDK in our project.

Then I'm going to show you how to enable/disable certain Map controls like compass, zoom in/out controls, my location button and more. Also how to enable/disable map gestures like scrolling zooming, tilting, rotating and so on.

After that we will go through to process of choosing and applying different Map Types and Styles. You will learn how to apply dark and light map styles to your app.

You will learn how to animate Maps camera movement, how to Animate zoom levels, how to handle single click and long click events, how to place markers and drag them on the map. Then how to customize markers, and info windows as well.

Also you'll learn how to add different shapes to your Google Map like Polyline, Polygons, Circles, Overlays and basically everything you'll even need!

So Only after we get fully introduced with most of Google Maps features, we are going to start and build a real Android application. Our app will be called Distance Tracker, and as the name suggests, we will create an app which will be able to track our users location and track the distance which user travels. Our application will use Foreground Service and it will track users location even from a background when we kill our app. Bottom line, you will be able to  track how many kilometers have you traveled and how much time it took.

In this course you will not learn just how to use Google Maps SDK, but also how to handle Run-time permissions, and the best practice of requesting those permissions sequentially as the newest Android API requires.

Also our application will use Foreground service with a non-removable Notification which will always stay on the top. Unless we stop and kill our foreground service. Now this is not the course where you will just learn the theory, this is the course where you are going to combine theory with practice and create a real android application to put all your knowledge which you gathered throughout this course together.

So bottom line, the level of knowledge you will get from this course, depends on how much effort you put into watching and practicing with this course.

So what are you waiting for, let's get started Developers!

Meet Your Teacher

Teacher Profile Image

Stevdza - San

Android Developer & UX/UI Designer

Teacher

Class Ratings

Expectations Met?
  • Exceeded!
    0%
  • Yes
    0%
  • Somewhat
    0%
  • Not really
    0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Your creative journey starts here.

  • Unlimited access to every class
  • Supportive online creative community
  • Learn offline with Skillshare’s app

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Hello there and welcome to my course. In this course, I'm going to teach you how to implement the Google Maps SDK for Android using the power of our Katlyn programming language, we're going to start this course by introducing with the Google Maps SDK. You will first learn how to connect your Android Studio project with the Google Cloud Platform. And after that, we will go through the process of generating debug release API keys in order to enable our Google Maps SDK in your project. Then I'm going to show you how to enable or disable certain maps. Controls like campus, zoom in and out, controls my Location button and more and also how to enable and disable our map and gestures like scrolling, zooming the old thing, rotating and so on. After that, we will go through the process of choosing in applying different map types and their styles, you will learn how to apply a dark and light a map styles to your map. You will learn how to animate maps, that camera movement. How to animate the zoom levels, how to handle our single click and long click events. How to play some markers and a drag them on the map. How to customize markers and info windows as well. Also, you will learn how to add a different shapes to your Google map, like a polylines, polygons, circles, overlays in basically everything you could think off. So only after we get full introduced to a thermoset or Google Maps or futures, we're going to start and build a real Android application, replication or will be called the distance tracker. And as the name suggests, we will create an APA, which we'll be able to track our user's location and attract the distance which are users travels our application and we'll use a foreground service and it will track a user's location even from a bare ground when we kill our app. Bottom line, you will be able to track how many kilometers heavier traveled in how much time it took in this course, you will not just learn how to use the Google Maps SDK, but also how to handle runtime permissions. And the best practice or for requesting those are permissions to sequentially is the newest Android API requires also our application. We will use a foreground service with a non removable our notification, which will always stay on the top iOS, we stop and kill our foreground service, of course, now, this is not the course where you will adjust, learn the theory. And this is the course where you're going to combine theory with practice in create a real Android application to put all your knowledge which together throughout this course together. So a bottom line and the level of knowledge you will get from this course depends on how much effort you put into watching and practicing with this course. So what are we waiting for? Let's get started. Developers. 2. Create Android Studio Project: Hello there and welcome back. So in this video, we're going to create just a simple Android Studio project. So just go to File New Project. And here we are not going to create an Empty Activity project. Instead, they were going to use already made a template for Google Maps. So we need to select this Google Maps activity in. The reason why is because this template will generate all the necessary code we need for our Google Maps to be set up successfully and we don't need to waste our time creating everything from scratch. I'm going to just select this Google Maps template and I'm going to explain you all the generated code that we got from this template. And you will see, so now click Next. And here we're going to name our project, for example, Google Maps, demo our case or click Finish. All right, so just wait a little until grid or finishes are building this project, our case. So now I'm going to explain you ensure you all their files which were generated by this template. So first, we're going to start with our enjoyed the manifest file. So let's open that up in here. As you can see on top of our file, we have only one permission and that is the axis final location. So actually this axis fine location is not required to use a Google Maps API. But since we are going to use my location function in this course, then we're going to need this permission because we're going to need to locate our device later in this course and you will see our k. So as you can see, this template has a generated this permission. And down below we have one more tag that is metadata tag. So basically this metadata tag is referencing our API key. And the one I click, you will see that this value attribute is linking our Google Maps key XML file. And I'm going to explain you that in just a second. So basically here we have a two roots and the first one is a condo google.png daughter Geodata API key. And basically here we're defining the API key which we are going to use for our Google Maps API. So to use the Google Maps API, we're going to need to have an API key from a Google Cloud Platform. And in some of the next videos, we're going to also login to our Google Cloud platform. And we're going to create an API key for our Google Maps API. So for now, I'm going to open up this Google Maps key XML file. So just click on that and click Control B. So you can just open that immediately. Here you can see only one on Google Maps API XML file. But in reality we have two of those files. And let me show you that. So, so we're going to switch from this enjoy to project view. And now let me show you that we have those two files or two versions of this wall Maps API. So let's open that up. Okay, so app here, then source, and here you will see that we have a two directories, so debug and release. And each one of those directories contains a resource directory. And inside of those resource directories we can see values. Then inside those values we can see. Maps, API XML files. So here we have open this debug version, and now I'm going to open up this release version as well. So you can see that basically those are the same, but the one that will be used for debugging and the other will be used for our release version. So here, as you can see inside this file, we have a resource as a root element, and inside we have just a simple string element. Okay? So it's the same in both of those files. So just a simple string element. And this element is basically referencing our API key. So as you can see here, it says your API key. Here is the place where we need to enter our Google Maps API key. Ok, so now you might be wondering, why do we have two versions of this file at the back end release. So basically, if you want to use this application on a real devices, or if you want to distribute your application on Google Play store, then you are going to need to generate a release API key as well. So there is a difference between a debug API key and the release API key, okay? And the main difference is that this release API key will be used on a real devices and this debug API key can be used on enjoyed the emulator only. So in this project, we're going to only use this debug API key. But don't worry, I'm going to also show you how you can generate a release API key as well. So hearing the comments of this debug version, we have summer automatically generated code. So here as you can see, we have our package name and down below we have our sha-1 debug certificate fingerprint. Ok. So as you can see, this certificate fingerprint was automatically generated for our project, but this is a debug certificate fingerprint. And as you can see in our release version of this file, we don't see that certificate fingerprint. That that is because we have to manually generate release certificate fingerprint by ourselves. So we're going to need this package name and our sha-1 debug certificate fingerprint in order to generate our API key down here. And we're going to do that from our Google Cloud Console in the next video. So also you can see on the top of this file that we have a one URL. So this URL is also automatically generated by this Google Maps or template in here is basically just a simple URL, and those are queries were automatically generated. So for example, as you can see here on this URL, we also see our sha-1 certificate fingerprint for a debug, and we can see our package name as well. So this is a way for us to actually create our API key very easily or in easy way. So we can just copy this URL paste in our web browser and we can just generate our API key in a few clicks. And that, that's exactly what we're going to do in the next video. But also I'm going to show you the manual way to create an API key from your Google Cloud Console as well. So don't worry. There's one more thing before we proceed to the next video. So now you saw that this Google Maps template has automatically generated this debug certificate fingerprint. And now I'm going to show you how you can generate this same fingerprint by yourself. And it's very easy. Ok, so you can do that from this gradle option on the right side. So just click that and open that up. In here you will see the name of this project. So just click this little arrow, then you need to open this tasks. Then you need to open this enjoy directory. I came in here you can see two files or sorry, three files or three options. And we are going to new to basically double-click on this signing report. So just double-click on that and you will see that the Android Studio will automatically generate those certificate fingerprints. And as you can see, this sha-1 certificate fingerprint is basically the same as in our debug version right here. So this is basically sha-1 hash representation of your certificate for your project. Okay, so now you have learned the difference between those two files. So we have debug and release versions of our API keys. And if you are planning to use this application on a real devices and distributed that app to other users, then you're going to need to generate this release API key as well. And for that, you're going to need to generate released a certificate fingerprint as well. So now you saw how to generate sha-1 a certificate fingerprint for a debug version. And now I'm going to show you how you can generate this certificate fingerprint for a release version as well. Okay, so let me just close that for now. Okay. So in order to generate a release certificate fingerprint, you will need to build your release version as well. So just click build options, then our generates sign the bundle or APK. So here we have two options and in this case I'm going to use an APK. So just for a demonstration purposes, but you can use each one of those. So we're going to generate a release APK for our project. And here you can see that we need to generate our key store path. So basically willing to create new KeyStore file and that file will be used to sign our application. So if you are planning to release this application on Google Play, then you're going to need that KeyStore. So I'm going to create a new file here. In here, we need to add some information to the first thing we need to say where we want to save this key store. And for example, I'm going to save that. I'm going to say that on my desktop. So just select the directory here and the name of this file can be Maps or Google Maps demo in here you can see this extension. So basically that's short for a Java key store. Okay, so this file will contain all the certificates we need for our application to actually be published on Google Play. So click OK. And now that we can specify the actual file which will contain that really certificate, then we need to specify the password. So I'm going to type here. So I'm going to type here some random password. Okay? So here we have our key alias in here. You can type anything you want, but you also need to remember this name. It's very important. And down below we need to generate another password for this key. So. It's a recommendation that you should create a different password for KeyStore in for this key. So be sure to create different password, but also be sure to remember those passwords because if you lose this password, then you will not be able to generate a new update for your application. And down below, we can specify some more information for this, for this release. So those information will not be visible in your app. Instead, they are only going to be visible for your certificate. So here I can just type, for example, the name of my youtube channel. Here I'm to click OK. And then as you can see, we have basically specify the path and the file we want to create. So this is our key store, and this is a very important file which you should keep privately and securely, because without this file, you will not be able to, to sign your application anymore and you will not be able to send a new update to a play, for example. So be sure to keep this file privately insecurely here you can also check this option to remember the password, so you don't need to type this password every time. So just check this option, click Next, and here we're going to select a release, okay? Any, for example, for this signature versions, we can select both of them. So, so this is not very important at this moment. So just click Finish. Just wait until Android Studio is building your APK file. So while this Android Studio is working, I'm going to open up a project file and I'm going to show you where this APKs will be generated are case. So our APK was successfully generated in here when you open your project inside the Android Studio projects directory. And we need to go to app then really is. And then you will see that this release version of your APK was successfully generated. And of course, on our desktop, when I open that up, you will see that now we have a successfully generated this Google Maps demo KeyStore. So this file a very important and you should keep that privately and securely. So basically, whenever you create a new version of your application, you're going to need to have this KeyStore file. So now that we have generated our release build, then I'm going to show you how to generate a release Certificate, Fingerprint R, k. So let's close that now. And for that we're going to need to open up our terminal here, okay? Okay, so there is an official Android Developers documentation which you should check out. And here we have a steps to actually generate our debug and our release certificates. Okay, so here you can see the actual terminal commands which we need to enter in order to generate our It's certificate fingerprints. So I'm going to just copy this command here and I'm going to enter that in our Android Studio terminal. So here I'm going to just paste that code and we need to change two words here. So here as you can see here where it says your alias name and willing to say C0 0 because that's the name of our aliens, if you recall, our k and here where it says your key store name. And we'll need to specify a full path where our KeyStore is actually located. So let me remove that for now. So here basically I'm going to copy the full path where our store is located. So here I'm going to paste that right there or k. So here we have C, then users, then the name of my directory here than desktop. In here we need to specify the name of our KeyStore. Ok, so Google Maps demo dot j, k, s. So here as you can see, it says a key tool and that's basically the tool for generating our certificate fingerprints. Then we have this list than v, then a KeyStore. In here we are specifying the name or the full path where our key store is located, and then areas in the name of our alias, which is k 0. So now that we have written all of that, we can just press enter here. It will prompt us to add the password. And of course you should remember that password from earlier. So I am going to just type that password right here and click enter. So now you will see that new SHA, one fingerprint was generated. And as you can see, it's a different from our debug certificate fingerprint. Ok, so as you can see, this one starts with F1, then a two-way, and it ends with a C7. And our debug certificate fingerprint is totally different. So now I'm going to copy this release certificate fingerprint, and I'm going to paste that inside my release version of this Google Maps API. So I'm going to type that here. So SHA, one and there it is. Okay, so now I have pasted this new release certificate fingerprint. And in the next video, we're going to need those two certificate fingerprints in order to generate two different API keys. Okay, so that will be all for this video. And in the next video we're going to log in to our Google Cloud platform. In there, we're going to generate new API keys for our Google Maps API. 3. Connect the Project with Google Cloud Platform: Hello there and welcome back. So in the previous video, we have created the Android Studio project, and we have also used our Google Maps template. So I already explained all the files in the codes which were automatically generated by this template. So as you already know, we have a two different files or two different wall Maps API files, one for the bike and the other for release version. So in the previous video, I have also shown you how to generate by yourself the bug end release certificates, fingerprints. And here we have added the new comment for our release sha-1 certificate fingerprint as well. So for example, if we run this application without API keys, then you will see that here in our activity and we share our Google Maps, but nothing will show. And that is because we need to first generate our API keys and then we can use the Google Maps API. So before we go to Google Cloud and create API key, I just want to show you our Maps activity and our layout file. So as you can see, those two files were also automatically generated. So inside our activity maps layout file, we have only one fragment in that is a simple fragment which is using this support the MapFragment. So it is very important to add this name attribute with this support MapFragment. And that's how we are going to be able to use our Google Maps in our activity. So support MapFragment is basically SomeClass offer fragment and it's the easiest way to use Google Maps with this support MapFragment, okay, and now our Maps activity, you can see here on the top, we have only one global variable of a type of a Google map. And now I'm going to change its name to say only map. So just hold the Shift plus F6 and let's rename this to simple as map. So click enter our case. So as you can see inside our own create method, we have basically obtained our support MapFragment. In here, we have called this get map async function. And inside the parameters of this function, we have passed this. And that is because we have already inherited this old mare per ready callback on top of our Maps activity as well. So as you can see here for this, I get mare per async method. It says that this method must be called from the main trend. It will be executed in the main thread as well. In the case where Google Play service is not installed on the user's device, then this callback will not be triggered until the user installs that. In the rare case, when the goal map is destroyed immediately after creation, this callback is not triggered in the Google Map object provided by this callback is a non null. So basically this get MIP async, We'll call this map already function whenever our Google map is ready. So basically this on map ready is something similar to, for example, onCreate method inside our activity. So basically this old map already will be triggered in cold when our acuity starts and when our Google map is actually ready. So inside this map ready, we're going to basically add all the necessary logic to manipulate with our Google Maps and inside our own map already, we have fewer lines of code. And I'm going to explain you that in some of the next videos. For now, we're going to focus on generating API keys for our Google Maps API file. Ok, so here. Google, you just need to type our Google Cloud and you need to open up the first link which says a cloud dot google.com. So let's open that up. And the first thing which you need to do, or you need to login to your Gmail account so you can access this Google Cloud. So let just sign in here. Okay, so now I have successfully logged into my account. And I can click here on this button that says go to console. So click that. And then now this is our Google Play Console. Okay? So here on, on the top, we can select our projects which we have connected with our Google Cloud platform. And as you can see, I have one project with the name of maps demo. Don't worry, this is my old project and my new project which we have created that together is called the Google Maps. Damn, ok. So here you can just create a new project with this button. And you can just follow along and just add the name of your new product and so on. But there is an easier way. So let me just open up Android Studio. And here when you open up this debug version of our Google Maps API file, you will see that we have this link which was automatically generated. So this link basically contains our debugger certificate fingerprint, and our package name. So we're going to just copy the URL here, and we're going to paste that URL in our web browser. So this is an easier way, but there is also a manual way. In the manual way would be to create your own project like I showed you earlier and here you will also need to add a few more informations. But now let me just paste this URL right here. Ok, so as you can see, this link will ask us to register a new application. So you can click on this drop down and you can select already made Project if you did the manual way. But since we're going to create a new project, just leave that as it is and click continue our k. So as you can see, now basically everything was done automatically for us. Okay, so here it says that API is enabled now and the project has been created in Maps SDK for Android there has been enabled. So just click Create API key K, And now you will be automatically redirected to this page where you can check your API key. Okay, so here we have just one API key in the name of our project is my product. So I think that you can change the name of this product, but for now it will stay that way. So it's not very important in this moment. So now select this API key one, and here you will see the name of your API key. You will see your, the actual API key. So this API key was generated for your debug certificate fingerprint. And now I'm going to show you how to create manually a new release Certificate Fingerprint API key. So first let's copy this debugger API key. And now I'm going to open up this debug version of Google Maps API. And here I'm going to just replace this text with our new API key. Ok, so now when we run our enjoyed the studio, we should be able to see the actual result in our own world, maps should work. Okay, so now as you can see, we can see our Google map, okay? And if you're having troubles seeing this picture, then you should probably restart your Android Studio and you should probably wait a few minutes because sometimes it can take time to actually, to actually enable this API key for your project. But for now, as you can see, our Google Maps is working in this moment. We have this marker placed inside the Sydney. So by default, this marker is placed in Australia, Sydney, because that's the place where a Google Maps was created. So you can zoom in and out by holding down Control and just moving your mouse now k. So now you saw how to actually generate an API key in a Google Cloud Platform. And basically for that, we only need the package name in our sha-1 and certificate fingerprint. So now if you try to install this application out of our new APK file, which was generated for a release build. Then when you run this app on a real device, you will not be able to see this result because we haven't added the new API key for our release version. And now I'm going to show you how to manually create an API key for this release build version. So first time we do copy this sha-1 certificate fingerprint which we have generated for this release build. Then I went to open up a web browser. So here I'm going to go back to previous page. And here as you can see, we have this API key number one, which was automatically created by that link which we have opened. But now let's create a new API key for our release bill. Ok, so click Create Credentials API key. And now you will see that this API key was immediately generated. But there are a few things which we need to set that before we can use this API key. So click close, then go to this new API key number two. And here you need to check this option that says four enjoyed amps. So we can actually restrict permissions for our project. Then down below we have an option that says add an item. So you'll need to click here and then you need to add the exact package name of your project. In this case, it's com dot example.com and Google Maps demo. So we can double-check that to see if that is the same name or K. So let's open this debug version. And here as you can see, it says a com dot example dot google maps demo. So it's basically exactly the same as we typed here. And down below, we need to paste our new sha-1 certificate fingerprint for our release build. So this sha-1 certificate fingerprint is different from our debug certificate fingerprint. So now that we have a paste those to information, click done. And now you can click Save to save those, those changes. And now you will see that this new icon will appear. So now we can just go to this API key and copy this new API key. And this new API key will be used inside our release version of our Google Maps API. So here just paste this new API key, and now you will be able to use this Google Maps when a real devices and on our Google Play if you want to, of course, upload this project or this application on Google Play. So now we can get back to Google Cloud Platform. I can show you how you can navigate to this page where you, where you can create your own API keys. So when you log to your Google Cloud platform, this is the page on which you're going to see. So not top, you can select the actual project which you are going to use. And in this case, our project is called the My Project. So now click this navigation menu. Then down below you need to scroll all the way down and you need to select the Google Maps app, platforms or platform. And then you need to click this credentials in there. You will be able to access this page where you can see your API keys are k. So let me just open this navigation menu once again. Here we also have this option to select APIs and services. So you can click Library here. In here you can see all the APIs which you can iterate to your Android application. So in this case, we're using a Maps SDK for Android. And if you are manually creating your APIs and your project, then you will see a new button here that says install or something like that. But since we have a pasted the URL which was automatically generated by our project, this one. Then this synapse SDK for Android there was enabled the automatically. But again, I am repeating. If you are creating this all by yourself, then you will need to basically go to this page here and enable this Maps SDK for Android by yourself. So that'll be all for this video. Now we have successfully connected our project with Google Cloud Platform, and we have also generated the two API keys for our debug and release versions as well. And now you will be able to run this application on your a real device as well because we have generated this release API key as well. And in the next videos, we're going to get introduced with Google Maps API. Furthermore. 4. Get Coordinates Information: Hello there and welcome back. So in the previous video, we have connected our project with Google Cloud Platform. And in this video I'm going to show you how to manually get coordinate information about a specific location on Google Maps. But before that, I just wanted to show you how our application looks. So far, as soon as you can see when we run our application, we're going to see this one marker on one city in Australia named Sydney. So if we zoom in, then you will see that the name of this city is Sydney. And the reason why we see this default coordinates on this CD is because google Maps was created in this exact city. So as you can see when we open up our Maps activity, you will see that we have overrided one on map already function, and I already talked about the dysfunction in the previous video. So basically inside this function, we are initializing our global map of variable and we are setting a Google map object from this function to our global variable. And then down below we are creating one outlet longer object. And this led along object. He's basically consists of latitude and longitude. And those values inside the parameters of this object are actually the exact coordinates of, uh, Sydney. And then down below we are also using this Google map object to add a marker. And that marker is added on top of this Sydney city. And we have also added this title on this marker which says marker in Sydney or came. And down below, we are using this move camera function, which is basically setting the camera view to be on top of our exact location, which we have already defined inside this variable named Sidney. And that's how we're able to see this city when we run our application. So let me just run that again. Okay, so as you can see, this camera view is pointing to this marker on the center of this Google Maps. And that marker is pointing to this Sydney. Okay, so let me just zoom in. And they only press on this marker, then you will see a message that says marker in Sydney, OK. And we have specified that text inside this title function. And now I want to show you how you can get the exact values of specific location on a Google Maps manually by yourself. So let me just open a web browser in here. You can open up Google Maps. So just type google.com slash maps. Here for example, we can search some specific locations we want. So for example, I can type Los Angeles are K, and as you can see, we're going to immediately get the Navigator to this. Los Angeles is a city in Google Maps. And now you're wondering how can we get to the exact coordinates of this city? Well, it's very easy and there are multiple ways to achieve the same goal, but the easiest one is just the right-click on this Los Angeles text here, and then here we go. So here you can see the exact latitude and the longitude coordinates. So you can just click this and you will see a message that says a Copy to Clipboard. Okay, and now we can go to Android Studio and we can just paste those coordinates right here. Okay? And now when we run our application, we should be able to see a different city. So now I can rename this variable by clicking shift plus F6. And here I can say Los Angeles. So press enter, and now I can change this text here to say Los Angeles as well. Let's run our app now. Okay, so now as you can see, that marker is placed on top of our Los Angeles. So those were the exact coordinates which we have copied from our Google Maps earlier. And as you can see, it works perfectly fine. And even when we press this marker, then we're going to see these texts which says marker in Los Angeles. Okay, so that was all for this video. I just wanted to show you how to manually get coordinate information of a specific location on Google Maps. And in the next videos, we're going to continue exploring Google Maps API. And I'm going to show you some more interesting features. 5. Controls and Gestures: Hello there and welcome back. So in this video, I'm going to talk about controls and gestures. So Google Maps API offers built-in UI controls that are very similar to those found in official Google Maps application on your Android smartphone and weekend and modify those controls and their gestures using a UI is settings class, which can be obtained from Google Maps class. So in this video, I'm going to show you how we can modify, enable, or disable some UI controls and the summer gestures, which are available on Google Maps API. So by default, we can use basically all our gestures on our Google Maps. And as you can see, for example, I can zoom in and I can zoom out using swipe gestures or using a double-tap for example. So as you can see, it works and that also we can use our summer rotation gestures as well. So everything basically is enabled on our map. And there programmatically we can enable or disable those gestures. So by default, most of those are gestures are already enabled. And now let me just show you the code in here inside our own map, ready. We're going to use our rural map object to actually work with those controls and the gestures. So down below I'm going to write Map dot GUI settings. And from here I'm going to call Apply scope function in here. Basically, we are going to enable or disable or our Google Maps controls and their gestures. So first time we will start by showing you how we can enable two buttons for us zooming in and zooming out. So we can just call here is a zoom gesture enabled and we have another one that says Ii's a zoom controls enable. So the first one is for enabling or disabling gesture controls for zooming, and the second one is for showing or disabling doors, zoom buttons. So I'm gonna do is first this is a zoom control enable and I'm window set its value to true now, okay, so if we hover over dysfunction in press Control Q here we're going to see the documentation for that. In here it says that either basically enables or disables the zoom controls. So if enabled, the zoom controls are a pair of buttons, one for a zooming in and for a zooming out that appear on the screen. So when pressed, they can cause the camera to zoom in or out by a one zoom level. So I'm going to talk about the zoom levels a little bit later in this video. So basically there are, I think, 20 zoom levels from one to 20 and even disable the zoom controls are not shown on the screen. So here it says that by default, the zoom controls are enabled, but they are actually wrong because those zoom controls are disabled by default. And as you saw in our application here, we don't see any zoom in and zoom out buttons. So now with this line of code, those buttons will be enabled. So let's run our app again so you can actually drag it out. Okay, and now as you can see in the bottom right corner, we can see those two buttons for a zooming in and zooming out. So when we press this Zoom In button, once, we're going to zoom in, zoom level. And we can press this button multiple times. And there we can zoom in and zoom out very easily, so it works perfectly fine. So if you want to enable those two buttons by default, you just need to add to this simple one line of code. So next we have this is zoomed gestures enabled. So by default, this value is set to true and the zoom gestures are actually enabled. But for example, we can set it to false and we can disable those zoom gestures. So let's open up our application and as you can see, we can use those zoom controls, but we cannot use the zoom gestures, like double tapping on our map here or using two fingers. So it doesn't work because we have disable those Azzam gestures. Now you might be wondering, why do we need to disable those zoom gestures anyway? Well, there is a case, for example, when you want to display your business or your shop in your application, and you don't want to allow users to move throughout the whole map. You just need to zoom in on a specific street and just show your exact address for your shop, for example. And in that case, this zoom gestures can be disabled. And now I'm going to show you how you can specify the exact zoom levels for your map. So here, as you can see, inside this movie camera function, we have a camera update factory, and here we are calling a function named the new lat long. Okay? And also there is a one more function and name the new LatLng zoom. And this function accepts two parameters. So the first one is the actual left long object. In the second one is the actual assume value. Ok, so here for the zoom level, I can type for example number 15, and I can use this f because this is a float value. And I already mentioned that there are 20 zoom levels, so from one to 20, and in this case I have used the number 15. So let's run our app and let's see how our map will look like now. So now as you can see, our marker or our city, Los Angeles, is zoomed in at this zoom level of 15. And as you can see, we can move here on the map, but we cannot do zoom in or zoom out. So this is useful when we want to show only our business or our shop here on the map. So next, let me show you some more options which we can use with this UI settings class. So also there is a scroll gesture enable the value. So by default, this is enabled. And for example, let me just disable that by setting that value to false. So now when we run our application, so now you will see that we are not able to move our camera view elsewhere on the map. So as you can see, I am trying to move left, right, top and bottom, but it doesn't work because we can set it this scroll gesture enabled to false. And now those are scrolling gestures are actually disabled. And for example, we can also disable zoom control. And then user will not be able to zoom in or zoom out and just see basically static imagery here on the map are case. So I'm going to just remove those two for now. So next we have, for example, is a tilta gestures enabled. But I'm not going to use this because I'm not able to use a filter gestures on this Android emulator device, but We can use a tilta gestures on a real smart phone devices. So I'm going to skip that for now. And next we have is a rotator. Gestures enabled in this rotate gestures is enabled by default, but we can just disable that and set its value to false so it cannot rotate on the map. And the next we have, this is my location button enabled. So basically if we set that to true, you would think that now we are going to be able to see that the button for locating our own position on Google Maps by using location permissions. But when we run our application, you will see that we are not going to be able to see that the Location button on our screen. And the reason why is because that, that button will be shown only when myLocation layer is enabled. And I'm going to show you how to track your own position on Google Maps in some of the future videos. But for now, I'm going to skip that. But basically in order to use this myLocation button, you will need to enable this allocation layer and we're going to talk a little bit later. So let me remove that for now k. So our next that we have, this is map, a toolbar enabled and its default value is true. So this toolbar is enabled by default. And now I'm going to show you that. So I'm going to remove that for now and I'm going to open our app here. So this toolbar will be shown when we press our marker on the map. So as you can see, when I press that, we're going to see this title in the down below, we're going to see those two icons. In those two icons basically represent toolbar. So now when we press this icon, it will basically lead us to Google Maps official application. So as you can see, and it will open up that same location on its official Google Maps application. So I'm going to close that for now. And this toolbar will be hidden when we click somewhere else. So you can see, so it will appear only if we press on some marker here on our map. Of course, we can disable that toolbar by setting its value to false. So next, we have some more options here, and I'm going to show you this is composts enabled. So I don't know if you have noticed so far, but this campus is enabled by default and it will show up only if we rotate our map right here. For example, I'm going to try to rotate the map. And you will see that the, this compost now appeared here on the top left corner. And when we press this campus, it will return us to a default that rotation degree, and it will disappear. Okay, so as you can see, by default, this compass is enabled. And from here we can just disable that by setting its value to false. So one more important thing. So if you want to disable summer gestures on the map, that doesn't mean that you cannot change the camera position. In fact, you can do that programmatically so well. For example, if we disable scrolling here on our Google map, that doesn't mean that we cannot change the actual location on our map, but we can do that programmatically by using a Movie Camera method from our Google Maps object. And also, I have forgot to tell you there is something called the lite mode, and it's a part of the Google Maps API. And it's basically a lightweight met with a minimal user interactions. So for example, with the light mode, some features are disabled by default. And I'm going to make a separate video for this light mode in the future. For now, I'm going to skip that. And basically now in this video you have learned how you can enable or disable some are crucial gestures in the controls on your Google Map. And also you saw that you can use this function named the new outlet long zoom, where you can specify the exact zoom level. And if for example, I'm going to change that to number ten for now. And our zoom view or our camera view will basically be a little bit further. So now as you can see, when we enter this number or value of ten, then we're going to be able to see the whole city. And our previous value was 15. And basically we have zoomed in inside the city for that value. And we can use a different value, for example, number five, and we can use some other values as well. So from number one to number 20. And now with this zoom level of five, we can see multiple cities and the maximum value I think is a number 20. So let's run our app so you can check that out. And basically we did to value, we can see one street very clearly, but for now I'm going to set its value to a number ten so we can see the whole city, and that will be all for this video. So in the next videos, we're going to continue exploring. Furthermore, our Google Maps API. 6. Map Padding: Hello there and welcome back. So in this video, I'm going to talk about map padding. So as you already know, Google Maps API feels in entire map container and that container in this case is support MapFragment. Now, in the previous video, you've seen where some UI controls were placed on the map. So for example, zoom in and out. Buttons were placed on the bottom right corner, as you recall, than a compass button was located on the top left corner, then my Location button is located on the top right corner, even though we haven't seen that one yet. And at the bottom left corner we have this Google logo. So those UI controls our position there relative to the edges of the map container. And now you might be asking, what does that have to do with map padding anyway? Well, met padding is used to actually move those UI controls are away from the edges of the map container. So we're appending is placed around the edges of the map container using a set padding function. So are the map will continue to fill an entire container anyway. And, but the text control positions, map, gestures, and the camera movement will behave is eat. He has been placed in a smaller place. So now you might be asking, why would we need to move those map UI controls anyway? Well, let me give you a simple example for that. So imagine that we need to create one sidebar on the right side of this map container. So if we place that sidebar, it will overlap with those controls on the same side. And in this case the zoom in and outer buttons. And that way we wouldn't be able to interact with those buttons. So now that's where map padding comes in. So well with Mapper padding, we can specify how many pixels we want to move. Those UI controls are away from the edges of map container. And now I'm going to show you how to do that programmatically. But we are not going to add any sidebar. Instead we're going to just imagine one. Okay, so I'm going to go to this nmap already function. And here down below I'm going to call this Google map object. In here I'm going to call set padding function. So as you can see, this function accepts for different parameters or afford different integer values. So each one of those integer value represents one side on the screen. The first one is, we have, the second one is the top, and the third one is right, and the last one is bottom. So here I'm going to add a 00. And the third value should be, for example, 300 pixels and the last 10. So now with this function set padding, I basically added the 300 pixel padding on the right side of our map container. So now let's run the app and you can see that the padding offered 300 pixels will be added on the right side of our map container K. So let's see. And you will see that those zoom in and outer buttons were moved on the left side. And the reason why, because we have added a 300 pixels on the right side and that this padding can come in handy when we have, for example, some kind of a sidebar here where we have some more options. But of course, this is just one simple and basic example. And you can create many different kind of staffer with this padding function, so it's very useful. Okay, so the center point of our map container will no longer be on the center of the screen as before. Now, because we have added a padding you on the right side, that center point will move on the left side for the exact same distance as that padding value. So as you can see at this moment, we see these red marker on the center of our screen, and that's where the center point was. But actually, if we tried to zoom in, then you will see that we are not going to zoom in on that same exact spot where this red marker is. Instead we're going to zoom in a little bit on the left side. So let's try and click this plus button. And as you can see, we are actually not as zooming in on this red marker, even if that marker was on the center of the screen. So that center point is now moved on the left side is I already mentioned, and that's why we are actually zooming in on the left side a little bit. Okay, so that's one more important thing which you should remember. And the last thing which I forgot to mention earlier. So you'll see this Google logo on the bottom left corner. Well, Google Maps API terms of service, says that your app must not to remove or obscure this logo image. And I think that this information is also important if you are playing to publish your application on the Google Play Store. Because when they are reviewing your application, they will check if whichever removed or obscure this Google logo image. So you should always keep this logo image are visible around here on this position. Ok, so now I'm going to remove this padding here which we have added. I don't need that at this moment, and that will be all for this video. Now you know what our map bedding is, how it works in how to configure it properly to fit your needs. 7. Change Map Type: Hello there and welcome back. So in this video, I'm going to show you how to easily change your map type. So Google Maps API includes several map types like normal, hybrid Satellite terrain and the non for a no map at all. So what's the difference between those map types you might be asking, well, each map type offers a different kind of information, so well, let's say you need a map for navigating from a car. And in that case, you would probably go with a normal map type because it can be more helpful in that specific case. So you can actually see better street names and so on. But if you need a map, for example, exploring a nature, Laker, mountains, hills, and other terrains, then you'd probably go with a terrain map type instead. So we're now in this project, I'm going to show you how to change those map types. And for that purpose, I'm going to basically create an options menu right here on our action bar. And from there we're going to have a few options to change our map type, okay, so the first thing that we're going to open our resource manager right here. Then I'm going to open up our menu and I'm going to create a new menu resource file. So here I'm going to name this file map types manual and just press OK. So here we're going to create four different items, or maybe five, we'll see. So let's add a new item here. We're going to add the ID. So the ID can be a normal nap, then the title can be normal and show as action can be never R k. So I'm going to extract this string to strings.XML or came. Next time we will just copy this item and paste down below so we can change some values. So here I'm going to say hybrid map in here I'm going to write hybrid suppress all plus Center, and let's add it to our strings.XML. Next, let's create the third items so the ID can be satellite in the title here can be satellite. So all plus enter, enter, enter, enter. Next we have a terrain map. So let's change the name here to terrain or plus enter our K. And I'm going to add one more, which we'll say non r k. So let me just rename that to non. So basically this non map type will show no map. And I don't know why we actually need this. Map types are anyway, but still I just wanted to show you as well. So now we have five items here, and now let's open up our Maps activity in here. I'm going to remove these comments so we can have a more space in our activity. And here I'm going to override the two methods. So we'll press Control O and the search for onCreateOptionsMenu R k. So here we're going to find our menu and we're going to inflate that. So let's use the menu inflator than inflate. In here I wanted to pass our menu resource file. So menu dot maps type's menu. And as a second parameter, we need to pass a menu from the parameters of this function and we can return true right here. Okay, down below, we need to override the one more method, name their own options item selected where we can handle a click listener is for our menu items. So 4t plus o and search for on options items selected. Okay, so this one in here, I'm going to say when item dot item ID in here, I'm going to say r dot id dot normal map. When we press our normal map menu item, then we want to apply a new menu type for our Google Maps in here I'm going to call Google map objects. So map dot type or map type in here we're going to call Google Map object. And we want to call a map type or normal. Ok, so I'm going to copy this code and just change few values. So here I'm going to change to hybrid map in hearing, which will change to hybrid map type hybrid. Okay, so next we have a satellite, so satellite map in here, map type satellite k. Next we have a terrain k in here, terrain map, so map type terrain. And finally, we want to add here a non map in here, map type and non, and of course, so we just need to return true here, k. And now let's run our application so you can check that out. Okay, so now we can see our options menu right there. And when I press that, we are going to see our five different map types. So the default map type for our Google Maps API is a normal. So when I press normal, nothing will happen. Next, let's try our hybrid map type. Okay, so here as you can see, and we can see the actual different map type. And when I zoom in, you will also see more information as well as the actual satellite look. So this is a hybrid and we also can see the names of our streets and all other information, as well as the sexual satellite look. And when I chose a satellite map type, then those names will disappear. So we are not going to be able to see those information. We're going to only see the actual satellite local Cain. And next we have a terrain. Ok, so here as you can see, we can see some a terrain and let me zoom out so you can see more clearly. So this is useful if you are planning to go hiking or a, climbing the mountains and so on. So you can see the actual terrain of the place or the location in which you're going to go. And finally, we have a map type of non. So when I press this non, We're not going to see anything. And as you can see, we don't see anything except our marker which we have already placed in the To be honest, I don't know why would we need this map type of non anyway, but still I just wanted to show you all the map types available inside this Google Maps API. So what that'll be all for this video. Now you saw how you can change your map types, and that will be all for this video. 8. Change Map Style: Hello there and welcome back. So in the previous video, you've learned how to change map type. And in this video I'm going to show you how to create a custom styles for your map. So in order to create custom style for your map, you will need a JSON file which describes how your mapper will be stylized. Now, don't worry, you don't need to write that JSON code all by yourself. There is already a web application which will do all of that work for you and generate the JSON code automatically. So we're now let me open up a web browser and let me show you that web application. So the URL of this website is map style dot width in Google.com. So when you open up this website, you will see this pop-up message. So there are two ways to stylize your map. The first one is by using Google Cloud Platform. In the second way is by generating a JSON coder which you're going to need to import to your project. And it is the moment we are going to use this second way and the future of these cores. I might show you first way as well, but for now we're going to focus only on this second way. So click, no things take me to the old-style wizard. So here as you can see, we can select some of the predefined styles for a Google map. So we have a standard that we have our silver, then we have our retro, then we have our dark, then we have a night nd. Finally, this aubergine. Okay, so now I'm going to select this retro style in. I'm going to use this style in my project. But before I generate the JSON code, I just want to show you that you can also customize more options. So here you hit a button that says More Options. So here we have a multiple categories to choose from. So for example, down below we have a road and then we can select, for example, our highway. Then from here we can select, for example, feel or stroke color. And down below we have also styles for that text. So for example, here we can choose the visibility, the color, the wave, saturation, and the lightness as well. So I'm not going to customize this style are furthermore, I just wanted to show that you can create your own custom map using this web publications. So it's very easy. You can just apply here a new options and you can see the results immediately. So for now, I'm going to get back. I'm going to select this retro style and then we'll click Finish. So now I knew pop-up will appear. And from here we need to copy this such JSON code. Ok, so as you can see, this is the complete JSON code for our retro theme. So just click Copy JSON. And now we're going to get back to our Android Studio. And here inside our resource directory, we want to create a new directory. So choose Android resource directory. And from the resource type we're going to choose a row and click OK. So inside this sorrow directory, we need to create a new file. So the name of this file can be, for example, style dot JSON and press Enter. And inside this file we're going to paste that JSON code which we have copied. Okay, so here it is. And now we can close this file. And inside our Maps activity, I'm going to create a new function which will basically set in the style on our Google map. So down below I'm going to create a new function. So private fun set map style. This function will have only one parameter and that is Google map. So here I'm going to create a try block, and here I'm going to create a new variable named success. And from here I'm going to use the Google Map object to call set map style. In here I need to pass a map style options object. So map style options, then I'm going to call this a load row resource style. And here basically I need to pass two parameters. The first parameter is the context. In the second parameter is the actual file. So r dot, rho dot style, that's the name of our JSON file. Okay? And basically this set map style, we'll return a Boolean value. So if we receive a true, then that means that this style was successfully applied to our map and the dumbbell. Or we can just type, for example, if this success is not true, and then we can just simply log one message in here I can type, for example, failed to add style or kN down below, we need to add the also a catch block. So here I can just catch an exception and I can just log that exception as well. So here I'm going to just use e dot toString or K. And now we can call this set map style function or from our own map ready. So set in AP style in here I can pass some map object. So now let's run our app and let's see if a new style will be applied to our map. Okay, and as you can see, I knew retro theme or a retro style. He has been successfully applied to our map. And to be honest, it looks amazing. So I can zoom in and see a little bit more. And as you can see, it works perfectly fine. So now with those tiles, so you can do many things. So now for example, if you're creating your application for a day in night version, or you can create the tools tiles off Google Map. And you can choose, for example, this dark or this night for a night mode and a standard for Demode. And then you can customize those styles depending on whether the user chooses a night mode or the mode. So that'll be all for this video. Now you'll learn how to actually create your own custom style for our map, and that's it for this video. 9. About Camera Position: Hello there and welcome back. So starting from this video, we are going to explore a camera and viewport. And as you already know, Google Maps SDK allows you to change the user a serve your port of the map by modifying their maps camera. So we're changes to the camera. We will not make any changes to markers, overlays in other graphics which you can use. So even though you can move the camera on the map, markers in other graphics will stay at their already specified coordinates. Now, the map view is modeled as a camera looking down on our flat surface and with default camera properties, we are looking at our map at 85 or 90 degree angle. So the position of the camera is specified by multiple properties like target, bearing, field, and zoom. So our target is basically representations of latitude and longitude values of allocation. Then bearing is orientation or a direction in which a vertical line on the map points it's measured in degrees clockwise from north. So for example, when you drive a car on the map, you need to turn a roadmap in order to align it with your eye, travel direction. Next, that we have a tilt which is a basically a view angle. It defines the cameras position on arc between directly over the maps center position and the surface of the earth. And it's measured in degrees from a direction pointing directly below the camera. So to make it even more clear to you, let me show you some examples. So first image on the left side is a default. Cameras tilt. The on the right side you can see a representation of that tilt. So here we can see an arc where number one is the actual camera position in the number two is the current map position. Now, let's say we want to change that tilt position to, for example, 45-degree angle. So on this image on the right side, you can see on position number three that now that camera move is a halfway along arc between position one, which has a 0 degree, and at the end of that arc, which has a 90 degree. Also, the camera is still pointing it in their maps, the center point, but now area represented by number four is visible as well. And finally, we have a zoom. So you already know that zoom level determines the scale of the map. So eta larger zoom levels, more details can be seen on the map. Yolo, it smaller zoom levels. More of the world map can be seen on the screen. Now, I already mentioned that there are 20 different zoom levels represented by integer values from 0 to 20. So for example, if we apply number one as a zoom level, we will be able to see a whole world. Then if we apply number five, for example, we will see closer like a whole continent. Then if we apply number ten, we will see a whole city. Then if we apply number 15 and we will see a closer streets, and with number 20, we will see mostly buildings. So bar or one more important thing to note about zoom levels. So due to screen size and density, some devices may not support the lower zoom levels. That's why you should always use get mean zoom level function on Google Map object to check for a minimum zoom level on a specific device. Okay, so that was just a short introduction on Google Maps camera. And in the next video, we're going to continue exploring Google Map Camera and viewport. 10. Show Buildings in 3D on the Map: Hello there and welcome back. So in this video, I want to show you how you can see your L buildings on the Google map in a treaty. And also I'm going to show you how to modify some camera properties, which I mentioned in the previous video, like a target zoom bearing and the tilt. But before that, I just want to modify this project a little bit. So I want to move some of the code from here inside the new class because I don't want to crowd this map's activity that much. So let me create a new package right here, misc, okay? And inside this package I want to add one new Katelyn class. And the name of this class can be, for example and style. And inside this class I'm going to put the code from this ONE option, cite them selected and this set map style function. So let me first copy this function. So I'm going to cut in this part of the code by hitting Control X. And now I'm going to place that function right here. I'm going to remove this private access modifier in here as a second parameter of this function and into other contexts, k in here, and we took pass that context. All right, so our next let me go to maps activity. In here. I'm going to initialize this class or leisurely. So private vol and style by lazy in here, let's type. Type and style are. Okay. So now I'm going to use this class to get the axis of this function, okay? And there's a second perimeter. We need to pass the context, right? So now I'm going to move this code here as well. So let me create a new function down below. So fun set map type. Okay, so this function will have a two parameters as well. So the first one is menu item and the second one is Google Maps or Google map. Okay, and now let's call this set map type here as well. So type and style set map type here, press item, and of course I google map object. So now as you can see, our Maps activity looks even more cleaner and it's easier for us to follow up the actual code. So let me just run the app to see if everything is gonna work just fine. Now k So our application and did not crash, and let me check if Mrs. working our k. So it is working perfectly fine and that's nice. So next, we can continue and I can show you how to actually modify some of the camera properties. So for that, I'm going to create a new class right here. And the name of this class can be camera and view port r, k. And here I'm going to create a new variable named Los Angeles. In the type of this variable will be a camera position. And here I'm going to use a camera position dot builder. And here I need to specify some of those properties, which I mentioned in the previous video. So the first one is the actual target. So here we need to pass a LatLng object, and I'm going to just copy the actual longitude and latitude values from our Maps activity. So let me just copy those two values because we are going to use a Los Angeles as well. Okay, so next time we will specify zoom level. Here I can say, for example, 17 zoom level. And next we can specify a bearing. So for now I'm going to set the 0 and the later I'm going to increase that value so I can show you the difference. Next thing we need to add a tilde. Tilde can be, for example, let me see, let's say a 45-degree. And finally, we need to call our build, okay, and we have some warning. Let me just call lat long object. And here let's pass those two values. Okay, so now it looks fine. And now I'm going to all solids initialize this class, so it's a lot easier for us that way and that way we don't mean to crowd our Maps activity that much. So let me create a new variable named Camera and viewport, and I'm going to lazily initialized as well. Okay, so here I'm going to press Control D, So I can copy this line of code one more time. And I'm going to comment out this first line of code. Okay, so here we're going to use a map object and its method named their Move Camera. And here we're going to also use a camera update factory, but this time we're going to change the function. Okay, so now we're going to use a new camera position in here we need to pass a camera position object which we have already created inside our camera in the view port class. So let's pass here a camera in viewport dot Los Angeles, and that's our camera position object. Ok, so now let me run the app so you can see how will that look like. Now, okay, so now let me just switch this camera and viewport class. So here we have specified first and that target, which is the actual location on our map, and in this case is a Los Angeles coordinates. Then I have specified the zoom level of 17. Then our bearing is 0, which is a default value. And for the tilt, I have specified there 45. Ok, so now as you can see, we are not looking at our map, eta 0 degree like we did in the previous example, so that the full tilt value is a 0. And now I have increased that to 45. So now I can just zoom out through time so you can see the actual map. Okay, so as you can see, we are not looking at our map. Strike from the top like we did in the previous example. So now we have changed our camera tilt value. And now when we zoom in a little bit, you will see that we can see those buildings in 3D, OK. And as you can see, it looks very nice. And also we can, for example, use a rotation here to rotate around. And as you can see, it looks amazing. So you can see all of those are buildings in a 3D. But of course, there is a catch. So for example, let's try and change the style of our map, okay, or the types or so lets choose, for example, now hybrid. So now you will not be able to see those buildings in a 3D like before, but still, using this tilde property of our map camera, we're able to see those buildings even better. So now as you can see, those buildings are even more visible now and we can zoom out even more to see our k. So as you can see, now basically we can see a complete building in a different til property. Okay? So let me just change this tilt value now to 0 so you can see the actual difference now case. So now as you can see, we are looking at straight from the top and now I'm going to change that back to 45 so you can see the difference now in our case. So there we go. And now I'm going to increase this bearing property in basically, our map will now rotate a little bit. So remember this image, and now I'm going to increase the bearing and you will see the difference. Okay? So now I'm going to set this bearing to, for example, 100. And now basically we are viewing our net from a little bit different tangled and before. And that will be all for this video, I just wanted to show you how you can modify some of those Camera Position properties. And you can see those buildings in a 3D only if you're using a normal map type. If you're using some of different map type, you will not be able to see those building senior 3D like that. Okay, so as you can see, only in a normal map type, and that will be all for this video. 11. Change ZOOM levels and Set Max/Min ZOOM level: Hello there and welcome back. So in this video, I want to show you how you can set the minimum and maximum zoom level to your Google Map, and also how to zoom in and out programmatically by yourself. So the first thing I want to show you how to set the minimum and maximum zoom level. So as you can see at this moment, we have a zoom level of 17. So let's open this camera in viewport class. So as you can see, this variable, camera position have a zoom level of 17. So now from this map ready and willing to set minimum and maximum zoom level. So let's call our Google map object, then set min zoom preference. So that's the function which we are going to use. So the minimum can be, for example, 15. And let's now add set max zone preference to 17. Okay, so now let's run our app and let's see how our map will behave in our case. So now as you can see, we have our zoom level at 17 Value. And now let's try to zoom in more. And as you can see, we are not able to zoom in anymore than death. And if we try to zoom out, we will be able to zoom out two times, so 12. And when I press this zoom out button, now it will not work. So only two levels of Zoom are enabled inside our Google Maps. So as you can see, 1715. So this way, we can restrict our user view port to only one single zoom level. And I think this is quite a useful option for multiple use cases. And now I'm going to show you how you can programmatically change your zoom levels. So let me just remove those two lines of code. And here I'm going to copy this line of code, but I'm going to call a lifecycle scope to launch a coroutine because I'm going to need the delay of a few seconds. And if you haven't added the coroutines dependencies, then you should add them. And as you can see, those are the exact dependencies which you're going to need to actually use a lifecycle scope. So here, instead of a new camera position, I'm going to call some different methods. So let's call Zoom. And here as you can see, we have a lot of different methods for zooming in and out. So we have a zoom in and zoom out functions. So those two functions will basically zoom in and out by only one zoom level. Then we have this zoom to function, which will basically zoom to a specific zoom level which we enter inside the parameters. And then we have those two zoom by functions. And those functions will basically zoom by a certain amount of zoom level. So for example, if we are navigated at zoom level of 17 and we add here a zone by number three, then we are going to get a new x2 value of 20. And if we add, for example, minus three, then we're going to get a new zone value of 14. So now I'm going to call, for example, this zoom by function. And I'm going to add here a number, three, r, k. And I'm going to add here a certain delay of, let's say two seconds. Ok. So after two seconds, we're going to increase our x2 value by three, and our default zoom value is 17, as you recall. And then we are going to increase that zone value by three in a two seconds. So let's run our app so you can check that out. Now K, So now let's wait two seconds. And as you can see, we, we're zoomed in via three zone values. So let me just increase that a little bit. So let's say, for example, four seconds. So you can see that even better. Now, k. And there we go. So that will be all for this video. Now you saw how you can zoom in and zoom out programmatically by yourself and how you can set the minimum and maximum zoom level as well. And in some of the next videos, I'm going to also show you how to create animations when you are moving your camera or zooming in and out. And you will see about that. So I'm going to just remove these lines of codes. I don't need that at this moment. And that will be all for this video. 12. Update Camera Position: Hello there and welcome back. In this video, I'm going to show you how you can programmatically update in the camera position and also how to scroll the camera over the map by shifting the center of the view with the specified number of pixels, either on x or a y axis. Okay, so we're back in our Android Studio project. And here for a moment I'm going to comment out this line of code, and I'm going to remove the comment from this line of code. So now when we run our application, we should be able to see a Los Angeles location with a zoom level or for number ten. Okay, so as you can see, it looks like that. And basically there are three most important functions for moving the camera position and inside this on map ready, let me just create a lifecycle scope so I can show you that and when to launch a simple coroutine. And here I'm going to call a map object, then move camera. Then here I'm going to call a camera update factory. In here, we have a different methods like we'll let long. So this function takes only one parameter and that is a let longer object. And then we have this new lat long zoom, which has a two parameters, lifelong object and the second parameter is a zoom level. In finally, we have a new camera position, which lets us modify our camera position even more. And you saw in the previous videos were remade that camera position object inside our camera in viewport class. So for now I'm going to use this new roulette longer function. Here I'm going to pass a new latlng object. So here let me just create a new variable named New York R, k. Let me was latlng object in here. I'm going to pass the executor coordinates of that city. And here I'm going to pass and New York are okay. And let me just add here a delay of, for example, let's say four seconds. So now you will see that our default camera position will be on a Los Angeles. And the after four seconds, we're going to move our camera to a New York. So let's run our app so you can see that. Now, case or Los Angeles. And after four seconds, we're going to get a navigator to New York are case. So there you go. Ok, so as you saw, when we move our camera from one location to another, there is no any animation. And I want to talk about camera animation in some of the next videos. But for now, you just saw how you can easily move your camera view to another location using these newer left longer function. We also have this new left Long Zhong which you have already seen. And there we can specify the exact zoom level which we want to add on that specific location. And finally, we have this a new camera position where we can add our camera position object like we did in our camera, in their view, a portrait class. Here we are able to specify some of the properties of their camera like Laker, target, zoom bearing endothelium. So as you can see, it's very easy to move a camera to a different location. And now let me show you a method named scroll by which lets you change the camera's position for a specified number of pixels on our X and the Y axis. So for example, a positive x value. We'll move their camera on the right side so that the map appears to have more of them left. And then a positive y value will move the camera down so the map appears to have moved up. And now I'm going to show you, will that work? So we're here. Instead of this new lead longer function, I'm going to use a scroll by in here. As you can see, this functional sets or two parameter, two or float values in the first one represents a value on our X axis, and the second one represents a value on the y axis. So here, when we press control Q on that function, we're going to see a documentation for that in here it says that this function returns like camera update that scrolls that camera or demand per shifting the center of the view by a specified number of pixels in the x and y directions. So there is one more important thing, which you should remember in here. It says that the scrolling is a relative to their cameras orientation. So for example, if the camera is bearing 90 degree, then at East is up and scrolling right will move the camera south. So don't be confused if you're modifying bearing value on our camera position object because you might get a different result than expected. So the first perimeter is x pixel. And basically here we can specify the number of pixels to scroll horizontally. So basically, if you remember, x axis is horizontal axis and y axis is a vertical axis. And now for example here I'm going to specify number 100. And the second one can be, for example 0. So now I want to move my camera for 100 pixels on the right side. And for the y axis I hear specifies 0 because I don't want to move my camera in the y-axis. So now let me just run the app and you will see that after four seconds, we're going to move our camera view port on the right side. So let's run that. So after four seconds, as you can see, we have moved on the right side for 100 pixels. And of course, there is no any animation to it. But don't worry, I'm going to talk about the animations in some of the next videos. And also here you can specify a negative value where as well. So here I can say, for example, minus one candidate or let's increase that value to 200. And here I can also specify, for example, 100 for a y-axis. And let me show you how will that work. So basically we're going to move now on the left side because we have a negative value and the down because we specified the y position as well. Ok, so now you saw that we have more than basically on the left hand bottom. And that's how you can update your camera position and scroll your camera for a specified number of pixels as well. So that's it for this video. 13. Setting Boundaries on the Map: Hello there and welcome back. In this video, I'm going to show you how to set boundaries on the map. So sometimes they can be useful to move the camera in such way that the entire area of interest is visible, integrate as possible zoom level. And there is a function called The New wet longer bounds, which lets us specify the location boundaries which we want to display on the map. Now, there is one catch with this function. So we can call this function only after the map layout is completed. And that's because the API calculates the display boundaries, the map during layout. So if you call this function before the layout is completed, you will get an app crash unless you add the two extra parameters for a width and height in that function. So now I'm going to show you how to set boundaries on the map. And for that, I'm going to open up this camera in the viewport class. In here. I'm going to create a new variable and I'm going to name that Melbourne bounds because we're going to use our Melbourne city in Australia. So here I'm going to call lat long bounds. Okay, so here, and this one accepts two parameters. So to let longer objects, and basically we, those two LatLng objects, we need to specify the actual boundaries. So let me open a web browser, and here I have opened the Google map. So here we can see our Melbourne City. So now we need to select two boundaries. So the first boundary should be southwest point. So Southwest can be, for example, right here, and I can click here, right-click, for example. And I can copy those exact latitude and longitude values of that point located in South West. So now I'm going to click that to copy those two values. Okay, so now let's open up Android Studio in hearing me to call latlng object. And here I'm going to paste those two values now came and then they're willing to add another boundary. So this boundary was Southwest, and now we need to get a northeast boundary, r, k and northeast boundary can be, for example, right here. So right click here, and then we will copy those two values. I'm going to open up Android Studio, and here I'm going to paste those two values. So this is a north east. And now I'm going to open up maps activity. And here I can remove this scroll by function. Now here I can call a different function so at long bounds. So as you can see, we have two functions here. The one which has sets lead longer bounds object and the one integer value in the other one which accepts three integer values. So those two extra integer values are the width and height. And if you want to set the boundaries before the layout is completed, then you should use this second function. But now I'm going to use this first one in here. I need to specify lat long bounds object. So I'm going to call a camera in the viewport class, and I'm going to call our Melbourne bounds. And here is a second parameter. I need to add the padding, so I'm going to set it to. And now let me run the app so you can see how those bounds will apply to our map. Ok, so after four seconds, we're going to navigate to Melbourne. And there we go. So as you can see now, we have specified those exact boundaries. We have used the southwest and the northeast boundary to actually show our Melbourne City. And for example, we can hear a specify our padding on each and every side. So for example, let me add that to 100. So now when I run the app, we should be able to see more of a Melbourne City in our boundaries are k. So basically this padding of 100 pixels have been the, on each and every side on this map. And that's what this padding is all about. So now there is another way of showing bounds on the map. So in some cases, you may wish to center your camera within bounds instead of including the extreme bounds. For example, to center the camera on the specified location from our boundaries while maintaining a constant zone. And in that case, we can use the newer let longer zoom function and just get the center of our boundaries. So now in that case we can call a different function in here. I can call now a new let longest zoom in here I can pass Melbourne bounds dot center. And here I can specify, for example, zoom level of ten. And now let's run our app and you can see the change r k. So after few seconds, we're going to get to our Melbourne. And here as you can see now we have used the center point of those Melbourne bounce to actually zoom in with the zoom value of ten. And that will be all for this video. Now you've seen how to actually create boundaries on the map using, for example, to bounce lake, Southwest and Northeast. And in the next video, I'm going to show you how you can restrict camera view. 14. Restrict User from Scrolling: Hello there and welcome back. So in this video, I'm going to show you how to restrict users camera view to a specific location on the map. Now in the previous video, you've seen how to set boundaries on the map, but then a user would be able to move around without any restrictions. And now I'm going to show you that. So I'm going to just call this new lat long bounds. And let's run the app again. Ok, so after a few seconds, we should be able to see our map with those boundaries which we have specified in here. As you can see, we can actually move around the map. And now I'm going to show you how we can restrict that move with the camera. The debt can be useful sometimes when you wanna constraint those boundaries and allow a user to move only within those boundaries are k. So now let me show you how you can restrict that camera movement. So here I'm going to call a new function named the set left long bounds for a camera target. And here I need to pass this Melbourne bounds. Okay, and now let's run this app and you will see that now we should be able to restrict our users movement on the map. Ok, so after four seconds we can see our new Melbourne bounds. And now when we try to scroll, as you can see, I can scroll to the some point. Ok. But nothing more than that. So if I try to scroll above those boxes boundaries, I wouldn't be able to do that. Okay. So as you can see, I can now scroll anymore up. And, and we are basically restricting our users camera movement. So now we can see only this, some airborne and of course, so we can zoom in and zoom out, of course, about those bounds cannot be passed. And that's how you're able to restrict their camera movement or the actual scrolling or the map. So a user will be able to move around only within their boundaries, which we have specified in our Melbourne bounds variable. And that'll be all for this video. 15. Animate Camera Movement: Hello there and welcome back. So in the previous videos, you've seen multiple examples of changing camera position, tilting the camera, using your boundaries, zooming in and out. But none of those examples, he had an animation. So we're whenever we updated our camera position with a new location, that change was made in an instant without any animation. Now, in this video, I'm going to show you how to make user experience more pleasing, especially for a short moves by animating the change. So we're to create any animation and we will need to replace Move Camera function with the function name the Animate Camera. And now I'm going to show you that. So first let me run this PR once again so you can see how our application looks. So without any animation. So after four seconds, we're going to get navigated to Melbourne City without any animation. So now what we need to do, we need to replace this movie camera function with Animate Camera. Now, k in here, as you can see, we have three different constructors. So the first one I said only camera update. The second one accepts camera update, then cancel or call back. In the third one accepts three parameters, and this integer value in the middle is the actual I mentioned duration. So we're going to use this third one. So here, as you can see as the first parameter, we have specified our camera update. Then as a second parameter we need to add the animation duration. So I'm going to add, for example, two seconds. And here for this cancel or call back, I'm going to set the null for now, but later I'm going to show you how to use this callback as well. And I'm going to comment out this line of code because we not need to set any restrictions now. Okay, so now let's run the app again. And you will see that after four seconds, we're going to get an animation from Los Angeles to Melbourne. And there we go. So let me run that tip again so you can see that once more. So this is a very good user experience because we can see how our camera is transitioning between one city to another. And as you can see, I have specified that this animation should last for two seconds, but you can make that animation longer or shorter, so that's on you. We can also use this Animate Camera on our code right here, so we can replace this move camera to Animate Camera in here. I can also set the duration, for example, to maybe, let's say four seconds and there's a whole bag, I'm going to set null. So now we're going to see an animation for our Los Angeles as well. So let's run our app. Okay, so let me run the app again so you can see that animation once more because of the map was loading and we couldn't see anything. So let's see if this time the map we'll load even faster. Rk. So sometimes it might happen that the map will not show immediately. So you will not be able to see that enemy at this moment. But don't worry, I'm going to replace this to move camera as it was before. We can also use this Animate Camera function to animate zooming in and out. So for example, I'm going to comment out this line of code. And I'm going to use this one. And we look paste that right here. I'm going to call Animate Camera. And here I can call a different function. For example, it's a zoom tool. And I can say here, for example, are 15 r k. So for the duration I can set two seconds and the third parameter can be null for now. So let me run that tape again and you will see that the after four seconds, we're going to use animation for zooming out, or sorry, zooming in. So basically we are animating our zoom level from ten to 15. And let me run that again so you can see. So after four seconds, as you can see, we have zoomed in via Fiverr zoom level value. So basically you can use this Animate Camera function to animate everything on the map. So for example, I can also use this scroll by function in here I can pass, for example, let me see 200, and here I can pass 0. So now I'm going to set here a duration of two seconds as well in here and null. So let's run that again. Now k, So after four seconds, we're going to scroll on the right side. So as you can see, slowly, r, k. So this Animate Camera function works perfectly fine with scroll by function as well. And we can also animate different properties of our camera, like for example, Target zoom bearing n tilde. So now I'm going to call this camera position name there, Los Angeles from our Maps activity. And I'm going to remove this line of code. I'm going to cut this part of the code from earlier, r, k in here. I'm going to comment out this time. So I'm going to change the small camera to Animate Camera in here also, I'm going to pass two seconds delay are Canada, the perimeter can be null. So here now you will see that we are going to be able to animate all those properties for our camera position object like target, zone bearing end tilt. So let me show you that. Let's run our app. And after four seconds, you should be able to see one beautiful animation. Now. Okay, so now as you can see, we have animated all those properties which we have defined inside our camera and view port class like target, zoom, level bearing, end up tilt. And finally, I want to show you how you can add a call back to your Animate Camera function as well. So now let me see, we are going to remove this now and I'm going to call google map dot cancel a ball callback. And here I'm going to override the two methods, so on finish and on cancel. So here I can just display Simple toast message. So this add Maps activity here I can say finished and here I can set the toast length two short R, k. And I can copy this, those message down below inside this on Cancel function in here I can say cancel. So this finish function will be called whenever our animation is completed. And this Cancel function will be called if we cancel our animation. So now let me show you that. So now after our animation is completed, you will see a toast message that says finished. Okay, so there it is. And now let me just run that app again so I can show you this on Cancel function as well. So while this animation is triggering, I'm going to cancel this animation by moving it and I'm going to receive that message. So that's how you can implement those to cancel callbacks. And I'm going to remove all those quotes for now and that Toby all for this video. So now you have learned how you can animate your camera movement and also how to trigger callbacks whenever your animation is completed or when it's cancelled. So that's it for this video. 16. Single/Long Click Events: Hello there and welcome back. So why in this video, I'm going to show you how you can add the single and the long click listeners for your map here. So for that, we're going to create two different functions. So let me create the first function on map clicked in here we're going to call our map object and we're going to call set on map click listener. So basically this will trigger whenever we tap on our map with a single tab. So let's hear this player Simple toast message. So this then I can say here, single click here, I can say tos dot Elaine short. And I can display that OK. And now I'm going to create one more function for handling along click. So private fun on math along clicked R, k. And here I can call map object, then set on long click listener. In here I can just paste that same Toastmasters, but I'm going to replace that too long click in, of course we can call those two functions from our own map ready. But of course I can comment out this coroutine because we're not going to use that right now. So let's call on map clicked and the on math along clicked. Ok. So now let's run our app. And basically whenever we tap on our map, one time we're going to receive this message that says a senior clique. So let's click here. Ok, so you can see that we have received this message successfully here. When I click again, we are going to receive that as well. So it's working perfectly fine. And also when we track and long clicker or a long press on our map, we're going to receive this long click Message. So those two listeners works perfectly fine and that they can be very handy, for example, when we are working with those markers. So for example, we can implement the logic to add a new marker whenever we long press on someplace right here. And also those click listeners will receive the executor let longer object, or basically the exact position on where we have pressed on the map. And here, for example, I can just type it than longitude, and I can also it dot latitude alkane. So for example, now let's run our app again. And you will see whenever I press or long clicker on our map, then we are going to receive the exact coordinates of that place. So let me just long click right here. Our K. So there you go. So those are the exact coordinates of that same spot which require pressed inactive, for example, zoom in somewhere to actually trigger this long clicks. For example, here, let me alarm click here. And now we have different coordinates. So that's how you can get the coordinates from those listeners. And for example here we can also call this addMarker function. So let me just paste that right here. In here instead of this a Los Angeles I can just pass it, which is referring to LatLng objects from this on long click listener. And here I can just say a new marker, R k. So let me run the app again. And now let's zoom in for example, and I'm going to long click here for example. And there we go. So we have created a new marker on our long click. And as you can see, it's working perfectly fine. So that was all for this video. Now you've, you've learn how you can implement the single click and an on-click listener on your Google Map. 17. About Markers: Hello there and welcome back. So well, with this video, I'm going to start talking about markers. So we're in the previous videos of this course, you've seen how to place a simple marker on the map, but now we're going to get a little deeper than that. So markers are used to identify a location on a map, and the default marker uses a standard icon which is widely recognized in a Google Maps API with this red icon. Now, with the Google Maps API, we can customize some are marker properties like color, image, opacity, anchor point, rotation, zed, Index, tag, and so on. So we're markers are incorrect and they receive a click events by default, in the typical single click event will bring up in an info window. So for example, when we click on this marker, you're going to see these info window appearing right here. And we have also specified this info window title which says monitoring the Los Angeles, you know, whenever repress our marker or we are going to be able to see this toolbar down below. But of course you can disable this toolbar, and I talked about that in the previous videos. So this worse and there we're going to talk about info windows in some of the next videos. Okay, so now I'm going to just to remove those two functions because I'm not going to need them anymore. K. So you have already seen how to basically place or create one marker on the map. And for that we need a Google Map object. And then we can use this addMarker function. And inside the parameters of this function, we are placing a marker options in here. We're setting the actual position of our marker with the latlng object in here, as you can see, we're also calling a title to set the title of info window. There are also some other customizations for markers and I'm going to talk about them in the next videos of these squares. So for now let me just show you one thing. So I'm going to show you how you can remove a marker from the map. And first let me just create a new variable name, Los Angeles marker. And we're going to store the result of this addMarker function inside our new variable. And this variable type will now be a type of a marker. So now this variable will hold this marker object and then we can call that same marker object. So Los Angeles marker in, we can access some functions of this marker object. So for example, let me just remove that for now. I'm going to uncomment this lifecycle and let me just add one line of code after this delay. So after a delay of four seconds, I can call this a Los Angeles marker in I can remove that marker. So now let's run our app and let's see how will that work. So now when we run our app, we're going to see this marker in after four seconds, it will disappear. So that's how you're able to basically remove a marker very easily, r, k. So I'm going to remove now this line of code, and that will be all for this little introduction video. In the next videos, we're going to continue exploring markers object. 18. Store Data Object in a Marker: Hello there and welcome back. In this video, I'm going to show you how to save n arbitrary data object in a marker using a set of tagger function and also how to retrieve that same data object. So this can be useful in some cases. For example, if you need to distinguish the different types of markers and there now and we'll show you how to do that. So the first thing, let's open up our Maps activity. And here in the last video we have made a new variable named R Los Angeles marker. And there we have saved our marker object from this function. Using this addMarker function, we have saved a marker object into this variable. So, uh, down below, and we will call this new variable, and I'm going to set a new tag on our marker. So here I'm going to use the double-quotes. And for example, I'm going to type here restaurant. So that's a specific tag which we added to this specific marker. And now I'm going to show you how to retrieve that same tag. So the first thing that we need to add the click listener for our marker. So I'm going to add that click listener right here. So comma then on marker click listener. Here we need to implement a new function ON marker click. Okay, so here I'm going to rename this P two marker and let me just remove this line of code here. I can just use the log statement and I can write here a marker in here. I can call this marker object, then tag. And I can convert that to a string. And here I can also add the if block to check if this marker is not null. So if a marker is not null, then I can call this log statement. And inside the else block, I can just bring something different. So here I can say, for example, our empty RK. And here as you can see, we get a warning from this one marker click. So as you can see, this function is returning a Boolean value. So setting a return value to false will indicate that we haven't consumed this event and that we wished for a default behavior to occur, which is for the camera to move in such a way to be centered and for the markers info window to open if it has one. So for example, if I return here are true, then let's surround the app. And now you'll see that we're no longer be able to show this in for dialogue, which says basically marker in Los Angeles. Okay, and before we run our application, let me just set this marker click listener inside our own map. Ready? So here I'm going to comment out this code for now and hear me to call map object, then set or marker click listener in here and we will pass on this. And this is referring to this one marker click listener which we have implemented on our maps activity. And now let's run this app and you can just observe this logcat as well. Ok, so now when we press this marker, you will not be able to see this info window which says a marker in Los Angeles because we have a return, true. So let's click on that. And as you can see, this info window will not show up. But we're going to see this tag which we have saved on this specific marker. And as you can see, we have successfully retrieved that tag from earlier. And now lets return here false. And now let's run the app. And now you should be able to see this for window from before. So let's click on that r k. So now we can see this default behavior of our marker click because we cover return false. So be sure to remember that. So if you return shrew, then this default behavior will not show up. Instead, you need to return a false for that end there. Now you saw how you can store a simple arbitrary data object into your marker Sowell, that's it for this video. 19. Enable Marker Dragging: Hello there and welcome back. So in this video, I want to show you how you can make your marker draggable. So basically on long press, you should be able to move this marker anywhere on the map. And now I'm going to show you how you can easily do that. But before that, let me just remove this ONE marker click function. And also I'm going to remove this all marker click listener and from here as well. So by default, our markers are not a draggable. So as you can see when a long press on that, nothing will happen. So what we need to do, willing to go here and we need to add the draggable to true. So pass here true. Now let me just run this app again. So now when you long press on this marker, you will be able to move that around, okay? And you can place that anywhere on the map by releasing the mouse click, so like that. And also you can implement a drag event. So let me just go here on the top. And I'm going to search for on marker, drag listener. Here I'm going to set map, dot, set marker drag listener. And here I'm going to pass on this, which is referring to our Maps activity in here. Let's press all plus Center and let's add that those three functions. So we have three functions on marker drag start one marker drag, and all marker drag end. So here in each of those functions, I'm going to log a simple log statement. So I'm going to say here and drag here a start, and we'll do just copy this line of code here. I'm going to say just drag in here and it will say end. And now let's run the app and let's observe our long kit here. So let me just write and drag now. Okay, so now when a long press and we're going to see a log that says a start. And when I move that around and we're going to receive a multiple times this log statement which says a drag because we are currently in a process of dragging our marker. And when I place this marker here and release a mouse-click, willing to receive this logged it says, and so that's how you are able to drag the marker on the map and also how to implement this drag listener. And from here we can use this marker object to do different things. So for example, to get the tag, to get DID to see if it's a draggable, if it's a flat, if it's still visible to get a position rotation snippet, title, zed, index and so on. So there are plenty of things which you can do with this marker object, and that'll be all for this video. 20. Marker Customization: Hello there and welcome back. In this video, I'm going to show you how to customize marker properties that affect the visual behavior of the map. So first we're going to start by changing the color property of this marker. And before that, let me just clean this map's activity are a little bit. So I'm going to remove those overrided functions because we're not going to need them anymore. I can remove this as well. And let me just remove this listener r, k. I can remove this line of code as well. And now in order to change the color of our marker, willing to add the icon function here. So let me just clean up this code a little bit. So now I can remove this draggable. We don't need that anymore. In here I'm going to add a new function named the icon. And the, as you can see, this icon accepts only one parameter and that is Bitmap descriptor. And here I'm going to call a bitmap descriptor factory. In here. I'm going to call a method name default marker, and that this default Marker accepts only one parameter of type float. And here basically we need to specify the exec color of our marker, which we're going to use. However, we cannot use any color there is, and we can only use Hue colors which are defined inside the bitmap descriptor factory. So I'm going to call Bitmap descriptor factory. And here we can choose some of those already defined float values. For example, humans into a zoo or a blue sea and green, orange, red rose, a violet, and yellow. And so far there is no, any easier way to, to add custom colors. So for now we can choose some of those already defined that colors. For example, let me chose this orange for now, are okay and let's run the app so you can check that out. Now our k. So as you can see now we have received this orange color for our marker. And there is a way of you to pass at customer hue value of a colour. So as you already seen, this default Marker accepts float value and you can specify our customer hue color value from 0 to 316. And now let me just open a web browser to show you that you can choose some of those values for a hue color. So be sure to visit this website name the W3 schools.com slash colors, Slasher colors underscore H, S, L dot ASP. So here as you can see, we have this H or S L calculator, and H stands for HU, S stands for saturation, and L stands for lightness. So in our case, we're only going to focus on the heel property. In this, you can see we have a different values for these Huo property from a 0 to 360. Okay? So now as you can see, whenever we scroll or move our mouse over this huge scroll bar, and we can see that this scholar is changing. So for example, let's say that we want to choose this green color for our marker, so 134 or k. So let's get back to our Android Studio and let's type here 1234, right? And type f. Okay, so now let's run our app and now we should be able to see green color for our marker. And there you go. So this is one way which you can customize your marker color by going to this website and checking this HSL, our calculator to basically select heuer value color for your marker. And then you can just copy that same value and apply that to your project. So now you might be wondering, how can we apply grey or black colour to our marker? Well, you cannot do that with this default Marker function, but there is a workaround. So instead of using this default marker, we can use our own custom marker in. We can load that marker from, from our resources. And we can choose either a vector file or bitmap object. And we can choose either a vector or a bitmap, but you cannot actually use vector files directly here. And I'm going to show you why in how to pass over that as well. So now I'm going to remove this default Marker function. And here as you can see, we have some different functions like from resource, from asset, from bitmap, from file, in from path. And basically each one of those function will allow you to specify marker image by using some external resource. And if, for example, we can use this from resource function in here we can specify some resource ID. And there, for example, I have already added the fuel resources in my project. So as you can see, when I open this drawable directory, I'm going to see this vector file named the IC enjoyed. And this is basically a vector image or vector icon which I have added to this project by going to a new vector asset. So this is a vector file and I, he also important this custom marker PNG image. And this is basically a simple PNG image which represents our marker in a green color. So now let's try and specify here our daughter drawable dot ICN Android. So this is our vector file. Okay, so now if we try to run the AMP, our application will crash. And that's because we cannot use those vector files directly inside this from resource. And instead that we need to convert our vector file to a bitmap, okay? And to convert our vector file to bitmapped, willing to create a new function for that. Now for that, I'm going to create a new function right here. So down below with me, just so private fun from vector to bitmap. And this function will accept two parameters. The first one is the actual ID of our drawable resource. So the type should be integer, and the second one will be the actual color of a type integer as well. So the return type of this function needs to be Bitmap descriptor, Now k. Next, inside this function we are going to create a new variable named vector drawable in the type of this variable should be drawable with a question mark because this variable can be null. In here, I'm going to use the resource. Compet dot, get a drawable in hearing to pass the first the actual resource. So I'm going to use resources from i get resources. The second parameter is the actual ID. So I'm going to pass that ID from the parameters of this function. So ID in the third one needs to be null. So after that, and it will check if this vector drawable is actually null. So if this vector drawable is null, then I'm going to just log a simple statement here. I'm going to write here maps activity for example. And here I'm going to say resource and not found in here. I'm going to return Bitmap descriptor factory dot default marker. Okay, so if our resource is actually null, then we're going to return a default marker. And with that we can avoid any exception. And otherwise we want to create a new variable named bitmap in hearing me to call bitmap dot create bitmap. And here we need to pass through different parameters. So the first one we need to pass a vector drawable, our drawable variable from the top, Datta intrinsic width. Then I need to pass a vector drawable dot, intrinsic height and excitory perimeter. I need to pass bitmap dot config dot a RGB 8888. So this one. So with this, we want to create a new bitmap object in here for the width and height of this bitmap, we are specifying the actual width and height of our vector drawable. In here we're specifying the actual bitmap config and after data into create a canvas object, so variable named canvas in hearing me to call a canvas. So this one, android.jar graphics and insight into past our bitmap object. So after that, I need to call our vector drawable object or our drawable object. Then it'll set the bounds in here, me to pass for the left and top and me to pass 00. Here I need to pass cannabis with in here a canvas height. Next, what we want to do, we want to set the actual color of our new bitmap object or actually to our vector file, but which will be converted to a bitmap. So let's use a drawable compat dot settings. In here we need to pass our vector drawable object in the second parameter is the actual color from the parameters of this function N. Finally, let's call our vector drawable dot. Draw in here, let's pass a canvas or ok. And finally, just to return bitmap descriptor factory dot from bitmap. And here we need to pass our bitmap object. So I, that's how we are able to convert our vector asset to our bitmap object. And we can return a bitmap descriptor, which is actually returned from this bitmap function of this bitmap descriptor factory class. So we're basically inside this function, we are creating a drawable object out of the resource ID off our vector file. Then we're going to create a bitmap object for our vector file. Then after that we are creating a canvas object and we are passing our bitmap to actually draw our bitmap on the cannabis. In here we're setting the abounds in setting the color of our vector drawable. Finally, we are drawing our vector drawable on the canvas. And inside this from BITNET function, we are passing our bitmap, which we hear created inside this function. And now we're going to remove everything from this eigenfunction because as you can see, when we pass this vector drawable directly, we're going to receive an app crash. And now let's hear call hour from vector to bitmap and he'll its best our ID. So our edata drawable dot ICE Android in here we can specify the actual color which we will use on our, on our vector drawable in here, I can just call our color dot parse color. In here I can specify the actual a hex code of the color inside a string. So I can pass here, for example, the black colour in later. We can change that. Okay, so now let's run our app again and let's see if our marker icon now we'll change our k. And now as you can see, our marker icon has been changed. And we have basically used our vector asset and converted it to a bitmap. So we can actually pass that to our icon function right here. And of course we can specify a different color inside the parameters here. So now let's run our app and let's see which color should be get now our case. So as you can see now, our Android icon is green. So that's how you're able to basically use custom colors on doors markers by using a custom vector drawable files, or by using a bitmap files as well. And for that, we can just remove this line of code. Now in here we can call Bitmap descriptor factory, not from resource in heroic and Bess are drawable dot-dot custom marker. So now our application or will not crash because this is not a vector drawable. It is a bitmap n. Now as you can see, we have our new marker image on our map. So now you've seen how to customize this marker color in how to specify a different into resources as well. And now I want to show you just a few more properties which you can modify hero. So now we also can modify our alpha value in here we can set the actual opacity of our, of our marker. So I'm going to remove this icon for now. We will use the default icon in here, let's say 0.5. So the 0 value here is a total transparency and one is for visibility. So now we're going to set half visibility for our marker. And let's run the app so you can check that out. And there we go. So now our marker is how transparent. Next we also have rotation, so we can rotate our America as well. So I'm going to rotate for a 90-degree. Let's run the app so you can try that out. And that there we go. So now our marker is rotated, so it will keep its rotation position. Our rotational will not affect the rotation of our marker. And finally, I want to show you one more property, which is called the flat. So we're marker icons are normally drawn with respect to the screen. For example, are rotating, zooming and tilting them at will not change the orientation of the marker. Now, you can set the orientation of the marker to be flat against the Earth and the markers that are oriented this way, we'll rotate when the map is rotated in change perspective, when the map is a tilted and flat markers will however, retain their size on the map when you'll zoom in or out. So now I'm going to set the value for this flag to true. And it's, the default value is false. And now you'll see whenever we rotate on the mat, this marker, we'll rotate as well. Okay, so you can see this marker is rotating while we are while we are rotating on the map as well. So as you can see, that's how this flat property is there working, and that'll be all for this video. So you saw how we can customize our marker icon and color and so on. How can we convert director to a bitmap as well? And that will be all for this video. 21. Marker's Z Index: Hello there and welcome back. So why in the previous video you've seen how we can customize our markers properties. And in this video I'm going to show you how to specify a zed index to your markers on the map. So what is this so-called zed index? Well, basically it specifies the stack order of the marker relative to other markers on the map. So a marker with a higher zed index will be drawn on top of other markers with a lower set index and the default set index value is 0. One more thing, markers are always drawn above other layers and overlays, Blake ground overlays, polylines, polygons in other shapes regardless of the zed index or the other overlays. So markers are considered to be a separate zed index group compared to other overlays. And I'm going to talk about those other overlays in the next video. So these squares, but for now we're going to focus on zed index property of our marker. So before we continue, I just want to move this function in some other class. So I'm going to press Control X to cut that. And I'm going to create a new class here named the markers. And inside this class I'm going to paste that function. I'm going to now comment out this function because we're not going to need that anymore. But of course I'm going to leave that into this new class so you can actually copy the code if you need it. So the next thing I just want to clean up this code a little bit. So I'm going to remove this fled from our previous video. And here I want to create a new marker. So I'm going to create first a new variable named there, Los Angeles number two in here I want to specify a newer values. So for that, I'm going to open up Google Maps in here. I'm going to choose one or spot inside Los Angeles. So for example, right here and I'm going to copy its longitude and latitude values, okay, now I'm going to paste those values right here, and then we'll create a new marker. So just copy this code here and then we'll change this to marker number two and hearing me to specify Los Angeles number two. Ok, so now let's run our app and let's see if we're going to see two markers on the map, R, k, So we can see those two. And as you can see when a zoom out, so let me just zoom out a little bit. So now you can see that those two markers are overlapping. So you can see that now this first marker is actually on top of our, this second marker which we have added. And now we can change a del zed index off our second marker to be on top of this first marker N. To do that, we just need to. Here, I knew functions. So Zed index inhuman to PES float value. So the default index value for our markers is 0 in here. If I best so one, then one is basically greater than 0 in this second marker will now be on top of our first marker. So now let's run the app so you can see the change. Now k. So now when a zoom out, this first marker will be behind our second marker. Ok, and there we go. So that's basically Zen index property of our markers. So you can specify this stack order of the marker, and that'll be all for this video. 22. About InfoWindow: Hello there and welcome back. In this video, I'm going to talk a little more about info windows. So an info window allows you to display information to the user when they tap on a marker. And if you have a one info window opened or now one marker and tried to open another window on a different marker, then the first one will be closed there automatically. And that way we are allowed to display only one info window at a time. So we're now, I'm going to show you how you can add description to this title. So as you can see, our info window is consist of just one text which represents a title. And now we're going to also add the subtitle or a description to our info window as well. So basically on our marker here, we just need to add a new function name the snippet. And here we need to write anything we want. For example, I'm going to write some random text and I can write this snippet here as well on our second marker. And now let's run the app to see how will that look like. Okay, so when we click on our marker, and now you should be able to see this text which represents the title. And down below this subtitle or some kind of a description text. So it's very easy to create an info window. We just need to specify this title and snippet. Also, you can show or hide this info window programmatically by yourself. And now I'm going to show you how to do that. So what the first thing, which I'm going to do, I'm going to add the marker click listener. So here I'm going to add on a marker click listener. I'm going to implement this one method. So all marker click and here inside our own map ready, I'm going to call Set on marker click listener. And I'm going to pass this in the parameters and alkane. So I have already talked about this one marker click. And if we return here, true, then whenever we press on our marker, the info window will not show up. So let me show you that again. So if this ONE marker click function returns true, then whenever we pressed when our marker, the info window will not show up. So as you can see, it doesn't work. And that's because we can return true here. And that means that we have a overridden the actual default behavior of this marker click. But if we return here of false, then we should be able to open this info window when we press on our marker. And as you can see now when I press that, we're going to see this info window. So for example, it can be useful to animate the zoom in animation whenever we press so when our marker, so let's say we can here call this p 0. Let me just rename this variable to marker. Ok, so here I'm going to call Google Map object, and I'm going to call a method called the Animate Camera. So here I'm, it'll call camera update factory and I'm going to call a zoom tool. And here I'm going to pass 17. So basically whenever I press on one marker, I want talk immediately enemy zoom in effect in, we're going to zoom in. We zoom level of or 17 in here. We also need to specify this animation duration. It can be, for example, two seconds in the third parameter is the actual call back. I'm not going to need that, so I'm going to pass null. And now let's run our app and let's see how will that work. So as you can see, when I press this marker, we're going to see these info window, but we're not going to see any animation. And that's because this ONE marker click user returning false. And I already mentioned that if you are eternal false, then only default behavior or will be applied to this click listener for our marker. But there is a workaround. So we can return here a true and still show our info window. So here I can call a marker from the parameters. Then it's function showInfo window in here I can passengers question mark because this marker is a nullable. So now we're returning true here. And also we're going to be able to animate our camera plus to show info window at the same time. So let's run our app again to see if that's going to work. So now when we click on this marker, we should be able to zoom in and also show an info window. So click here, and there we go. So now we have shown this info window successfully and plus we hear us on in. So that will be all for this little introduction video about info windows. And in the next video, I'm going to show you how to fully customize this info window layout. 23. InfoWindow Customization: Hello there and welcome back. So in the previous video, I have introduced you with Info window and you saw some interesting examples. And in this video I'm going to show you how to fully customize this info window layout. So before we continue, I just want to remove the code we don't need from here. So I'm going to remove this click listener than this. And also I can remove one marker because we are not going to need that anymore. Okay, so let me just remove this listener as well. Alright, so the first thing which we need to do when we are trying to create a custom layout for our info window, we need to create a new layout. So let's open up our layout directory in here. Let's create a new layout resource file. And the name of this file can be custom info window, our case or press OK. And here I'm going to add one ImageView and two text views. So firstly, it's said that one image view here and when to select, for example, this one. So this is just four example of course, I'm going to connect here left, top and bottom constraint. So all constraint can be 0. Next, I'm going to set this layout height of this root layout to wrap content. The layout, width and height of this image can be, for example, 100 dP. Okay? Next time we're going to add one TextView here, which will represent the title. And let's constrain that to a top here. Here I can add eight DP margins, and here as well, I can add one more TextView. Let's constrain their right here and here. Okay. I'm going to constrain this on the right side as well. Our case, let me place that here. And I'm going to connect this right constraint to apparent here as well. And I can connect this bottom constraint here as well. So here I can set a bottom margin to eight, right margin to eight in here, right margin to eight, our case. Let's just modify a few things. So when we need to change the ID of this first TextView suppressor Shift plus F6. And I'm going to change that to title TextView clicker refactor. Next thing were to change this ID to something different. So maybe description, text view. Okay, click Refactor. Here I'm going to just write some simple text saying, for example, our title. So it doesn't matter what you write here, we're going to dynamically get the text in the description from our Maps activity. Here I'm going to set the text color to black, text style to ball. And the text size can be, for example, a 16 SP. Here I can write something like some random text, R, k, So it will look something like that. So we're here for the title. I'm going to add a few more attributes. I'm going to say a number of lines one, maximum number of lines one. And I can say ALIP size here to end. So basically we will not be able to see a title which is longer than a one line. And that's why I want to constrain this text view to show only title in one line in here for our description text, I can add the same thing next slice, but this time I'm going to say max lanes of three, r, k. And here ALIP size to end as well. Oh, okay, okay, so for now I'm going to leave that layout file and later we might come back to modify that if we need to. So the next thing which we need to do, we need to create a custom info window adapter class. And for that I'm going to create a new quilting class inside this package. And the name can be custom info adapter. Oh, okay. So this class should inherit from info window adapter. In here we need to override the two functions and get info window and get info contents. So click OK. So the API will first call this get info window function. And if this function returns null, then this get info contents function will be called. And if this function also returns null, then the default info window layout will be used. So the first thing which I want to do, I want to add there just one parameter in the constructor of this custom info adapter, and that is the actual context. So down below I want to create private var variable named the content view. And I'm willing to cast that context as activity and the utter that I'm going to inflate the layout which we just created. So a layout inflator Then let's call inflate. In here I'm going to pass our dot layout and dot. Okay, so let's just import this, our, our case OR here lets call custom info window and the second parameter will be null, okay, and before I get into those two functions, I need to create one function which will basically set the text or the title and description text on our info window. So I'm going to name that function. Render views are okay, and this function will accept two parameters. So marker, it will be nullable because this marker from getting info window and getting four contents is a nullable as well. And the second parameter will be the actual view. So I'm going to name that content view of a tie preview. So here I'm going to create two variables, and the first one is a title, and I'm going to get that title from our marker now K, the second one is description, and we will also get a description from this marker and we choose a snippet. Okay, then down below I need to create a title text view. And here I'm going to call this content view dot findViewByID. Here I need to pass a text view, and here I need to inflate that view. So title text field n down below and introduce this title TextView to set a text. And I'm going to use this title variable from the top in which we have placed our title in the marker and down below and integrate one more variable description text view in here. I'm going to also use this content view dot findViewByID hearing to pass a text view in here, r dot id dot description, TextView, and here description text field dot text. And let's set the text from above. So now we need to call this surrender viewers function from both of those functions. So first let's call here. So our render views here and it'll pass marker. So let me just rename those variables to a marker. And here as well as the second parameter is a content view. And finally, I need to return here a content view. And I'm going to pass basically the same two lines of code inside this second function, r, k. And that's all we need to do for our customer unified data. Of course, I'm not going to change the actual image view from our customer for adaptor because I have already added there one simple image joule, but of course you can't do that from here. You can just get the reference of that image x2 and just change the image. So we're the next thing we need to go to our Maps activity. And here inside our own map ready, I need to call Google Map object. Then I need to call set the info window adapter in hearing, it'll pass our custom infrared debtor class. And here we need to pass the context, which is actually this, which is referring to activity. And I think that's all we need to do for our Customer Info window adapter. So now let's run our app to see if this new layout will be shown. Okay, so click on this marker and as you can see, we can see our actual layout, but our background is actually transparent. So what you need to do, and we need to go to our custom info window layout in here. I need to set the background color of this layout to white. And now let's run this app again. Okay, so I'll click here, and there you go. So that's it for this video. Now you'll learn how to create custom info window layout using this custom info window adapter. And that'll be all for this video. 24. Introducing to Polyline: Hello there and welcome back. From this video, we are going to start exploring different kinds of shapes which we can draw on the map. And in this current video, we're going to focus on creating a polylines. So well, what is polyline? Well, a polyline is basically a set of lead long girl locations, which forms a line segment that connects those same locations in order the sequence. So now we're going to create one polyline and first let me just clean up this activity a little bit. So I'm going to, I remove this info window adapter from here. So now I'm going to create a new function down below. So private fun, add, polyline came. So here first I'm going to create a new variable named the polyline came. And from here I want to call Google Maps object. So a map dot add polyline. And here I want to specify a polyline options object. So here I'm going to call polyline options. Then I'm going to use this applier scope function. And after that I'm going to call this function. So as you can see, this add function accepts multiple a LatLng objects or one of LatLng objects. So basically inside this function, we need to define the exact points or locations on our map, which we want to connect and create a simple polyline. So for example, I'm going to use the already defined their LatLng objects like Los Angeles and New York. And let me just cut and paste those two lines of code as a global variables on the top. So right here, let me just add the private access modifier as well. Alright, so down below we need to call those tools. So Los Angeles first and then a New York. So basically our polyline now will start from a Los Angeles then to New York. So be sure to follow that sequence order. So this is the first path or the first, and this is the second one. Ok, so let me just remove this dot. We don't need that. Next, we can specify the actual width of our polyline in here I'm going to say death to, for example, it's a five. And we can also specify the color of our polyline. And here I can choose, for example, color dot, let's say blue. Okay, and now let's call this function from our own map. Ready? So right here, and now let's run our app to see how will that work. So as you can see now, we can see one line or a polyline which starts from Los Angeles. And that's the first which we have added inside our add function. And then this polyline will end on a New York. So let me just zoom in a little bit more or ok. So now as you can see, this polyline is ending it New Yorker coordinates. And now let me add one or two more locations. So I'm going to just zoom out here on Google Maps and let's see. Okay, so let's choose, for example, Spain. Choose Madrid or K. Right-click. Then let's copy that and I'm going to paste a new coordinate inside our add function. So let me create here private vol K. So let along object R, K, Now K, So like that. And now let's copy this new latlng object right here. So as uttered, the value inside our add function, and now let's open our app. So let's zoom out a little bit. So now as you can see, our polylines starts with Los Angeles. Then the middle point is a New York, And then we are going to Spain. So this is how it looks like. So it's basically a simple line and I just want to show you one more interesting function from our polyline. So the name of that function is geodesic and it basically specify whether to draw each segment of this polyline as Gail DESeq. So default value is false and now let me just add it to true so you can see the actual change which will occur now. So let me just zoom in a little bit. So now you will see that those lines are not straight. And as you can see, those are basically now arcs. But actually this geodesic, we'll draw our lines in a way that it will follow the actual shape of our world. And our world is not flat, it's surrounded. And that's why we can see those arcs instead of straight lines. So this is a quite useful function to user with polylines as well. Now, you can however, change the shape of the polyline after it has been added. And for that you can call set points or function and provide a new list of locations. So now I'm going to show you how to do that. So first let me open a Google Maps here. And for the second, I'm going to choose some different city. For example, let me just choose maybe Panama, okay, and we will copy its coordinate. And now let me just create a new variable here. So Panama, and let's paste the new coordinates r, k. And now let's scroll down below. And inside this function, I'm going to call this polyline object, which is basically the return type of this ad the polyline. So as you can see, the return or the type of this variable is a polyline and that's a return value from this polyline function. So from here we can call points. In here, we need to specify a new coordinates or appoints which run to change. So here for example, I'm going to create a new variable named new list. So I'm going to use a list of lat long as a type of this list. And here I'm going to specify now, let's say Los Angeles, and then a, Panama, then Madrid, r k. Also we can remove this. We are actually not needed and we can specify this new list right here. Okay? So in order to make more sense, I'm going to add the delay function of coroutines right here. So let me just first at the suspended keywords here. And now I'm going to use here a delay of, let's say for example, five seconds. And I'm going to call this add polyline function inside this lifecycle scope. I'm going to remove this delay now, okay? Now, when we run our application, you'll see that after five seconds our polyline will change. So let me run the app again. Let's zoom out really quick. And now after five seconds, you will see that this polyline has been changed. And that's how you can change the actual polyline by using these points function or actually set points in here, you can just specify a list of coordinates or a newly store for LatLng objects. Now, you can also add a click listener for polyline. So for example, we just need to add here on polyline click listener in here we need to override a new function. So on polyline, click in here, say on a map ready, we need to add the map dot on polylines set on polyline click listener. So this one in here, we can just, just paste this in here. We can display a simple a toast message. So let's run the app and let's see how will that work. So now we're only press on our line, we should be able to see a toast message. Okay, so let me just click here. So as you can see, nothing happens even if we click on this polyline. And here we need to add the clickable to true because the default value is false. And now, when we run our app, you will see that now our polyline will be clickable. So let's just wait five seconds until our polyline changes. And now click here and you will see this message. Now, there is one catch when it comes to click listeners. So now let's imagine that your map is filled with many shapes which are overlapping. So if a multiple overlays or shapes like markers, polylines, polygons, and others are overlaid on top of each other than the click event is a cycled through the cluster of markers first. So markers are always on top of all other drawings on the map. And then after that click event is triggered for other clickable overlays or shapes based on their Zed index value. So at most, one click event is triggered per click, and click is not passed down to do overlays or shapes with a lower index value, our case. So that will be all for this video. Now you saw how to create one simple polyline and help to change its shape after few seconds by using this set points a function. And you also saw how to customize our polyline by changing its with color and a few other attributes as well. And you also saw how to add that click listener, Sowell. That'll be all for this video. And in the next video we're going to focus on are polygons. 25. Introducing to Polygon: Hello there and welcome back. So in the previous video, you've seen how to create a polyline, and now I'm going to show you how to create a polygon. So a polygon is similar to a polyline in a way that both of them consists of a series of coordinates in an ordered sequence. So before we create a polygon, let me just create a new class and move that code from the previous video in that I knew class. So I'm going to create a new cotton class name. The shapes are came in here. I'm going to cut this function. I'm going to paste that inside this new class. Now came, and now let me just remove this function from this lifecycle scope. And I can remove this polyline. I click listener as well are okay, I can remove this click listener RK, and they can just copy those variables inside this shapes class. And here I can just call Google Map object now. Okay, so now it looks better and hearing our Maps activity, let me just remove this click listener as well, and now we can continue working on our polygon. So I'm going to remove those two lines as well in New York. So here, let me create a new function, add polygon. So this function will accept only one parameter and that is Google Map object. So we're here, I need to create a new variable named polygon. And here I want to use a Google Map object and its function add that polygon. So hearing to pass polygon options and let me call this supplier scope function. And now we also need to add multiple lead longer objects. So now I want to go to Google Maps on my web browser to chose a different locations. So basically now, or with a polygon, I want to create something like a rectangle here on the map. And for that, let me just open a web browser or case. So here as you can see, this is our Los Angeles city. So here I want to choose four different points or four different coordinates. And basically I'm going to start from here. Then I'm going to go to here, then here, and here to create a rectangle. So first, I'm going to start right here. So right-click, then a copy. So here I'm going to create four different variables. So the first one can be named that p 0. And I'm going to use a LatLng object. I'm going to name this to P1, then P2, NRP three. Here I can pass the first coordinate. Then the second one can be, for example, right here. Okay? The second one, the third one can be something like here. Okay. And the fourth one can be, let's say maybe somewhere I right here. Oh, okay, let's pause it here. And now I want to specify those exact coordinates. So p is 0, then P1, then P2, and P3. So we need to follow this order. So we are starting to draw on the map with this p 0 location. Then we're going to draw a line to a P1, then P2 and P3. And now let me just initialize this class. So instead our Maps activity, let's sell easily initialized debts. So shapes and hearing, sight our own mapper ready, I want to use this shapes object. Then I need to call this function. So let me remove this private access modifier. Okay, and now let's type here, add a polygon, and let's pass our map object. Okay, so let's run the app and let's see what will happen now on our Google map. Okay, so when I zoom out, you should see our rectangular shapes. So it's not a perfect rectangle, but still something similar. And basically, as you can see here, now we can see that we have drawn for different points or which are specified for different coordinates. So this was the first line or the first location, then this was the second one, and then this was the third one. The fourth one. So now as you can see, this polygon is auto completing our shape. So if the last coordinate is different from the first coordinate, then this API will automatically close the polygon shape by appending the first coordinate at the end of the sequence of our coordinates. So that means that the behind the scenes, if our less coordinate is different from the first, then our polygon will add one more coordinate at the end of our sequence. In that last coordinate will be the same as our first one. So that's the trick behind this autocompletion with our polygon. And now as you can see, our polygon does not have any field color, and without that it looks almost the same as polyline. So to change that, I'm going to add here one more function. So fill color in here. I can specify, for example, color dot below. So let's run our app again, and now let's zoom out. So now you will see that this field color is blue, and we can also change this straw color. So here we can type stroke color to color, blue as well. Ok, so now as you can see, everything is the same color. So as you can see, we have specified this color value using this color class. And as you can see, our color is filled there 100% and we are not able to see anything behind this polygon. And in order to have our polygon health transparent, then we should use colors from our colors XML. So here for example, I'm going to replace this with R-dot, color dot, let's say maybe till 200. And I'm going to use this same color for our stroke as well. So now let's run our app. And now you can see that this color is basically how transparent. And we can see behind everything. So let me just open this colors XML. And even if we use this black from here, so let's just use black, then this black will not be in a full visibility. Instead, we're going to see everything behind it. So as you can see, it works just fine. And that's how you're able to add their transparency to your polygon. And finally, there is one more interesting feature I want to show you when working with polygons, and that is a hollow polygon. So basically, a multiple polygons can be used together to create a complex shapes, such as field rings, known as donuts, for example. Now a complex shapes are always the composition of multiple simple paths. So basically the trick is to define the two polygons in the same area. In the larger polygon will act as a fill area. While the smaller polygon will be transparent. And now I'm going to show you how to create that. So for that, we need to create a new polygon shape. And I'm going to launch a web browser in here. I need to choose a smaller coordinates so we can create some are smaller rectangle or a shape. So for example, I'm going to start around here, k. So let's create some new variables. So I'm going to name this p 00, for example. I'm going to pace here the first coordinate. I'm going to just rename those values r, k. So the second one can be, for example, around here. Next, the third one can be, for example here. And the fourth one can be somewhere here. Okay, so now we have created another four different LatLng objects. And down below inside our head polygon function I want to call here, add a hole in here. We need to add the list of new lead longer objects in here and we took pairs just list off. In here. I'm going to write p 00, p 01, p 02, and p three are came. So now let's run the app. And now you will see that we have used those two polygons to create some different shape. So now this larger area, or this first Polygon, represents our field area in this smaller rectangular shape, which we have created, is fully transparent. And that's how you're able to create some more complex shapes using this add whole function. But of course, you need to be careful here. So for example, if one of those points inside this smaller rectangular area is actually located the outside of this bigger shape, then this will not work. And let me show you that now. So let's say I want to choose the third for our smaller rectangle to be, For example here. So let's copy this coordinate and here for this p 02 and when to place this new coordinate. So now let's run our app and let's see what will happen. Ok, so now as you can see, this second polygon, or more precisely its third is outside of this first direct angular shape. And we, that we are not able to actually use this ad Hall or function. And as you can see now, this first the rectangular is not field. So you need to be very careful when you are creating this, this hollow polygon. So now let me show you just one more thing. So now let's see what will happen if we remove this whole function and we create a new polygon on top of our first polygon. So I'm going to just paste this code. And here basically I have made a new polygon with those new LatLng objects which we have added. So now let's run the app and let's see what will happen. So now you can see that both of those shapes are on top of each other and they are both filled with field color. And if you want to implement the on click listener for one of those polygon shapes. And you need to be very careful because you'll need to specify a zed index property on one of those polygons on which you want to implement a click listener. So for example, if you want to implement click listener on this first polygon, then you would need to add this zed index value. And for example, you would need to add one because a default value of this asset index is 0 for all, those are shapes. And if you specify a zed index here for this first polygon to one, then this polygon will sit on top of all other shapes which are drawn on the map, except of course, markers because they are totally different level, they are always on the top. But this is only when we are talking about overlays and shapes. And that way you would be able to implement the on click listener for this first polygon. So that will be all for this video. Now you've seen how to create a polygon objects, how to use a hollow polygons to create some more complex shapes using multiple, simple shapes. And that it will be all for this video. In the next video, we're going to talk about circles. 26. Introducing to Circle: Hello there and welcome back. In this video, I'm going to show you how to create a circular shape on the map. So well, there are two main properties which we need to define in order to create a circle. And the first one is a location point, which we are going to use as a center point of our circle. And that the second one is the radius, which is represented in the meters on the map. So what the circle will appear on the map are almost as a perfect circle when it's located near the equator. And it will appear in a non circular shape when it moves away from the equator, solar. Now, we're going to create a new function inside our shapes class. Okay, so before that, let me just modify this first function. So I'm going to delete this variable and I'm going to paste here directly on our points. So it will take less space inside our class. And that now at the bottom I'm going to create a new function. And the name of this function can be add circle. So what this function should accept her only one parameter of a type of a Google map. And here I'm going to create a new variable named circle. Here I'm going to call Google Map object and it's a function named Ed circle. So this function accepts or one parameter and it is a circle options. So let's use a circle options. And I'm going to call this suppliers scope function. And here, as I already mentioned, first we need to add the two properties. So the first one is a center point and the second one is the radius. So first let's specify a center here and this latlng object. And for the center point of our circle, I'm going to use Los Angeles coordinates. And the second property is radius. So here we need to specify a value, a double value, which will be represented in meters. So for example, I'm going to add, let's say, 50 thousand meters. And now it's opened up our Maps activity. And here I'm going to call add a circle instead. Now came, they're also before we continue, let me just add one more attribute here. And that is field color. In hearing to specify the actual color, which we're going to use. I'm going to specify, for example, this purple one or K. Now let's open our app. And as you can see here, when I zoom out, you can see a circle on top of our Los Angeles. And this is how it should look like, of course. So we can set here stroke color property as well. So we can choose, for example, the same color of purple 500. And let's run our app again, and let's zoom out and there you go. Now of course, we can change all those circular properties are later in our application programmatically, we just need to use this circle object. And for example, let me just add here as suspend keyword because I'm going to use a delay function so I can show you that. So let's use a delay of, let's say four seconds. And down below I'm going to call this circle. And for example, after four seconds I want to change the fill color. Let's just use, for example, the color black. And now inside our Maps activity, we're going to put this add circle inside the saliva cycles coal because we're using suspending function. Now let's run the app and you will see that after four seconds, our circle will change its field color. And there we go. So that's how you can change those, those properties later. So just by using this circle object, which has a return type of this add circle function. And now I'm going to remove that for now. I'm not going to need that and suspend keyword as well, our k, so we can move now this function here. So by default, this circle as well as other shapes, are not clickable. So if you want to make them clickable, you will need to add here clickable to true. I'm not going to add that now, but still, it's a good thing that you should know that. And of course here you can add on circle clicked, so on circle click listener and you can override a method to handle click listener for the circle and basically all other shapes which we have covered in the previous videos. Ok, so that'll be all for this video. And in the next video I'm going to talk a little bit more about shape customization. 27. Shape Customization: Hello there and welcome back. So in the previous videos, you've seen how to create a simple and basic shapes like polyline, polygon and circle. Also we have a customize those shapes at some level. However, there are some more properties which we can customize. And now I'm going to show you how to do that as well. So first, let's open up this shapes class, and I'm going to first start with this polyline function. So for now, you've seen how to modify properties like stroke with field color, stroke color, x_B index, and all other properties. So now I'm going to show you first one property which we haven't used in the previous videos, and that is a stroke pattern. So a stroke pattern can be used. The owner polylines, polygons, circles, and defaulter stroke pattern is basically a solid line for a polylines and outlines of a polygons and circles. And now you can specify our customer stroke pattern. And that pattern is specified as a list of dot get in the dash. So we can specify all those three or just two of them. And now I'm going to show you how to do that. So we're going to use this example from before. So this polyline function, and here I want to add a new variable and the top. So this variable can be named a pattern in here. And when to use list off in here, I want to specify dot dash in the gap. So first thing we start by using this dot and here we don't need to specify anything. Now let me use gap. So here I can specify, for example, a float value of, let's say 30 afloat. And next I want to specify a dash as well. And here I can specify, for example, 15 afloat. And here for this line or a polyline with, I'm going to increase that to maybe 40. And now I'm going to use this polyline function from this lifecycle scope. So Shapes dot, add a polyline and I'm going to remove this circle for now. So let's run the app and let's see how this polyline and will look like now. So as you can see, we have increased the actual stroke of our polyline. But I have to specify here at better function. So pattern, and here I need to specify the actual pattern which we have created. Now let's run this app again. And now as you can see, this is how our polyline will look like. So it's the exact line as we have specified. So first we have started with a dot, then we specify the gap between those two. And that gap is a 30 pixels, so this number is represented in pixels. Then after this gap, we have a dash, and after that, there shall we don't have any gap, but we can add one more. For example, gap of 30. Let's specify here for example, like that. And now you will see that in the space between this dot end is dash will increase. So let's run this app again so you can check that out, R k. So now as you can see, this is how it looks like. And also we can remove this dot, for example, and only show this dash in the gap. So let's remove the dots so you can check that out as well. Okay. And there we go. So this is how it looks like with only those gap and dash. Of course, we can specify only those two without this third one. And the reader should be able to get the same result. So there we go. And of course we can use, for example, only dots. So let's use dot here. Then i gap of 30 and we can remove this dash. So let's see how will that look like now. So as you can see now we can see only those dots. Okay, so this is how it looks now. So you can specify this stroke pattern as you want. Then of course you can specify this stroke pattern for polygons, endless circles. And of course, those stroke patterns will be applied only to those outlines of the polygons in the circles. But in this case, I'm going to only show you the examples for this polyline. The next property which I haven't showed you is called the joint type and for polylines and outline. So for polygons, you can specify a bevel or around their joint type. And the join type affects the internal bands in the line. So that internal band is, for example, right here. So this line is bending from this Panama position to this Spain, which we have specified already before. And that the new joint type will specify how the line is. Join here and you will see that. So if the line has a stroke pattern that includes a dashes, then the joint type are also applies when a dash trade-offs and joint and the joint types do not affect and dots because they are always circular. And now I'm going to show you how to use this joint type as well. But for that, I'm going to remove this pattern or I'm going to comment out that r k. I'm going to remove that from here. And I can just specify here, join type in here. I can call a joint type dot, for example, Bible. So we have two options, Bevel and around or the fourth of course, but this default has already been applied. So let me just show you how this bevel works and let me just run the app again so you can check that out. So let's wait for five seconds until the slang changes. Ok, so now let me go to Panama right here. And in order to see this, this bevel here, when this line is changing its direction. And I'm going to increase this width line. So I'm going to change that to, for example, 11020 so you can see the better. Okay, so now we have a bigger line. Let's wait until these changes, okay? And now as you can see, this bevel join type means that we're going to see here a straight line. And if we change this sublevel to, let's say around, then that the joint will be rounded. So let me show you that as well. Ok, so now as you can see, this joint here is around it, and that's how this joint type is actually working. So this surround the join type or will not be applied if you're lying, is only made of dots because dots are already in circular shape. And you can experiment with that if you want. So the next property which I want to show you is called the line caps. So you can specify a cap style on each end of the line. So there are two properties, start cap and endcap, and there are a few options so which you can choose for your calves. The first option is a bandgap, which is a default line cared. Then we have a square cap in the round cap. Also, there is a way to use a custom bitmap for your cap as well. So now I'm going to show you how to use that. So here we can add two functions. So we have started camp and end cap. So first of all, we'll start by using only their started cap. So here we need to specify which camp and we want to use. So there are four options. Custom cap around cap and bad cap in square cap. So our bad cap is a default one. And now I'm going to show you, for example, around CAB. So the start kappa will be around cap. And now let's run the app so you can see the change. Ok, so as you can see now this starter kit is around cap, and here we no longer see that straight line. And we can see these kinda Heller for a circular shape. And let me zoom out a little bit so you can see this endcap and the end cap here is a straight line and we can change its property by using gap as well. So hearing when it was end cap, but this time I'm going to use a different cap. So I'm going to specify, for example, square cap here. And let's run the app. So now let's zoom out. Now let's see this end cap. So as you can see it, these are square and we can use, but kept as well. So basically square in both camps are almost the same. And the finally, we can use custom cap as well. So we're now, I'm going to show you how to use our custom cab and I'm going to use a custom cap on our start camp. So custom cap, and here we need to specify a bitmap descriptor factory because we're going to use as a customer bitmap object on our starred cap. So, and when it goes from resource in here, I'm going to use a drawable dot, this custom marker, because that's the custom PNG image which I have imported into this project. And you cannot use vectors here, or you would need to use a function to convert a vector into a bitmap. But now I'm not going to do that and we'll just use this custom marker bitmap, which I already have in the second parameter which we need to specify is a float value. And that flaw to value represent stroke width in pixels. So I'm going to type here, for example, 20 float. And now let's run our app so you can see that now we are going to get a custom bitmap object on our cap. And as you can see, this is the same a bitmap image or we try to have imported into this project. And that's how you're able to use this disgust and bitmap for your care. And of course, if you want to change the size of this gap, you need to change this float value. So whenever you increase this value, this bitmap or will shrink, run our app again with this value of 100. So now you can see that it decreases its size. And of course, you can create your own image and add that to the bitmap to your project and specify here our customer care. And that's another way to customize those those lines. And those were some of the properties which I haven't explained in the previous videos. I hoped you will have learned a lot by watching this. Of course, some of those properties can be applied to polygons in their circles, like those stroke patterns. And you can experiment with that Furthermore, but that will be all for this video. 28. Ground Overlays: Hello there and welcome back. In this video, I'm going to show you how to create a ground overlay. So ground the overlays are image overlays that are tied to latitude and longitude coordinates. And ground overlay is fixed to a map. They are oriented against the Earth's surface rather than the screen. So we're rotating, tilting or zooming the map will change the orientation of the image. The ground overlays are useful when you want to fix a single imager, eta one area on the map. So to add a ground overlay, we need to create a ground overlay options object in there specify two main properties. The first property is that position and the second one is the actual image. So now I'm going to create a new class are right here. And the name of this class can be overlays are OK, press enter. And here I'm going to create a new function named Add ground overlay. So this function will accept only one parameter and that is a Google map object. And here I'm going to create a new variable named a ground overlay. In here, I'm going to use this Google map object to color, add a ground overlay function and dysfunctional sets or ground overlay options object. So let's call a ground overlay options. And then I'm going to call Apply scope function in here. As I already mentioned, we need to specify two parameters at least. So the one is the actual position and the second one is the actual image. So here I'm going to call our position. And here as you can see, we have two different constructors for this position function. And we also have one function name their position from bounce. So in the first two functions, we can specify latlng object, the second one, or in this third one willing to specify let long bounce object. So first, we're going to start by using this position function in here, we need to specify a LatLng object. So I'm going to copy one LatLng objects from these shapes class. And I'm going to choose this Los Angeles. Ok, I'm going to add it right here. And now let's pass this Los Angeles latlng object. And the second parameter is a float value. So this float value represents a width and we can specify either one or two for two values. So if we specify our one float value, that means that we are specifying the actual width. And if we specify to float values, that means that we are specifying width and height. So those float values will represent the actual meters. So for example, I'm going to type here, let's say maybe 11000 meters. And the second parameter, or the third parameter can be 100 meters as well, or one hundred, ten hundred, sorry. And the second function which we need to add here is the actual image. So we'll let's call hero image. And here we're going to call Bitmap descriptor factory. And we need to call from resource in here we need to pass in the actual resource. So r dot drawable dot. Custom marker. So I have already added this custom marker PNG into my project and I'm going to just reuse the same bitmap. And now from our Maps activity, I'm going to laser let you initialize this class. So private vol overlays by lazy in here I want to call overlays. So next I'm going to scroll down below in here inside our own map, ready, I'm going to call this function from our overlays. So overlays dot add ground overlay in here I'm going to pass a map object and I can comment out this lifecycle scope for now. We're not going to need that in this moment. And now let's run our app and let's see how will that look like. Okay, so let me just zoom in. And as you can see here, we have specified our ground overlay image and it's located in our Los Angeles coordinates as we have already specified. And of course, this imagery is already familiar to you. And here, if we open our overlays class, you will see that we have a specified here the width and height of this image to be, I want 1000 meters on the map. And for example, if you just increase that to 10 thousand meters in width and height, and let's run our app again. So you can see that now this image will be a bigger. And of course, as you can see, if we zoom in this image or will increase its size. So it's a little bit different behavior then for those markers. So if I zoom in, this marker will stay the same, but this image or this ground overlay will increase its size also when I rotate. So let me just rotate here. You will see that this round, the overlay will stay fixed to a map. And that's the typical behavior for those ground overlays. So as you can see, this is how it will work. So of course, you don't think to specify those too. Floating values. You can just specify one. And this API will basically know how to calculate the actual height. So you will see now that it will basically be the same. So the next thing I want to show you how to use lead long abounds object instead of passing this latlng object. So I'm going to remove that and I'm going to call position from bounce. And here we need to pass one or let long bounce object. And here I'm going to create a new lead longer bounce objects. So private of all Los Angeles bounds here I'm going to call laugh along and bounce. And here I need to specify two different LatLng objects. So the first one, we'll represent a south or west point and the second one will are present and northeast point. So I'm going to open up now Google Maps. So what, this is, Los Angeles and here I'm going to choose two different coordinates. So the first one shouldn't be Southwest. And I'm going to choose, for example, let's say maybe here. So I'm going to copy this value and then I'm going to paste here lat long and between Sir, that first coordinate and the second one, let me just choose one. And the second one should be. North east. So I'm going to choose, for example, it's a maybe here. Let's copy this coordinate and let's paste that here. So now inside this position from bounce, let's bears this loss here, Los Angeles bonds. And let's run our app. And now as you can see, this ground overlay is placed in the center of those two bounds which we have specified. So that's how it works. And then now I'm going to show you how you can programmatically remove this ground overlay. So for that, let me just set here a return type of ground overlay. So as you can see, this ending around the overlay function will return ground overlay objects. And now we want this function to return this same object. So now I'm going to just to remove that n-type or return. And now let's open up our Maps activity. And here I'm going to comment out this lifecycle scope. And I'm going to add here a simple delay of four seconds, for example. So after four seconds, we want to basically remove this ground overlay. So here I'm going to create a new variable named a ground overlay. And now I'm going to call this ground overlay variable, which actually holds this ground overlay object, which this ad ground overlay function is returning sonar. Let's call that, and let's call this remover function. So now you will see that the after four seconds, this ground overlay will be removed. So after four seconds. Okay, so there it is. It is successfully remote and that's how you can use this ground overlay object to actually remove that programmatically. Now, there are more options or properties which we can modify with this ground overlay. So for example, we can change its transparency. So here I'm going to call transparency and I'm going to set it to 0.5. Let's run our app and you will see that after four seconds, our ground overlay will change its opacity level. So as you can see now, it is a half transparent. So number one in float value is full of its ability and 0 is basically invisibility. So here we have a typed a 0.5. ul, which is basically a 50% opacity of our ground overlay. Also, there is a function here to change the image of this ground overlay. So for example, you can programmatically change this image by using a set image function in just specifying here a new bitmap descriptor object. I'm not going to do that now. I'm going to remove that. Also. There is a way to store a simple data object inside this ground overlay. So that applies to all other markers in the shapes and doorways. And for example here I'm going to create a new function. So this function will be named Ed ground overlay with Tang. And this function will also return this ground overlay. But first I want to change this code a little bit. So I'm going to add the new variable name, the ground overlay. And after that, I want to set the tagger or the actual data object on our ground overlay. So I'm going through this ground overlay object, then I'm going to call a tag in here. I want to specify some other value. For example, I can type my tag and then I can return here this ground overlay object. And now from our Maps activity, I can just call this other ground overlay function. So with tag and now for example, after four seconds, I can retrieve this same tank. So let's use this ground overlay object, then tag, and here I can just set a log statement for example. So maps in here, I can pass that to a string. So let's run our app and after four seconds, we should be able to see this inside our logcat. And there we go. So here it is the exact value which we have specified inside our ground overlay function or object. And that these tag information can be useful to, for example, adder sum, zed index priorities so you can differentiate one or ground overlay from another. There are many use cases and this was just one example. But it's very useful to know that you cannot add the simple tag information to basically each and every shape and marker and the overlay as well. Okay, so that will be all for this video. And now you have learned how to create a simple ground overlay objects and how to modify some of its properties as well. 29. My Location Layer: Hello there and welcome back. In this video, I'm going to show you how to enable and use my location layer, which is a part of Google Maps SDK for Android. So we're now, you might be wondering what is this so-called the myLocation layer? Well, it's a way of locating yourself on the map just by pressing myLocation button on the Google Maps. In the myLocation button is usually located on the top right corner on the map. Now, if we use a myLocation layer, we will not be able to receive the actual data of the current user's position. Instead, our camera will just automatically moved to our current location. So basically it's the easiest and fastest way of locating ourselves on the map. So well later in this course, when we started the building go real application, we're going to also use a different way to locate our device and they're getting the actual location data as well. Now, if your application needs to access a user's location, then you must be clear in the request irrelevant location permission first. So there are two main location permissions. One is named the chorus location, the second one is named the final location. And now you only need to declare one of those two, and you don't need both of them. So the first coerce location permission allows you to use the WiFi in the mobile cell data or both to determine the device's location. In the result, we'll return the location with an accuracy approximately equivalent to a city block. And on the other hand, the fine location permission allows you to determine as precise location is possible from the available a location providers, including the global positioning system or GPS, as well as Wi-Fi and mobile cell beta. After we decide that which one of those two permissions we want to use, then we need to request permission at runtime. So we're runtime permissions were introduced from enjoyed there, 6 or a marshmallow. And if your application targets API level 23 or higher, then you need to use this new permission model. So well, for best they user experience. If application requires a permission for only part of its functionality, then you should request the location permission at the time when the app performs the action that requires that permission. So the application must gracefully handle the case where the user does not grant permission. For example, if the permission is needed for a specific feature, the application, you can disable that feature. And if the permission is essential for the whole application to function, then the application can disable all its functionality and inform the user that they need to grant a permission. Anyway, I'm going to talk in more details about the handling and requesting multiple permissions in a proper way when we start building our distance tracking app. And for now we're going to focus on myLocation layer. So now I'm going to show you how to add that, that myLocation layer in how to enable this myLocation button on the top right corner. So before we continue, I just want to remove or some code from our Maps activity. So here I want to remove all of that for example. And you can see that here I have included the already, this is my location button enable. So this will basically display my Location button on our top right corner, but that's not all. We also need to use our map or Google Map object to call eases my location enabled and we need to set that to true. But if we set it to true, we're going to see a warning here. In this warning we will say that we are missing permission required by these Google map set location enable. So first, what do we need to do? We need to open our AndroidManifest file. And as I already mentioned, that we need to add the one offer to our location permissions. So let me use this uses permission tag in here, we have two different permissions for location. So as you can see, we have access course location in the x's final location. So in this case I'm going to use this second one, ok, and you don't have to use the bottom, then you just need to declare one of those. Okay, so back in our maps activity, so here, before we actually can set our ease, my location enabled to true, we need to handle our location permission. So when we actually start building our distance Tracker application, and we're going to use one, the library called the Easy permissions. And that's basically a library which will ease our work when we're requesting runtime permissions. And you will see, so for now we're going to do that manually. So we're down below. I want to create a new function named the check location permission. And here I want to use the if block. So I want to use context compet dot Czech self permission. Here I want to pass, and this is the first parameter and the second one I need to call manifest. So this Android dot permission dot x is fine location in the I need to check if we already have a permission for this final occasional. So equal to package manager dot permission granted. So inside this block, I want to cut and paste this line of code from above. So right here. Now we are going to also add the else block in here. I want to say request permission. So if we don't have permission, then we're going to request and new one. Also I want to add here one, a toast message. So here I'm going to write something like already enabled. So a length short. Ok, so if this first if block is executed, that means that we have already granted the, our application this permission. And otherwise in this else block, I want to create a new function. So request permission function in here I want to call activity compet dot request permissions. So the S1 here as the first parameter, I need to pass this activity. Then I need to pass array of in here I want to pass manifest dot permission dot x is fine location because we want to request this final question if we don't have it in here as the third parameter, we need to pass a request code for this permission and I'm going to write just number one, but usually you would want to create a new constant variable for that. So here, if you are still seeing this warning, than just press Enter, and that warning will disappear. So now that we have added the two ways here to check. Actual location permission into request one would need to override their one, your function name, the onRequest permission result. So press Control O and search for on request permission results. So this one in here, we can remove this. And here I can say if I request the code is not number one because that's the exact request code which we have defined inside our request permission function. And that request code is associated with this x is fine location. So if these requests code is not number one, then we want to just to return from this function. If it is number one, then we want to call if block here we want to call this grant result is not empty and grant result, the first item with a 0 number in this array, and we want to see if this permission is actually granted or not. So PackageManager dot permission granted. So if this permission was granted by our user, then we want to display one toast message here, first, k here, I'm going to say, for example, granted. And down below I want to also call this myLocation enabled to true r k. And here in Else block, I'm going to just display a simple toast message saying, for example, something like, We need your permission. And I'm not going to handle all cases for this runtime permission. This is just to show you how this my location layer or functions. And I'm going to show you how to request and handle a runtime permissions even better when we start creating that application distance tracker, because that way we're going to use a library called Easy permissions. And it will help us a lot to, to handle all permissions so inside our application. So after we have overrided this request permission result, there is only one more thing we're trying to add here. So a press here, all plus Center. And instead of adding this ADD permission check because we actually don't need that, I'm going to add this suppressed saline missing permission so we can actually remove this warning. And now I'm going to run the app so you can check that out. And before that, let me just call this check location permission inside this on map ready. So for example, right here. And so whenever we run our application and whenever our map is ready, then we're going to call this check location permission. And we're going to check if our application already have this axis fine location permission. And if it has, then we're going to display this simple toast message that says already enabled. And also we're going to enable our myLocation layer. Otherwise, we're going to request the new permission in here. We're calling this request permission function to actually request a new permission access vinyl cation with this request code off one. And of course, this onRequest permission result will be triggered every time our permission is denied or granted. In here we're checking if our request code is not number one. In that case, we just want to escape or return from this function. And the here we are basically checking if our permission is actually granted. So if it is, then we're displaying Simple toast message and we're enabling our myLocation layer. And otherwise we are displaying the source message that says we need your permission. So now let's run the app and you can see by yourself how will that work? Okay, so here as you can see, when our application opens, this function check location permission is called. And since we don't have our axis fine location permission granted by your Xr, then we are skipping this if block in, we are requesting a new permission. So now if I press deny, then this a toast message will appear that says we need your permission. So clean the NIH, okay, so like that. And then I'm going to run the app again. Okay, so now again, we are getting this prompt to allow or deny our permission again. And then now I'm going to click allow only well, using this app, so click this and you're going to see this message that says Granted. And also now we can see our myLocation button. So as you can see, this myLocation button is located on the top right corner. And when we press that, we're going to immediately zoom into the current devices location. And since I already defined the current location of our device to a Los Angeles, then we're going to zoom to Los Angeles immediately. So click this button. As you can see, we have immediately zoomed into our current position, which we had defined in our emulator. And also we can see this blue circle and this blue dot. And that's how this myLocation layer is working. So we cannot get any data from it, like the actual location in coordinates, but it can easily locate our device in a few seconds. And of course, I'm going to talk about runtime permissions in more details when we start working on our distance Tracker application. So that will be all for this video. Now you have learned how to implement myLocation layer and enable this myLocation button on Google Maps. 30. Create the New Project: Hello there and welcome back. So well with this video, we're going to start building our distance Tracker application. And you have already seen in the first videos of these squares how our replication will look like. So basically, we will be able to track our user's location even if from a bare ground. And that even if a user destroys the application, we will be able to track our user's location using a foreground service and background location. So I'm going to explain everything you need to know when we actually start implementing those functionalities. But for now first, we need to create our project. So our project will have a single activity and the multiple fragments. And here we are not going to choose Google Maps activity. Instead we're going to choose an empty activity. And the later we are going to create a fragment that with the Google Maps. So select Empty Activity, then click Next. So let's name our application, distance, tracker, app or game. So here for the language, we're going to choose a coating. Of course, minimum SDK version can be 21 and click Finish. Now K. So let's wait until our Android Studio is building this project. All right, so let's just move that here on the left side a little bit. And the first, and when to open up this gradle build file or both of those Gradle build files. And I'm going to add all necessary plugins and dependencies which we're going to need. Okay, so first I'm going to start with plugins. So here I'm going to just paste the plugins, which we're going to need. So we're going to as navigational safe hours, then we're going to need Katlyn parcels as well. Then Katlyn kept and of course, a dagger hilt because we're going to use dependency injection with our application as well. Okay, so the next thing, I'm going to enable data binding in our application. So just add this bill futures data binding true, and with that, we will enable our data binding. And the down below, let's scroll and let's add some dependencies. Again, I'm going to just paste those talents is right here. So as you can see, first that we have our navigation component, then we have a lifecycle, then we have some dependencies for a coroutines. Then we have dependency for a few hours location. I'm going to talk about fuels Location, API in some of the next video. So these squares, and then we have one util dependency. And there we're going to need this util dependency to actually calculate the distance between our start and the end point. And you will see about that as well down below next, whichever dagger, hilt, of course. And finally, we have a 1 third party library called the Easy permissions. So you might have heard about that it's a very useful inconvenient. And of course I'm going to talk about this library in details in some of the next videos when we actually start implementing your runtime permissions. So for now, you just need to know which are the balance is. We're going to need for our projects, our k. Let me scroll up and let's open up this second Gradle build file. And here I need to add the two class paths. So the one for navigation safe arcs, the second one for our a_dagger hilt. Okay, so what this project will be available for you to download from my GitHub raw files. So don't worry about death. And here let's just sink now. Okay, perfect. So let's close those Gradle build files for now. The next thing, I'm going to select a few colors for our project. So let's open up our resource directory. Then I'll values, then let's open up our colors XML. So here I went to change those are default colors. And for that I'm going to open up a website called the Material dot io slash resources slash color. And here as you can see, we have some material palette, for example, when we select one of those scholars. So you're going to see that we are going to get three different values, primary, light and dark. But this time I'm going to select my own custom color. So just select this custom. And here I'm going to paste my favorite blue hex code color. Okay, and now we're going to generate those three different colors. So let's just edit those callers to our project. So here I'm going to rename this scholar to say blue or 500. So blow instead of a purple refactor. And let's change this color as well. Ok, next we have this light color. So let's copy this color code. And we're going to paste that color right here. And let's press Shift plus F6 so we can change the name. So let's change the name here to below 200 clicker refactor and there one more dark. So let's copy this dark version as well. Let's paste that new color right here. So here press or Shift plus F6, and let's rename this to below 700th refactor, our K. And also I'm going to add up to more colors are red and the orange. And those are some basic colors which we're going to need for our project. So we can close that for now as well. Then finally, I'm going to just open those teams XML. So both versions and for our application, we're not going to need the ActionBar. So here I'm going to use a no action borrowed theme are, okay, and let me just copy this same theme inside a different version of these themes xml. So replace this dark action bar with no ActionBar r. Ok, perfect. Now we can close both of those. So for now, that will be all in, in the next video, we're going to implement the navigation component to our project. And also we're going to connect our project with Google Cloud Platform so we can actually use the Google Maps SDK. And for this video, that will be all. 31. Implement Navigation Component: Hello there and welcome back. So in the previous video, we have created our project. So we have added the all necessary dependencies. We have changed our project colors, and we have also applied the newer theme without the action bar. So in this video now, I want to create a navigation graph, and I want to create three different fragments, which we're going to need later in their scores. So I want the first thing. Let's open up this resource manager on the left side. Then let's select this navigation in here. Let's press this plus button to create a new navigation resource file. So the name of this file can be nav and graph. And this file we'll represent an aviation graph. So click OK. All right, so now we need to create three different fragments. So let's first click here, there's a button, then create new destination. So first we're going to create the permission fragment. And for that we're going to choose this blank option in our permission fragment that will basically handled the first permission which we're going to need for our applications. So you will see when we come to a dead for now, let's just create those fragments. So the name of this fragment can be permission fragment. So click finish our k, So let's create another one. So the second fragment will be used to display our Google map. And we're going to select the already defined a template for that. So this Google Maps fragment, so select that and click Next. And here are the name of our framing can be maps, fragments, so that's okay. Click Finish. All right, so our default destination will be permission fragment. And finally we need to create another fragment. So the third one, and let's use foramen blank as well. Click next and that this fragment will be used basically to display the results from our distance tracking application. So here let's name this fragment, result fragment. And later we're going to change this fragment into bottom sheet dialog foramen, But for now it will stay this way. So click finish, I'll kill it and just place this on the right side here as well. Okay, so we're not going to design them right now. We're going to do that in the next videos of this course. For now, I'm going to just connect them. So Parisian frame and that will be connected to our maps fragment. Then maps fragment that will be connected to our result fragment. And our results frame will be connected back to our maps fragment as well. So that's how navigation graph will look like. For now, we're going to have three different fragments. The first one, permission fragment, which will be basically a default destination of our NAB host fragment. And this fragment will basically be shown only the first time when we don't have a permission to access user dislocation. And the after we grant permission or one time, then this fragment will not be shown anymore. And whenever we allow our application, we will automatically be redirected to our maps fragment. But of course, we're going to create the logic for that in the next videos of this course. So for now I'm going to open up a dosa fragments and I'm going to remove those unnecessary codes. So let me just to remove everything from here, I'm going to just leave this OnCreate View function. Let's open up our results frame and as well, let's remove all of that. Okay, perfect. So let's close those fragments. And our maps fragment does not contain a doors, unnecessary codes, so well, for now I'm going to open up our main activity and the inside of our activity Main Layout, I'm going to add the nav host fragment, which will host all our fragments. So first let's remove this default TextView and it searched for nav host fragments. So this one, just place that here and select our own navigation graph, which we just created. Click OK. And let's constrain this nav host fragment horizontally and vertically with a parent or, okay, perfect. So here as you can see, we are linking our navigation graph which we just created. And here I can change the ID of this fragment to say, for example, something like nav host foramen. So press Shift plus F6 so we can re-factor. So nav, host, fragment, click Refactor. Okay, so let's open up our main activity now. And the first woman to lazily initialized and never controller. So private latent heat var and nav controller. And here I'm going to just call this a nav controller variable. And then I'm going to call Find the nav controller in here. I'm going to pass the ID or power never host fragment. So with this one, and of course, we're going to need that later. But for now this is how our main activity should look like. So let's run our application here to see if everything's gonna work just fine. So our default or destination is permission fragment, and we're going to design that fragment some of the next videos. Ok, so as you can see, we don't see any action bar because we are not going to need that. In here. We can see our text that says, hello blank fragment. So that means that our permission fragment has been successfully applied as a default destination. And we can see that so well for now, that will be all. And in the next video, we're going to connect our project with Google Cloud Platform. We're going to enable Google Maps SDK for Android. And also we're going to generate some API keys. So we can actually use our Google Maps API. So that's it for this video. 32. Design PermissionFragment Layout: Hello there and welcome back. So in the previous video, we have implemented our navigation components and also we have created our navigation graph. And in this video we want to design our fragment permission. So we're here, let's open up our XML code in here. We're going to change the route layouts to constraint layout R, k, and we can remove this TextView for now. So the first thing that we need to add the one button here, let's just drag and drop that right here. So we're going to constrain that on the bottom, left and right now, okay, so we're all margins here should be 32, so let's select those. Okay, so for the layout width, I'm going to select the 0 dp r k, n for the height. I'm going to say, let's say maybe seven vdp. Okay, perfect. And let me just change the ID here. So press Shift plus F6, and I'm going to say here, continue button, OK, clicker refactor. Here I can just say continue. So now press Enter, so we can extract this text to our strings.XML, but be careful, we need to add here something different. Then I continue because this continue is a reserved keyword. So we can say here for example, continue, texts are case or now press OK, now it's fine. Then here I'm going to add one TextView, which will represent basically a description of our permission which we are going to request our k. So let's connect that to our button here. And of course left and right, two apparent. So are those the margins on the left and right should be 32 as well. Are. Okay. And the bottom margin here can be, let's say maybe 48th, our case, I'm going to say layout width to 0, dP, R, k. Let's open up our XML code so we can change a few more values. So here I'm going to add the text alignment to center. Text. Color can be black, text size can be 16 SP, and the text style can be Italica. Okay, sorry, I have added all those attributes on the button so I can just cut them and add them on our text view so I can move this TextView on the top here. Okay, so perfect. And here for the text, I'm going to add some text right here already prepared. So I'm going to open first values, then our strings.XML. And here I'm going to create a new string. And here I'm going to name that permission description now, okay, and I'm going to just paste some text here. Texts that will say are welcome to distance tracker. In order to use our application, we will first need to request location permission from you. Otherwise, we will not be able to provide you with our service. And if you agree and wish to continue tap on the button below R k. So let's close that for now in here, I can just delete that string, which we have just created our case. So it will look something like that. We can also change this idea of this TextView. Also press Shift plus F6, and here we can say permission. Description, text, fuel, clicker, refactor, our k. Next we need to add one more, a TextView on the top here. So I'm going to connect this bottom constraint to a constraint of our text view down below. So here, left and right margin should be connected to a parent. Of course, margins should be 32 here, and the bottom margin can be eight. Okay? So let me just cut and paste this text view on the top here, just above our permission description text to you or case. So here in here I can rename this text to something different. So press Shift plus X6 and I can type here. Welcome. Text view. Press a refactor, our k here for the text, I'm going to say permission required, and I can press all plus entered to extract this string to Maya strings.XML. So press OK. Next for the text color, I'm going to choose a red color for the text styling and to choose the bald for the text size, I'm going to choose a 26 SB for a text alignment, I can choose a centre or k. So let me just open this. So I can see Enda here also, I can set the layout width to 0 db, so much constraint R, k, so perfect. And there is only one more view which we need to add, and that is an image view. So I have already prepared there one imagery or for this frame and permission layout and then went to opener this Adobe XD. So here as you can see, I have this one vector file. So I'm going to export data vector file on my desktop as SVG R k. So I'm going to export that and now I'm going to import data SVG to my project. So here inside our drawable directory, I'm going to click vector acid. Then here I'm going to check her local file here. And then we choose that file which I have, just export it. So I need to find that on my desktop. So let me see RK desktop. And there is a welcome image, SVG. So now just press or next ten, finish. And now I can end here in imagery or so. Just drag and drop that right here. And they can choose this new welcome imager vector, which I have just important. So click OK in, I can just constrain that to a bottom here. Then I'll have to write two apparent of course. So bottom margin can be 100 DP for now. And of course I can change its ID. So let me just cut and paste in this view on the top here, right there, and press Shift plus F6. And I can change this ID to Welcome image view clicker, refactor, and there it is. So now we can run our application in C. How will this fragment layout the locking, our emulator, our case. So this is how our application, and it looks now so far. So as you can see, we don't have any action bar because we have chosen a theme without the action bar. And we have this beautiful image view. Then we have a door text views where we are explaining our users that we need to request this permission, this location permission if a user wants to use our service. And of course, in the next video, we're going to implement the necessary logic to request the runtime permission. So whenever a user selects this mutton were should be able to prompt the user to allow us or grant us a permission to access fuels location permission. And this fragment will be shown only the first-time user runs the app. And after a user grants us permission, then this fragment will not show anymore. Instead their maps fragment will be shown in of course. So you will see that in the later videos of their scores. For now we have designed our fragment permission layout. And in the next video we're going to implement the logic to actually request their runtime permission. 33. Check & Request FINE_LOCATION Permission: Hello there and welcome back. In this video, we're going to implement the logic for our permission fragment so we can actually request their runtime permission for our fuels location permission. So we're basically this fragment there will be shown to the user only the first time when our app and does not have a fine location permission. And we want to edit the logic, you know, or Continue button. So whenever a user a tap on the button and your pop-up window will appear asking the user to grant the location permission to our app. Here, we have also explained that in said that this permission is essential to our application. And without it, we will not be able to and provide our service to the user. Now, before we implement the necessary logic, I need to inform you about best practices when it comes to requesting your runtime permissions from yours or so with the official Android, the documentation says that when our feature in your app needs location axis, you should wait until the user interacts with the future before making permission request. Also, if your app requires a multiple permissions, it's recommending that your app performs incremental requests. That way you will request permissions, so one by one only when they are needed. And that, that's the case with our application as well. Our application, we'll need the three different permissions. And from those three different permissions, two of them will require a runtime permission request. Also, if your application targets enjoy the 11 or APA level 30 and higher the system or will enforce this incremental request, the practice. And for example, if you request a foreground and they'll beggar on permissions either same time the system or we'll ignore your requests and the doors that permissions so we'll not be granted. Now in our permission fragment, we are going to request the fine location permission. And then later in our maps fragment, we will also request our background permission as well. But I'm going to talk more about beggar and permission and you later videos of the scores. For now we're going to focus only on a permission fragment. So well, before we continue, we need to open up our enjoyed the manifest file. And here we need to declare fuels location permission. So here we have a one, no comment because we care to edit our mips fragment template. In here it says that the x is coarse or fine location permissions are not required to use the Google Maps Android API, but there you must specify either a course or a fine location permission for a myLocation functionality. And of course, we are going to use this location functionality. And that's why we're going to need to add. One of those are permissions. So and we've got chores are fine location permission because I'm going to need more precise location of our user. So I can remove these common for now. And as you can see, our excess final caution permission is already inside our AndroidManifest file, so we don't need to declare a chorus location. We have this final coercion and that's fine. So now let's close this Android, their manifest file in here inside our project that I'm going to create a new Katlyn object. And this object will be named permissions. Press enter. And here first, for now, I'm going to create a tool Function, one for checking if we have a location permission in the second function for requesting geolocation permission. So before I create those two functions, you need to add 1 third party library called the Easy permissions. So let me open this web browser and this is the actual URL. So give harm.com slash Chevy am going Slasher, easy permissions, forward slash or KT x. So this is easy permission circuit, the extroversion specifically made for a Katlyn and all you need to do is you need to add this dependency. And I have already added that dependency in my project. And basically this library will help us a lot when they're working with their runtime permissions. And you will see, of course. So let's get back to our Android Studio in here I'm going to create the first function, which will check if our application now has location permission. So let's create a new function name the location permission. This function will have only one parameter and that is the actual context. Next down below, I'm going to call easy permissions. So this same library that has permission in here, the first parameter is the actual context, and the second parameter is the actual permission or permissions which we want to request. In this case, I just want to request final cation or check if we have a fine location permission. So you will manifest enjoyed dot permission, dot axis, final cation. And basically that's all we need to do to request or sorry to check if we have these ACCESS_FINE_LOCATION permission. So next, and below that I need to create one more function named the request location permission now, okay, and this function will have only one parameter and that is a fragment. So Android x-dot flame and dot ab. Okay? And here we need to call again easy permissions, dot request permissions. Here we need to add the multiple parameters and the first one is the actual are fragment. Then the second parameter is a rationale. So basically here we need to specify the actual message we need to display to our user when a user denies our permission. And here I can say, for example, this app or this application cannot work without a location. Permission are case, so that's fine. The third parameter here is the actual request code. And for that I'm going to create a new object here so I can place all my constants later or for this application. So let me create here a new Katlyn object name. The constants are k, press enter. And here I can create the new constant, so constant of L, permission, location, request code in here. I can type for example, number one. Oh, okay, that's fine. So I can close that for now. And here I'm going to write permission, location, request code, and I can just import that. Okay, perfect. And the final perimeter here is the actual permission which we want to request sewn into type here, manifest dot the permission dot axis, fine location. So that's all we need to do to actually request our It's fine. Location permission. Alright, so now we have created the, those two functions, and now I need to go to my permission fragment in here. I need to basically add their on-click listener for our Continue button. But for that, I need to use data binding so I can access my views from a permission fragment. So for that, let me just open this flaming permission in here. I'm going to click on this constraint layout. Then I'm going to press all plus enter in here I'm going to click convert or data binding layout. So this will basically generate all the necessary classes which I need to and my viewers to fragment. And here I'm going to write two variables. So first, private var under a score of binding, and here I'm going to call our fragment permission binding. So this class was automatically generated by our viewer binding. And here I'm going to set its initial value to null. And then I'm going to create a read-only a variable named the binding in here, I'm going to use the getter to get the value of this underscore binding in here, I can set the double bang operator in here. I can just type under a score of binding equal to fragment permission binding dot inflate. In here I can just pass the actual inflator instead of the layout r k, n here I can return binding Dr. Ruth n. Now let's remove this question mark and the one more thing. So I need to override onDestroy viewable function so I can send this underscore or binding to now. So let's set our underscore binding to null when our fragment is destroyed. Now K perfect in here, let's call our binding dot continue button and that set onClickListener in here, I'm going to say if he has location permission. So now let's import this function from our permissions objects. So orthocenter here, let's pass the national contexts, so require context. Okay, so one more thing, I forgot to actually return this easy permission. So I can remove this brackets and I can just diaper equal. So now this will return a boolean value and it will basically return true if our application now he has this final location permission in the, it will return false if we don't have this permission are k. So now it looks even better. Okay, so this warning we'll now disappear. And the hero can call, find their controller dot and navigate in here I can call R dot Id dot action permission fragment too. Fragment. So if we have permission, we want to automatically navigate to our maps fragment. And in Alice blog, I want to call a request our location permission. So all plus centre, and that's the function from our permission object in here is just this, which is referring to our fragment. So now basically when we run our permission fragment, we're going to check immediately if our application now has this location permission and that if we have this permission, then we can just navigate to our maps frame end. And if we don't, then we can request a location permission. Now, down below, we also need to override their one function on request permission result. So we'll press control plus o and search for on request that permission results. So this one, and here down below, we only need to write the one line of code in that is easy permissions, dot on request, permission result. In here we just need to pass a few parameters. So the first one is the actual request codes. So pass request code. The second one is the permissions. That third one is grant result in here as a final one and it'll pass at this, okay, and that's all we need to write for our own request permission result. Now I want to implement one interface here. So easy permissions, permission called bags, and now we have a warning here. So press all plus Center and let's important those two functions. So on permission denied and on permissions granted. So press okay, and we can move those two functions down below, below our own request permission result. So basically this permission denied will be triggered every time a user denies our permission. And this permission granted or on Permission granted, will be triggered when a user grants certain permissions to our replication. So here first I'm going to write some code in our own permission denied. So here I need to check if user permissions dot some permissions permanently denied. He ran into pests or this is our first parameter n. The second one I need to pass parameters. And the first item, which is referring to the first permission, which is a final cation. So basically, there is an option for the user to select. Dont ask me again now or something similar. And that way we can just simply delta user data if he or she wants to continue using our application that we need to enable some permissions. And for that, we can call settings dialogue to actually open our permission dialogue so user can enable that permission or manually and you will see, so let's call this the dialog dot builder in hearing to pests or require activity as a first parameter or gain Next, let's call a build and show. And in ALS blog, I can just call our request location permission. And I can pass this in inside our own permission, granted, we can just call our finite controller to navigate from our permission fragment to our maps fragment. Okay, so that's it. And now let's run our application so you can see how all of that work. Ok, so as you can see, when we tap on our button, we should be able to see this permission request. So here it says that allow this and Stryker app x is this device's location. So we have a few options to select while using the app only this time and deny. So if we press the nine, you will see this message that says that this application cannot work without television permission. And if we open up our permissions object, you will see that this message was editing this function, okay? And if I press. Okay. Then we're going to be prompted again to give him the permission. And if I press the NIH, nothing will happen. But if I press this Continue button again, then we are going to receive this message that's generated from this easy permissions library. And here it says that this app may not work correctly without the request and permissions. Open the app settings screen to modify permissions. And if we press OK, then the code from our permissions fragment right here, we'll be executed. So now if you press OK. Then settings dialog will appear. So I'll click OK. And now from here, we can manually enable some permissions. And here we can choose, for example, Let's see location. So here it says denied. So click location we can enable here, for example, ask every time or allow only while using the add R k. So let's now get back. And now when I press continue, we're going to get the Navigator to our maps fragment. So don't worry if you don't see here anything inside our maps frame. And we still interconnect our replication with Google Cloud Platform and we need to generate some API keys. We're going to do that in the next video. I'll came. So if they run the airport again, then, uh, let's see what will happen. So now we're going to see our permission fragment, but we have already gave her permission to our application. So why does this frame into appearing now? Well, we're going to add just one more thing. So open up a main activity in here. Let's just add one if a blog. So I'm going to import this function, okay, or plus Center. And inside our main activity, we are checking if we have our location permission and if we do have that, then we're going to just navigate them directly from our permission fragment, that two maps fragment. So now let's run our app and let's see now what will happen. Ok, so now as you can see, we are no longer seeing our permission fragment because we already have a location permission, which we weren't needed. And now every time we run our application, we're going to get navigated to our maps fragment. So now as you can see from our main activity, we are always checking if we have this permission in only if we have it, then we can navigate to our maps framing directly and we need to again, go to our permission fragment. Then inside our permissions object IQ greater than those tool useful functions to check if we have our permission and to request location permission as well. And then inside our permissions fragment, we are basically adding one OnClickListener in our continuum button in here as well. We are checking if we have this location permission, and if we have that permission, we can just navigate to our maps or fragment and else we can request and your permission in of course, so we override the this onRequest permission result. And I have also implemented those promotional callbacks. So on permission denied and on Permission granted. This permission denied callback is very useful when yours or denies our permission. So we can actually ask a user to manually enable our permission. So that will be all for this video. And in the next video, we're going to connect our project with the Google Cloud platform. And we're going to generate some API keys for our Google Maps. 34. Add Google Maps API Key: Hello there and welcome back. So in the previous video, we have implemented the all the necessary logic we need for our permission fragment. And now basically whenever we run our application for the first time, we're going to see our permission fragment. And when we press Continue button, now we're going to request location permission. And the after we grant our application that permission, then whenever we run our application next time, we are not going to see our permission Fragment. Instead, we're going to directly navigate to our maps fragment. Okay, so there is a one more small issue or a mistake which I made in the previous video. So let me just scroll down below in our permission fragment. Apparently I have made a mistake and I have written a different method. So instead of overriding onDestroy view, I have arrived at this onDestroy options menu. So now I'm going to remove this function and I'm going to override the new one. So on destroy view. So this one, press enter our case or now we have a right one. Alright, perfect. So in this video we're going to actually generate the API key for our Google Maps in we're going to add that API key to our project. But before that, let's just rearrange our project structure a little bit. So here I need to create a new package and I'm going to name this package. Oh, okay, so I'm going to place this constants objects, they're right here. And also these permissions object as well. So Clicker refactor our Came later. We're going to modify our package structure furthermore, But for now, it should stay that way. And the next thing we need to first open our project view here are k and here inside our source directory, inside our debug directory, we're going to find a new file, Google Maps API. We also have this same file inside our release directory right here. But I'm not going to add release API key for Google maps. I'm going to only add debug key, but if you wish to add the release key, you can do that as well. And I already shown you how to do that in some of the first videos of the squares. So now I'm going to open up this debugger Google Maps API in here. As you can see, this file that was automatically generated when we have created our Maps activity or sorry, maps fragment. So now from here we can just copy this link and create our API key immediately. So just copy this URL. And now you need to login to your Google Cloud Platform. And here I'm going to paste that link. I'm going to press Enter. Ok, so here we can create a new project. So click just continue. And this will create a new project on our Google Cloud platform in our case. So just wait a little bit and then click Create API key r k. So now we have created a new project right here, and we can rename our project by clicking this three dots manual. In here we can select a project settings. In from here we can, for example, type and distance tracker app. Now k, so click save, and then now we have a successfully renamed the our project. So now I can open up this menu and here where it says API in services, I'm going to go to library. And now if we choose Maps SDK for Android, you will see that this SDK was automatically enabled, the one we have used, the data automatically generated URL from our Android Studio. So now what we need to do, and we need to go to Google Cloud Platform. Then I need to click this menu here. And then down below I need to scroll until I find the Google Maps platform. Here I need to click credentials are k. So as you can see, this key was now automatically generated. And when I click on this API key number one, we're going to open up a new window here, and you'll see that now everything is already here for us and we can just copy this API key. So click this button and now let's add that API key to our Google Maps API XML file right here. So just pays that API key. And now when we run our application, we should be able to see our Google map. So let's run our app. Sometimes it might happen that you need to wait a few minutes until you can see the actual map. Now case. So there we go. Now we can see our Google map and this marker is showing us Australia, city named Sydney. So we can zoom in a little bit our k, And of course we can close this file. We can move back to our enjoyed view. We can close the permission fragment for now, and these permissions object as well. And in the next video, we're going to customize our fragment maps layout. 35. Design MapsFragment Layout: Hello there and welcome back. So we're in the previous video, we have generated our API key for Google Maps, and we have added that API key to our project. So in this video, we want to design our fragment maps layout. And our layout should contain this support MapFragment and also two TextViews and three buttons. So now let's open up our fragments. Fragments, maps, layout. And here I want to use the constraint layout is a Ruther layout. So let me just add here a constraint layout. I came here, I'm going to just copy those two lines of code or cut them and paste them on our constraint layout here. We also need to add the two important attributes, layout width and a layout height. So I can type hero match parent, layout height match parent as well, our game. And this fragment now can be put inside this constraint layout. So now we can select our fragment and we can constrain that to apparent horizontally and vertically. The ID of this fragment will be a map. Next, here I'm going to add two different TextView. So well, one TextView will represent basically a message that will say tap on my location button to continue or something like that. And the second TextView will basically be used as countdown timer. So first I'm going to add the text view, which we'll represent that countdown timer, R k. So let me just connect those constraints to apparent vertically and horizontally case. So down below I can say here, I can change the ID to something different. So press the Shift plus F6 and I can type here. Timer, underscore TextView ARE came here. I can just type, for example, number three because this timer will count down from three to 0. Down below, I can add a few more attributes. So I can use a text color to red. I can use a text size too. A DSP text style can be bold, and it should look something like that. So it's default visibility will be invisible. And we are going to show this timer TextView programmatically from our maps Raymond, later in this course, you will see for now I'm going to set its visibility to invisible, so something like that. And then I'm going to add one more text view on the top here. So I'm going to also constrain this TextView horizontally and vertically with the parent. And here I'm going to change the ID of this second TextView to something different. So press the Shift F6, and let's add here a hint, text, view and click Enter. And here I'm going to say, for example, our DEP on my location button down below, I'm going to set the text color to black. Text size or text style can be bold. Text size can be 20 SB. So what this text view will be visible and we're going to change its service ability programmatically from our maps fragment. So basically, whenever we open or run our application, so let me just run our app so you can see came. So whenever we run our maps, we're going to see this message that will say. Tap on my Location button. And of course we're going to add that myLocation button later into squares. And basically we want to disable almost every gesture on the map so user cannot move around and the user can only click this myLocation button after he launches this maps foramen. So you will see, and of course in the visibility of this hint text view will be visible. But we're going to change that programmatically later in this course you will see. And finally, we need to add the three buttons. So one button will be start button, the second button will be stopped button in the third one will be reset button. So let me just add first this start button. I'm going to connect a left-right and a bottom constraint to apparent. So don't worry, I'm going to change that with the code here. So bottom two, bottom of, I'm going to say here parent and to end off parent as well, and start to start off parent. Okay, so now it looks good, sour layout the width and height, there should be a wrap content margin on the bottom can be maybe 16, and on the right and the left can be 0. So it can be centered here vertically. Texts should say, start for this button. Now, K perfect. And it's the visibility will be visible at first, so it's default. Visibility value will be invisible. So press this next. Let's set the second button. And again, I'm going to just the constraint that with apparent like I did with the previous one. Now K, So like that here I'm going to say stop. Here. I'm going to change the color of this button. So let's use a beggar around tint attribute and I'm going to use a red color for our stop button are cases where it can look something like that. Of course, bottom margin can be 16 as well, our left and right 20. And let me add just one more button. And of course this button will be invisible as well by default, R, k. And let's add the third button here, k. I'm going to add the same constraints as before. Here I'm going to change that to a reset. Here. Background tin can be orange, and also I'm going to add the one icon on our third button. But first let me add here a margin of 16 on the bottom. And now I'm going to add one new icon to our project. So vector asset here I'm going to search for maybe a refresh our K. I'm going to rename that to IC, reset Next and Finish. Here I can specify a new attribute name, the app icon. In here I can just telling a drawable IC reset our case or now our third button, we'll have ICANN. And also I can change the IDs of those buttons. So first button, let me just click cashews plus F6. This first button will be named a Start underscore button, and this second button will be renamed to stop underscore button. And the third one, so Shift F6, reset underscore button, click a refactor our k, And let's add those strings to our strings.XML. So all plus Center are k. Now stop. Kay, now start o, k, All placenta here as well, perfect. And we can also add here this number three for example. So we don't see any warning now, and this is how our maps fragment layout will look like. So of course, I'm going to set the fourth visibility for our reset button to invisible as well. So at first, only our hint text to you will be visible. And of course, later when we start implementing the logic, we are going to change those views, visibility as we need. Okay, so before I finish up per this video, I just want to do one more thing. So let me just open this HTML code and I want to convert this fragment maps to our data binding layout. So press here all plus enter on our Constraint Layout and press Convert to data binding layout. Because there we're going to need to use data binding to bind our viewers with our maps fragment. And now let's open up our maps fragment in here. As you can see by default, we have this callback variable, which is basically implementing this on map ready callback interface. But instead of using this interface in this variable and we're going to implement that interface on our maps fragment. So let me just add here a comma, then a map ready callback in. I can remove this whole callback button. Now as you can see, we can see a warning here, and let's press all plus Center. And now we can override on the map already function. So this function will be triggered every time our map is ready. And now we have an error here. And instead of passing the score back, we can just type this and this is referring to our maps. Raymond in our maps fragment is implementing the same interface. So that's all fine. And now I'm going to just create two variables on the top here for our viewer bindings. So now I'm going to write private var under score a binding. Here I'm going to use a fragment maps bindings. So this class was automatically generated by data binding when we have converted our layout to a data binding layout. So press enter and here we're going to add a question mark and its default value will be null. So down below we're going to create another variable, but this time a read only variable named their binding in here we're going to use the getter to get the value of our underscore binding and the inside of our onCreate view, we're going to just color underscore binding, they are equal. Then a fragment maps binding dot inflate. And here we can just pass here this inflator. In, of course here we can return binding daughter Ruth, and now we can remove this question mark in here. I need to add a double bang operator so I can remove any warnings. And of course, at the end I want to override the onDestroy view. And here I want to set underscore binding to null so we can avoid the memory leaks and the inside our onCreateView, I'm willing to just add three onClick listeners for now. So binding dot, start button, dot, setOnClickListener. And here I'm going to just add click listeners for those two buttons as well. So stop button and the reset button. So for now, that will be all in the next video, we're going to continue working on our app. 36. Enable My Location Layer: Hello there and welcome back. So why in this video we're going to add my location layer to our application. But before that, I just want to fix one more thing. So as you can see now, we are currently located on our maps fragment. But now when I click back, as you can see, we're getting back to our permission fragment. And that is a bad user experience because that's not how we imagined this functionality. So in order to fix that, we need to open our navigation now graph. And from there, we need to basically destroy our permission fragment whenever we navigate to our maps fragment. So for that, let me just select this arrow which is pointing from permission fragment to our maps fragment in here, willing to select pop up tool in here. I need to select permission fragment. In here. I need to check this option to true. So pop-up to inclusive. And now when I run our application, we shouldn't be able to navigate back to our permission of fragment anymore. Okay, so let's check that out. And here we are currently at our maps fragment. And now when I press a beggar button, as you can see our application or will close. So now that we have a fixed depth, we can proceed next n, We can add myLocation layer or myLocation button right here on solids, open up our maps fragment. And here first I'm going to create one global variable, private. Late in need of our map, of a type of a Google Map. And I'm going to initialize this variable inside our own map ready function, which we have a overridden because we have implemented this Almere periodic callback. So here inside them when to call this map object and then I'm going to use this Google map object from the parameters. So first let me just rename this to Google map, okay, so it can make more sense in here, I'm going to also add double Bangor operator, okay, So when x, I want to add my location layer to our Google Maps. And also I want to change your settings. So we're here and we're going to call map object. Then I'm going to call is myLocation enabled. And I want to set that to true. So now as you can see, we are going to receive a warning here telling us that this line of code requires that permission. But since we have already checked for our fine location permission, we don't need to do that here anymore. So now I'm going to press alt plus enter in here. I'm going to add this suppressor linked notation. So missing permission because we are already checking for this permission inside our permission fragment, and we don't need to check that here as well. So down below I want to call this map object again, they want to call a UI settings. So from here I want to some settings to our Google map and willing to disable some are controls in their gestures because we're not going to need them in here. First I'm going to start with is zoom control. Controls enable. I'm going to set that to false because we don't need those zoom controls anymore for our application. Then I'm going to use is a zoom gestures enable. I'm going to set that to false as well. Then it is rotation or rotate the gesture enable, I'm going to say that two force as well. Then down below is field gestures enabled. I'm going to disable that as well. Then is. Thus enable that will be false as well. In there one more is scroll gestures enable. I'm going to set that to false. So for our application, we're not going to need all of those functionalities because we don't need to give our user permission to move around the map, instead our application, or we'll move the camera view on our map as we progress in our way. And that's why I want to disable all of that. And here, there is one more thing which I want to add and that is myLocation button and click listener. So here on our maps fragment, I want to implement that click listener. So here I'm going to call our Google map object. Then on my location button click listener, our case of this one. And here also we have a warning. So let's press Alt plus Center, and let's add this on my location button click function. And here we also need to call math and that set on my Location button and click listener in here. We need to pass this as a perimeter because this is referring to our whole fragment and our fragment is implementing this listener. Okay, so this is how our own map already functioning or will look like in here, we need to handle how our Location button will function. So whenever we press our myLocation button, I want to basically hide this text which says that DEP on my Location button. And I want to hide this text with animation in the after two seconds I want to display here start button. So before I continue working on our On My Location button and clicker function, I want to create a new object here. So inside our util package, let me just create a new Katlyn object and I'm going to name this extension functions are k, press Enter, and okay, so let me just refactor the name of this file. So extension functions. Ok, so now we've got it right in here. I want to add the four different extension functions for basically hiding and showing Gov is ability of our views and also for enabling or disabling our buttons. So you will see later that those functions will be very useful. So first let me create function for our view class. And this function should be named a show or cane. So inside I'm going to type this, which is referring to the actual view, then visibility in here, I'm going to set the visibility to visible. I'm going to copy this function down below. In this second function should be named the hide. And here I'm going to say visible are. Okay. Next function will be for our button. So fun for a button. The first one should be named that enable. So here we are going to enable our buttons. So this dot is enabled to true. And let me just copy this one more time down below in this one should be named this stable in here. False. Okay, so now that we have created those for extension functions and we're going to need them in our project. And you will see. So let's close that for now. And the first inside our own myLocation, a button click function, we're going to add some code here. So first, I'm going to animate our a hint text view so we can actually create a fade out the animation for that when we press our Location button. So I'm going to use a binding dot, Hinter, TextView dot animate. Here I'm going to animate the alpha property to 0 in floating value. So basically we will decrease the alpha value to 0 and our text view will be invisible. So duration for this fade out and emission should be 1.5 second. And here also I want to add the lifecycle scope so I can call our delay function. And here I'm going to call delay function of 2.5 seconds. And after 2.5 seconds, I want to basically show our button. So here first thing we're going to call our binding dot hint TextView. And I want to use this high the extension function which we have created. So after 2.5 seconds, I want to hide this TextView and I want to show our start button. So biting dot star button dot show. So those are the two extension functions which we have defined inside our extension functions here. And we're going to meet all of those functions later in our maps fragment as well, you will see, and here also I want to return a false. So now let's run our app and let's see how will that their work. So now basically, we should be able to see our myLocation button on the top right corner. So as you can see, we can see there. And when I press this myLocation button, this TextView which says On My Location button, should the fade out and that our button here or a start button should appear in 2.5 seconds. So as you can see, I have set the location on our device to be Rodrik in Australia. So now when I press this semi Location button, then our maps will take us to that same allocation. So President. And you will see that this text view will disappear. And our Start button, however, shown in 2.5 seconds. So that's exact behavior which we wanted to implement. So that's it for this video. And in the next video we're going to implement a runtime permission for our background location. 37. Request BACKGROUND_LOCATION Permission: Hello there and welcome back. In this video, we're going to request background location permission from a user. But before we start with the code, let me share with you some information about the background location, permission, and the updates with the new API versions. So if your application needs to share user location and continually, even if from the background when application is not active, then you must declare this permission in your Android manifest file, along with other location permission like a chorus or a final cation. So this is important only when requesting a background location permission on Android ten or an API level 29 in higher, on the other hand, lower enjoyed the API levels. You didn't have to include this bag around location permission at all. Because I, when your application receives their foreground location access like a coarse or fine location, then you automatically get this background location permission as well. But since we want to support their newest Android, the API levels, then we will include this new beg around the location permission and the only request it from API level 29 in a higher ok, so for requesting and tracking these background permission and we're going to modify our permissions object. But before that, we need to open up our AndroidManifest file. And here we need to add one more permission. Here, let's declare one more and that is bare ground locations. So access background location. Let's close that for now. And here we're going to define two more functions for checking if our application now has a background location permission. And the second function for requesting your background location permission. So first, let's create a new function name that has their ground location permission. This function will take only one parameter of type context in the it will return a boolean value. So here I'm going to type if build. So Android OS dot version and the SDK integer is greater than or equal to build version codes dot dot q. So this q is referring to API level 29. As you can see, this is the actual documentation. So only when our application shares or enjoy the API level of 29 in higher, then we want to check if we have this permission. So here I'm going to return, I'm going to call easy permissions. Dot has permission here. I'm going to pass context as a first parameter. And as a second one I'm going to call our manifest dot permission access background location. And of course, outside of this if block, I'm going to just return true. So if we are using an API or lower than 29, then this function we'll just return true, which is totally fine. And if our application is using API level 29 in higher, then we are going to need to check if we have this permission. And let's create another function for requesting these newer location permission. So request bang around a location permission and that this function will take only one parameter of type a fragment. And here I'm going to create one if block. So basically I'm going to copy this if block from our ball and just to remove this code. So here we are also checking if our application is installed on the device 29 in higher off API level. And if it is, then we want to call is the permission request. Permissions. Here we want to pass a fragment as a first parameter, as a second one that we need to type a rationale to explain our users. We actually need this background location permission. And for that I'm going to just type something like background location. Permission is essential to this application. Without it, we will not be able to provide you with our service. So that's the text which we want to display our user in case the user wants to deny this list permission. Then as a third parameter, I'm going to pass the actual request code. And first I'm going to add a new constant for our background location permission request code. So here let me just create a new constant. So permission ground a location request code, and it will have a number of two R k. So here I'm going to type that same constant. So permission beg around a location request code, just press or plus Center so we can import it. And as a final perimeter, we need to add the actual permission which we run to request. So Tipler manifest not permission dot axis background location, and that's all we need to add inside our permissions object here. So we have greater that all functions for checking if we have this permission and for requesting the same permission as well. So now we can close that. So now you might be wondering when and where do we want to check in requests, this background permission? Well, we want to do that when our user taps on our Started button. So here on our Start button on click listener, I'm going to add new function. So on start button, clicked in here, press all Parr Center so we can create this annual function. And I'm going to move this function down below. So somewhere here, then I can move this code above as well. Ok, perfect. So when we tap on our button, we want to check if we have this background permission. Of course, if we are using API level 29 and higher, and if we don't hear that permission, then we want to request one before we actually start using our service. So here type or if he has bare ground allocation permission, so press or plus centers. So we can import this function in hearing it'll pass a context as a parameter, so require context. And in Else block, we just want to call request their ground location. Permission function, press all plus enter R k. So whenever we press our star button, if we don't have this permission, then we're going to request one in here. Let me just pass and this R k. So before we continue, we need to override one more function here, and I'm going to override that function here. So on request, permission results are this one. And here I'm going to just paste this line of code. So I'm going to call easy permissions dot on request permission resolved. And basically we want to pass the data from this function too easy permissions, so we can handle the result with our library. And also we want to implement a new interface here in our maps fragment. So let me just call Easy permissions, permission call bags are k. And here I want to press all Center so we can important those two functions. Now, let me just place those two functions below our own request permission result. So our first there were going to handle our own permission's denied function. So here I want to call an if block and I want to call an easy permissions dot, some permissions permanently denied in here I want to pass. This is the first perimeter and list of strings here and here, and it'll pass number are 0. So the first permission. So if a user permanently denies our background location permission, then we want to call a settings dialog dot builder here let's bestseller require activity, then build, then show. So basically if our user denies our background location permission permanently, then whenever a user press the Start button, we want to show this settings dialogue so user can manually enable this location. And in Ellis blog, I just want to call our request background location permission now K, So like that. And of course inside our own permission granted, I just want to call on start button clicked function r k. So I think that will be all for our background location. And here I'm going to just a longest simple statement for now. I'm going to say here are already enabled Sowell And now I'm going to run the app and let's see and now what will happen. So I'm using this emulator of API level 29. And on this emulator we will need this background location permission. So let's press this sum allocation button first. And after 2.5 seconds, we should be able to see this Started button. And now when I press the Start button, as you can see, we're going to receive a runtime permission request. So here it says that allow distance tracker app to access this device's location all the time. So this all the time means that we want background location even if our application is not active. So you will grant our application this beggar and location permission only if you press this, allow all the timer button. And here if you click Keep end on-task again, you will get this message that says that this app may not work correctly without the requested permission, opened the app settings screen to modify their permission in here. If you press okay, then you will get there redirected towards settings dialogue to actually enable that permission to manually. But if you click Cancel, nothing will happen. And if you press the Start button again, then you will get the same screen and you will not be able to proceed the next this application's functionality until you enable that background location permission. So now I'm going to press OK. And from here I can just enable this permission or check this option which says allow all the time. Oh, okay. Let me just get back. And now if I press start and then we're going to receive this message that says already enabled. So that means that we have enabled our background location permission and we don't have to worry about anything anymore. Sowell, and that'll be all for this video. And the next video we're going to continue working on our app. 38. Implement the Countdown: Hello there and welcome back. So in this video I want to implement a countdown timer. So as you can see, this is how our application looks so far. So here we have a one, TextView which says that one, My Location button in here. When I press dislocation button, then these texts will slowly disappear and the Google Map will point or move the camera to our current position on the map. So let's check that out. So as you can see, now we can see our current location, which we have specified in our Android emulator is this specific rent week location. So now when I press the Start button, I want to implement a countdown timer, which will start from the second. So we should be able to see here, for example, three to one end goal. And after that the countdown timer is finished then, and only then we can start tracking our user's location. So only after we implemented this countdown timer, then we can proceed next and we can start working on our foreground service. So first, let's implement that countdown timer. So here, as you can see in our maps fragment, we have an on-click listener of what our start button. And whenever we click on our Start button, this onStart button is clicked. Function will be triggered and let me just move that down below so we can take it out r k. So here it is. And here I just want to remove this log statement. And I want to say here, start count down. So we're going to create this function down below or came. And after we press our start button, then also we want to hide our Started button and we want to show our stop button. So down below it's been just call binding dot star, the button sable. So you want to disable our Started button and also run to hide our starting button. And we want to show our stop button. So stop button daughter shown and all those three functions are extension functions, so which we calculated in the previous video. And whenever we press the Start button, we should trigger this start countdown function. And we should of course hide in disable our start button and show our stop button. So now we're going to start working with our starter countdown function. So first here, what I want to do, I want to show our timer text view so we can actually display that timer or a countdown. So here I'm going to call binding dot, Timer, Text view, dot show, show, arcane. And also we want to disable our stopping button. So why do we want to disable our stop button? Well, it's because when our countdown timer starts, we don't want the user to be able to cancel anything. So only after that countdown timer is finished and we receive a first location from our surveys. And then we can enable our stop button. And you will see later when we actually start implementing our service. So for now we want to adjust the display, our timer TextView, and disable our stop button. So down below I'm going to create a new variable named a timer. The type of this variable shouldn't be count down timer or came in here, I want to just call our countdown timer in here as a perimeter is, I need to specify two values. So the first one is milliseconds in the future. So that's basically the number from which our countdown timer or should start, and our countdown timer should start from the third, second. And in that case, I should say here for seconds and here for the interval, I'm going to say 1 second. So basically our countdown timer should triggered every second and it should less than three seconds. Okay, so let me just open the brackets here. And as you can see now we have a warning here. So press all plus Center and here we need to add the two functions, so on teak and on finish. So this authentic should be triggered. Every second in this on finish should be triggered the when our countdown timer is completed. So first we're going to start working with on thick function. So here I'm going to create a new variable named the current second. In here, I'm going to use this longer variable from this function and I'm going to rename this function to something different. So milliseconds until finished. In here, I want to divide that with basically 1 second. In that way, we're going to get the current second on every thick in our countdown timer. So basically this current second will have the value of three, then two, then 10. And here I want to create one if block and I want to say if current second, I wanted to convert it to a string. So if that is equal to 0, then instead of displaying 0, I want to display a text which will say goal. So here I'm going to call a binding dot timer TextView dot text. And I want to send it to go. And down below, I also want to change the color of our timer TextView. So set text colour here on to call context content dot get color here, require context as a first parameter, n r dot color dot blank as a second parameter. So basically I want to change the color of our timer TextView to black when we get to 0. And instead of displaying a 0, I want to display a goal. And down below in Else block, I want to do basically the same thing. So I'm going to just copy those two lines of code and I'm going to modify this color to red for example. And here for the text, I can just say current second, and I can convert that to a string, of course, now k. So basically on our countdown timer, on each second, I want to change our timer TextView so we should be able to see a three to 10 we're going to replace with this texts, which will say in Go and the text color for this goal should be changed to black, and the color of those numbers from three to one should be read. So that's the logic behind this countdown timer. And of course, on this finish or function, I just want to hide our, our timer TextViews. So Timer Text view dot hide. And finally, below everything, I want to call a timer dot start. So I can actually start this timer or case. So this is how our start countdown function should look like. So now we can run our application and see if everything is gonna work just fine. Okay, so now press this myLocation button. And now when we press the Start button, we should be able to see here this timer TextView, which will change its text every second. And we should be able to see 321 and then go. And when we see go, we're going to see a black color of this text view. And basically when we finish this countdown timer, and then at this timer text view will disappear. Let's click Start. So you can see 321, then go. And as you can see, those numbers were colored in red and our goal text was colored in black. And of course you saw that while that countdown timer was working, our stopping button is disabled. And of course, we are going to enable this stop and button once we actually start them moving on the map. And you will see about that when we actually start creating our foreground service. So well, for now, that would be all. And see you next video. 39. Introducing with Services: Hello there and welcome back. Before we actually go and create their service in our project. First, I'm going to give you a brief explanation about services in general. So we're a service is an application component and that can perform a long-running operations in the background, it does not provide a user interface. And there once started, a service might continue running for some time, even after user switches to another replication. So well, for example, our service can handle network transactions, play music, perform a file, input and output operations, or interact with the content provider all from the background. And there are three different types of services, foreground and background in the bound service. So a foreground service performs some operation that there is a noticeable to the user. And for example, in audio app would use a foreground service to play an audio track and foreground services and must display a notification. And foreground services continue running even when the user isn't interacting with the application. So well when you use a foreground service, so you must display a notification so that the user is, are actively aware that the service is running and this notification and cannot be dismissed are less. The service is either a stopped or removed from the foreground. Next though we have a background service. And background service performs the operation that the isn't that directly noticed by the user? For example, if application you use their service tool compact, it's storage. That would usually be a background service. And there finally are bound service offers. A client server interface that allows components to interact with their service, send the requests and the receiver results. They're bound. Service runs only as long as another application component is bound to it. So a multiple components can bind to the service at once, but when all of them are unbind, the service is destroyed. So were to create a service, you must create a subclass or for service or a user one off its existing subclasses. And in our case, we're going to use their lifecycle service, which is a lifecycle away or a service. And the most important callback methods that you should override our onStartCommand, onBind, onCreate, and onDestroy. So well for onStart command, the system invokes this method by calling us start service function when another component like activity, for example, requests for their service to be started. And when this method executes, then the service is started and kinda running in the background indefinitely. And that if you implement this, it is your responsibility to stop the service when its work is completed by calling stopSelf function or a stopService function. Next, onBind function. So the system invokes this method that by calling bindService function when either a component or wants to bind this service next, whichever onCreate. So what the system invokes this method to perform a one time setup procedures when the service is initially created and this function is triggered there before onStartCommand, onBind functions and the service is already running. This method is not called in finally, whichever onDestroy, So the system invokes this method when the service is no longer used and that is being destroyed. So your service should implement these to clean up any resources such as thread's, register, listeners or receivers. And this is the last call the service receives solar for example. We want to start a service from an activity or a fragment. We would need to call a start service function. And after that, our service will start and the onStartCommand function wouldn't be triggered immediately. So the service would continue to run until it stops itself with a stop cell function. Or if we use the stopService functional from activity or fragment for example. So we're now after we create the service class, are willing to declare it in our enjoyed the manifest file. There, you can ensure that your service is available to only your application by including enjoyed the exported that actually do it and setting its value to false. And this will effectively stop other applications from starting your service even when using an explicit intent. Also a service that runs in the main thread or feets hosting process. And the service does not create its own thread and does not run in a separate process unless you specify otherwise. So you should run any blocking operations on a separate thread within the service for avoiding application not responding errors. And for that you can just use a quaternion coroutines, Of course. Okay, so that will be all for this brief introduction with the services. And in our app, we're going to create a foreground service. And as I already mentioned, foreground service means that we would also need to add the non-renewable notification, which will constantly stay active as long as our service is active. And that way, a user will be aware of our service all the time. In the plus, we will be able to track our user's location from the background even if our application gets destroyed. So you will see all of that inaction when we actually start implementing our foreground service from the next video. 40. Create TrackerService class: Hello and welcome back. So why in this video we're going to create a foreground service. So well, the first thing I'm going to create here a new package, and I'm going to name this package service. Oh, okay, so inside this package I'm going to create a new Katlyn class name, the tracker service. So our tracker service should extend the from a lifecycle service r k. So this one, Android x-dot lifecycle, and they're now inside this class or service. If I press control or we should be able to see some other functions which we can override. So here, as you can see in this Android x lifecycle lot lifecycle service, I went to override the onCreate onStart command. So those two functions, so click OK. And now that we have created our service, we need to declare a foreground that permission. So let's open up our enjoyed their manifest file in here, we need to declare one more permission. So foreground service in the also inside our application tag or we need to declare our service. So here I'm going to create a new service tag. And for the name, I'm going to select our tracker service class, which we have just made. Next, I'm going to specify a foreground service type in here. I'm going to say location, and then I'm going to also use one more attribute, name their export it, and I'm going to set its value to false. So in the previous video, I already mentioned this attribute in basically this flag indicates whether the given application component is available to other applications. So now we have said that to false, and now only our application now will be able to use this service. So we don't need to request the runtime permission for our a foreground service because this is a normal permission and it's automatically granted to our replication, which is a great thing. So now I can close this AndroidManifest file, and now I'm going to open up this constant, that object. And here I want to declare a tool more constants. So here I want to declare a constant val Action Service. Start and hearing with the right action service, start. The down below I want to create another constant named the action service stop. So here Action Service stop as well. So those two constants will be used to actually send the command from our maps recommend to our tracker service. And you'll see now. So we're now I'm going to open up this maps fragment and then we scroll down below. So just below our Astarte countdown function, I'm going to create another function. So private fun, I'm going to name this function send action command to service. So this function will accept a one parameter of type string, and that will be our action constant. So if I type string, all right, so here I'm going to call, I intend in here we're going to pass a few parameters. So the first one is context, and the second one is the actual class, and that is tracker service class r, k. And here I'm going to call apply on our intent so I can specify action. So this