1. Home
  2. Training Library
  3. Programming
  4. Programming Courses
  5. Layouts and Animation for Android Apps

Project Youtube Player Completion

Start course
Overview
Difficulty
Intermediate
Duration
4h 7m
Students
1
Description

In this course, you'll start experimenting with XML code and diving deeper into layouts, namely linear and constraint layouts. We'll also look at animations and build a few fun features with them. Then, we'll take a deeper dive into the Kotlin programming language and constraint layouts, before building a fully functioning Tic-Tac-Toe game.

On top of that, we'll then build a second app which can play YouTube videos within it, and you'll learn how to work with APIs and API keys.

Intended Audience

This course is intended for beginners to Android app development or anyone who wants to master coding in Kotlin.

Prerequisites

Since this is a beginner-level course, there are no requirements, but any previous experience with coding would be beneficial.

Transcript

Hello and welcome back. In this video, we'll finish up our YouTubeplayer demo. And first, I want to show you the two documentation links for this. And we already viewed one when we downloaded the YouTube player API. Here we go. But basically, if you type in android YoutubePlayer API, this gives you more information on the API. And you can click around here. You can also look at the YouTubePlayerView. This is what we're going to be using, and we got all of these classes in our application, when we incorporated the YoTubePlayer API in our app. 

The one we're going to be using is this one YouTubePlayerView. So, this is the documentation for it. Again, you can take a look at this if you want, and to implement this view, we'll be using a custom view, so you'll be seeing something new here. So, let's get started with the view then. Back to our app. Here we go. Right now, we only have this text view. I'm going to get rid of this. And let's start building our custom view. So, I'm going to say <view, you see view pops up right there. Hit 'Enter'. For width, I'm going to say, match_parent, and for height, I'm going to say, wrap_content. And then for the constraints, I'm going to do something I haven't done before, which is, I'm going to allow Android Studio to infer them for me. All right. 

So, if you highlight the view that you're on, and then go to this magic wand over here. You see it says Infer Constraints. If I click on it, check it out, it goes ahead and adds some constraints for us. We have start to the start off, so left, top, and to the right. All right so, all three that we could have added manually, but we just did it with one click. That's great. Over here, I have the id. I'm going to change the id to youtube_view. And now the name of this view or the class name. Right?

It's a custom view. But what we want to call this is YouTubePlayerView, because that's what we're going to use for the documentation. So, one way to do that is we can define the class name within here. All right, we'll say class = and then the entire name ending with YouTubePlayerView. So, where do you get this? If you look back at the documentation for YouTubePlayerView, you see right here com.google.android.youtube.player.YouTubePlayerView. This entire thing, that's the name, all right? So, I'm going to copy this, 'command C', and simply paste it in here. And because I have the library, the API, I can actually use this and you see, I don't get any red lines anywhere. Okay, so now our view is ready to go. 

You see it over here. And once we have a player over here, it's going to show the entire thing, and I'm not sure if I covered this before, but if you wanted to see what this would look like in the actual emulator with the app name and everything, you can actually go to this right here, 'View Options' and click on 'Show System UI', and you see the name pops up, and this would be the view that would show up in the emulator, right, with the name and everything. But I'll leave it as my old one, I really need that. Okay, now let's hop on to our main activity and implement the code first, and this is the first time that we'll be doing this, is instead of our main activity, extending AppCompactActivity right here, we're going to be extending the YouTubeBaseActivity. 

Okay, so right here, I'll get rid of AppCombatActivity, and change this to YouTube, t is capitalized there and you see as I start typing it, you see YouTubeBaseActivity pops up, and if I enter this, it will import the relevant class for me right there. And if I expand it, you see here YouTubeBaseActivity. So, now my main activity extends YouTubeBaseActivity. Great. And I won't be using view binding for this. I'll keep things simple. And first, what I'll do is create a variable of type YouTubePlayerView. I'm not going to assign it yet, I'm simply going to create it, okay? So, similar to how we did it for our binding variable which we've been using for view binding, I'll start off with private and then lateinit you see lateinit var. And I'll call this myPlayerView, and this is going to be of type youtubePlayerView right there. 

You see down there YoutubePlayerView, and you see the class is now imported here as well. So, I can use the type of YoutubePlayerView in my class, and then within my onCreate, I'll keep my onCreate nice and neat for this one. So, what I'll do is simply call a function which I'll define later and use that to initialize the youtubePlayer and everything. So, I'll just call it initializePlayer(). Now, if you had a button in your layout and you wanted to start your video when the button was clicked, you would use onClick and provide the function name. But here I'm simply calling it directly from my onCreates, as soon as the app loads, it's going to start this. It's not defined obviously. 

So, I'm going to go ahead and define it, and I'll say private_fun initializedPlayer and you may be wondering, what does private mean? Private means it's only accessible to my class right here. And then open close parentheses, and then open-close curly brackets. I'm ready to go and first, I'm going to need to grab my view variable and initialize it. So, right here, myPlayerView, and let's find this. So, =findViewByid. And the id, I gave this is, right here youtube_view. So, I'll look for that R.id.youTube_view right there, and we don't have to cast this or anything because we already know the type is YouTubePlayerView. And the next step is to initialize this. So, myPlayerView and the method name for that is initialize. All right. And this takes two items. 

The first one is the API key, which we created from google, and I'll put that within quotes. For now. I'll just leave it as API key. And the second one is what's called an OnInitializeListener. You can see right here, YouTubePlayer.OnInitializeListener. I have to create this. And you can do this outside if you use a variable and have the OnInitializedListener created there. You can refer to that object here, or you can create this object on the fly. And this is called an anonymous object. To do it this way, I have to say object: and then I can specify it. So, my object is youTubePlayer.OnInitializedListener right there, and then open-close curly brace. And this OnInitializedListener has two methods that need to be implemented. You see my object is showing up with a red underline here, it's for that reason. So, if I hover over it, you see, it says object is not abstract and does not implement abstract member. 

And if I scroll down, you see implement members. If I click on this, it shows me the methods that are available, and for this to work I need to implement both methods, so I'm going to highlight both of them. Okay, one is oninitializationSuccess and the other is oninitializationFailure. Okay. If I do that, you see android types in the code for me, brings in rather not types in. So, over here, I have my first one oninitializationSuccess and there's a TODO "Not yet implemented". So, I'm going to get rid of this TODO right here, and I'll get rid of this TODO from oninitializationFailure as well. So, here we need to look at three things. What are these three things? p0, p1, and p2 that are being passed into my method. You see this p0, and you can change this if you like, I'm going to leave them as p0, p1, and p2. This p0 is of type a YouTubePlayer.Provider. So, the ? over here in Kotlin, the type system can hold null values, which are called the null references, basically think of them as if they didn't exist. And if they were null, then if you didn't have this ?, it would throw an exception, but Kotlin can actually have null values that it can hold. If it was just like this, let's say I'll get rid of the ?, then it wouldn't be able to hold null values. And if this was there, it would throw an exception. All right. 

So, that's the point of the ? right there  for these types, for these objects. So p0 is YouTubePlayer.Provider. We're not going to be dealing with this, so I won't talk about this much. We are interested in these two, but primarily in p1, p1 is the player of type YouTubePlayer. We're going to be using this to play the video or load the video and all that good stuff. And p2 is of type Boolean. p2 is basically if the player was restored or not. And you can use this or you can't, we are not going to need it, but I will add it later on. Let's start off with p1, which is the player that we're primarily interested in. So, we want to grab our p1 parameter that's being passed in, and we want to run this method called loadVideo. Okay? You see, as I start typing in L-O, you see all these other methods show up as well, Playlist, Video, Videos, and they accept different things. You can pass in a list of names. You can pass in a playlist. You can do all these other things. We'll keep it simple and just load video. And it's expecting a URL for this video. I'll leave that empty for now. I'll fill this in later. But what is this red over here?  Is because see p1 right here is nullable. 

There is a possibility that p1 may be null since I'm allowing it, so I would have to check for that. But there is another way to quickly take care of this by using the not null assertion operator. So, to get rid of this, I'll do a shortcut here; two exclamation marks. And this two exclamation marks is called the not null assertion operator, and it converts any value to a non-null type. And if I happen to get a null value here, then this will throw an exception. All right. So, then we've crashed basically. But I'm just going to assume that it's not going to happen. So, that's a quick way of taking care of that. The other way would have been to check for if p1 not equals null. That would have gotten rid of this as well, and include this code of loadVideo within there. Or how to handle if p1 was equals null. So, if I did p1 equals null, then what to do? else, get onto this. Those would have been other ways of dealing with this. But I'll simply use this shortcut. And then the next step is to play it. 

So, p1.play. That's it. So, for this, I'm going to need to load the video that I want to play. So, let's pull up YouTube and get a video. So, here's one of my videos. And the URL you want isn't the whole thing. You want to grab the portion right after v=. All right?  And another way to do this is if you go to 'Share', you see this part after the be/, this last part... Actually, I can't copy just that part from here. I'll just copy the whole thing and remove the other part. So, back to Android Studio. I'm going to paste it here. And then I'll get rid of this first part. All right. Okay.  So, this will load that video and play it. And the last part is the API KEY. This is where I'm going to paste in the API key that I created in the last video. Here we go. 

So, this is the key, and I'm going to simply copy it from here. So, API key is copied to clipboard. And normally, you wouldn't want to paste your API key directly here. Depending on the security level and other security considerations, you would definitely use a different methodology for providing the API key. But for our test app right here, this is good enough. So, I'm simply going to paste this right there. And that's it. That's all I have to do. So, again, you wouldn't want to do this and expose your API key this way, if you are using, let's say, a public repository and posting this to GitHub for others to see. But security management associated with this would be a lot more videos, and we haven't covered it so far in this course just yet, so I'm just going to do it this way for now. Okay.  So, right here, I'm going to go back here because the last step I did was the signingReport Configuration, which I edited. So, I'm going to go back to app. And let's go ahead and play it, and make sure you use the Android 10 device that you have. Let's run it. All right. Looks like it worked. Let's pull it up. Here's our emulator. You see the video is loading. That's great. 

If I was using Android 11 over here, it would say, "Player failed to initialize." There you go. The video has popped up in the player. And I think you can hear me speak in the background. And if I pause it, you see I get all the options that a standard YouTube player would provide. I can play here. I can pause. I can move forward in the video. I can go full screen. Now, since this is a new emulator, I'm going to enable landscape mode, so I can go in landscape mode, especially for video. So, that's enabled. Let's close this and go this way. And there you go. The video starts playing. Now, let's do one little optimization and use this variable that we have or this parameter that's passed in of p2. And I briefly mentioned, this was basically if the player was restored. Right now, we're not using it. 

So, what happens is if a player had already started playing a video, you want to deal with that, you want to simply play from the point that the video was left at, okay? And that's what this Boolean does. So, let's use it over here. if (p2), meaning if p2 is true and that the video was restored or someone had start playing this video before, then I want to simply do p1.play. All right.  So, the player start playing it. But, again, we have this red over here and that's because p1 can hold null, so let's deal with that over here. If p1 != null && p2, then I want to play. And you see the red disappeared from here. else, I want to do this, right? Because the video had already been loaded, I don't want to reload it again, I simply want to play from that point. But if it wasn't the case and this Boolean was false, then it will simply come to this else condition and load the video and start playing it. All right. 

So, let's apply our changes and play it. So, right here, that's a slight optimization that we can make. And I'm going to start off in portrait mode. There we go. It's loading. And you can hear me in the background in the video. I'm going to pause that, move this to here, let's say, the eight minute mark. Let's see what happens. Start playing. Now, I'm going to switch to landscape mode. Check it out. It is in the eight minute whatever second time frame where I had left it. All right.  So, that's the benefit of using the was restored or p2 variable. Excellent. 

So, our YouTube player app is doing pretty well. And hope you enjoyed building this project. There's a lot of new ground we covered while building this app around actual real world programming involving, using APIs from a third-party resource, in our case, Google in the YouTube player API, and also working with an API key. So, I hope you found all of these useful, and will be able to use these skills in future apps. And with that, we bring this section to a close. Congratulations again on having made it this far. And in the next section, we'll jump into RecyclerViews which are essential while developing Android apps. Hope you're excited, and I'll see you in the next section.

 

About the Author

Mashrur is a full-time programming instructor specializing in programming fundamentals, web application development, machine learning and cyber security. He has been a technology professional for over a decade and has degrees in Computer Science and Economics. His niche is building comprehensive career focused technology courses for students entering new, complex, and challenging fields in today's technology space.

Covered Topics