Alright so moving on, once you know what an intent is, the code's going to be fairly, really easy to understand.
So let's go, swing over to the Google documentation and find out more about intents.
Alright, so it says here that "An intent is an abstract description of an operation to be performed".
So the use of the word abstract here can be a bit confusing, because intent isn't an abstract class.
What they really mean here is that it's not tied to any particular operation.
So reading on it can be used with a start activity method to launch an activity, which is what we're using
it for in our app, and intent can also be used to send data to components that are registered to receive broadcasts,
such as a notification that a text message has been received for example, and also to start a service. But
it's launching activities that we're interested in here.
Now the next paragraph is a bit jargony, but basically means that you can use an intent to launch an
activity, without linking your code directly to the activity that you want to launch.
So if you wanted to start the devices email app, you just specify email in the intent, without having to
know which app the user's installed to handle emails on that device.
So the most significant use of intents is in launching activities, and the documentation refers to them
as the glue between activities.
So in other words intents bind activities together. Now as well as the reference documentation,
Google also provide guides on many aspects of Android.
Now the reference documentation can be quite formal, but the guides are often written in a friendlier style,
and there's actually a guides, a guide rather on intents. I'm just going to paste that link in, so you can check that out.
Now here it's saying that "An intent is a messaging object
you can use to request an action from another app component",
and that's probably a more helpful description than an abstract description of an operation to be performed,
as the previous page had.
Now this page also mentions using intents to start activities, and mentions that the intent describes
the activity to start and carries any necessary data.
So I think this page is more readable.
So watch out for URL's starting with developer.android.com/guide, as well as the slash
reference pages, because the guides can be more help.
We can see here where we've got slash guide in the URL, compared to slash reference there.
I think the slash guides are a bit more readable in many cases.
So once you finish this section, and you've seen how the code starts the various activities from our
buttons, it is worth reading the rest of this page to get an explanation of how Android handles intents.
Now don't worry about the bits about services and broadcasts just yet.
It's activities we're interested in at the moment.
Now we're going to create our own intent shortly,
but here we don't need to, or have to, because the YouTubeStandalonePlayer class will actually create them for us.
Now if we want an intent to play a video, we just call the create video intent function, if
we go back to our code, and we're using that as you can see on line 40, and to play a list of videos
as a playlist we're calling the create playlist intent.
Now both of these functions will turn an intent that we can use, to start an activity but to perform
the operation we want. Both methods need to know which activity's starting the intent,
and that's why we're providing this here as the activity.
Now we also have to provide the Google API key
and the ID of what we want to play, either a single video or a playlist, depending on which intent's
being used. And by the by the functions of the YouTubeStandalonePlayer class are documented, and we
go back to a browser, paste that link in,
and they're actually documented on the YouTubeStandalonePlayer down here. You can find out more
about it there from the link on the left, so
check them out if you want to know more about its functions.
So that's actually it. The documentation for intents may look a bit scary, but using them is actually pretty simple.
Now it's just as easy to create our own intents to start different activities in our own app. I'm going to switch
over back to the code now, and we're going to go back to our MainActivity.
We're going to add the code for the buttons on the main screen.
So the first thing we want to do is make the class implement the onClick list of interface, just as we
did in the previous video for the StandaloneActivity class.
So to do that we're just going to add a comma here,
and View.OnClickListener, and
you can see the imports are added automatically.
We then add the code to assign the listener to the buttons,
and I'm going to do that that after the setContinueView.
So it's going to be btnPlaySingle.setOnClickListener, parentheses this, and btnPlayStandalone,
or sorry, btnStandalone I should say, dot setOnClickListener, this, and accept the synthetic import
if Android Studio doesn't add it automatically, but you can see here on line 6 it was added automatically for me.
Now we've got an error at the moment but that will disappear once we implement the interfaces
onClick method, so I'm going to go ahead and do that now.
So we get Android Studio to generate the interface method by using control I.
Again, before you do that remember to make sure that the cursor is inside the class
when you do that, otherwise you'll get a weird error and it won't actually work. So I'm going to press enter there, and then we
need to add the code for that so let's actually change this.
And what we'll do is we'll try refactoring it this time, so Refactor, Rename. We'll
call it view again, enter. Get rid of the question mark, we'll get rid of the TODO. The code's going to be val intent equals
when, parentheses view.id, so R.id.btnPlaySingle, error token, capital I for intent,
making sure that Android content is the one that was selected there.
This is the first argument, comma Youtube,
this time it's Youtube with a lower case t, Activity colon colon class.java
right parentheses. We'll do the same for the Standalone, so R.id.btnStandalone error token, intent
again, parentheses, this again comma, this time it's going to be StandaloneActivity
colon colon class.java closing parentheses, then an else error token throw IllegalArgument
Exception, parentheses double quotes "Undefined button clicked". Then outside of the code block for our when, startActivity intent.
So this code's very similar to the code we just created in the StandaloneActivity class.
The difference here is that we're creating our own intents.
Now the intent class has got several constructors, but whenever you want to use an intent to launch a new
activity in your own app, then this is the one you'll often use.
Now we have to provide it with a context, so you can see we use this to pass the current context.
Now the btnPlaySingle button will launch the YouTubeActivity, and btnStandalone starts our Standalone
Activity, and these are passed as the second parameter to the intent class constructor.
Now YouTubeActivity colon colon class as you can see being used here on line 21,
that's called a class literal, and it's a way to pass a reference to a class as a parameter.
Now you wouldn't pass string or integer as a parameter.
You'd use an actual string such as, you know, tim in double quotes, or an actual number like 100,
and this is the same thing.
We need to pass an object of type class, whose value is the YouTubeActivity class, and that's how you do it in Kotlin.
Now don't worry too much about it, just remember that when you want to pass a class to a function, you
have to create a class literal by adding the colon colon class at the end,
and because these are Java classes we're also adding dot Java.
Now the other thing I've done is check that this method wasn't called by some other button. Now it shouldn't
be, because we've only got two buttons in the screen, and
we're actually handling both of them in the when statement.
So we've got a case for each button in other words, but it's good practice to make sure in case we add
a new button, and forget to update this function.
So that's why I've added the else branch on line 23.
Alright so that's it, that's our code finished.
Now there's one more thing that the new activity wizard does,
and we've got to do that manually for the StandaloneActivity class.
Now I mentioned it briefly when we used the wizard to create the YouTubeActivity class, and it's to do
with the manifest file.
So let's have a look at that, and see what that's all about.
We're going to open our manifest file up here. Now inside the application tag as you can see here on line 7, there's
tags for each of our activities, and in this case you can see we've got dot MainActivity and dot YoutubeActivity.
Now we're actually missing a tag for the new StandaloneActivity, and
I'm going to add that in a minute.
Now when we created the YoutubeActivity using the wizard, and checked the launcher activity box, the
wizard added an intent-filter tag with an action filter and a category filter.
So we've got this intent-filter that's got an action, and also a category tag as you can see. Now without
these, we couldn't launch the activity as we've been doing,
so we would've been unable to see YoutubeActivity working. So checking that launcher activity
box resulted in these extra tags being added to the manifest for YoutubeActivity.
And once again these wizards don't do anything that we couldn't do ourselves, they just save us a bit of
time and typing.
So now that we've got a way to launch the YoutubeActivity using a button, we actually don't need these
intent-filters anymore, but we do need an activity tag for each activity,
otherwise they can't be seen by the Android system and can't be launched at all.
Now the tag must include a name attribute but everything else is optional, and I'm going to also specify a label
and that will appear in the activity's title.
So I'm going to modify the YoutubeActivity element first, and add another one then for the new StandaloneActivity.
So basically again all we need here is activity,
and we've got android name YoutubeActivity, and I'm going to also add the label.
And what I'll do for clarity is put that on the next line,
so Android colon label, and we'll call that Youtube Player. So, and we'll come back to there, then I'm going to delete this
intent-filter as I mentioned, and we've got the closing activity tag now, and we're going to copy that,
and we're going to create another one now for our StandaloneActivity.
It has to be inside the application before the application closing tag, so
this time instead of YouTubeActivity, we're going to call this one StandaloneActivity, and you can
see that Android Studio is correctly referring to our StandaloneActivity class, and press enter there.
OK, get rid of that trailing activity there, and
this time it's going to be called StandaloneActivity.
That's going to be what's on our label.
Alright, so at this point now the apps finished, and we can actually run it on a device to make sure it all works.
So I've got my emulator going, and I've got it set to portrait mode as you can see there. Now,
we've been running the YoutubeActivity until now,
and Android Studio reconfigures the play button on the toolbar, so that it runs the last activity that
you selected, you can see up here it's YoutubeActivity. Now
if I just click the run button, I actually get this error pop up on the bottom of the screen.
So I'll do that and show you, see down the bottom there, the error,
"Error running YoutubeActivity:
The activity must be exported or contain an intent-filter". Essentially it's now complaining about
the fact that the YoutubeActivity entry in the manifest file must have that intent-filter,
and of course we've just taken that out of there. But that's fine though because we don't want to run Youtube
Activity directly anymore.
We're going to be using the buttons that we've added now.
Now what we're going to do is make sure that we're in an MainActivity. Now
sometimes when you right click in there, it doesn't give you the option to run MainActivity from the menu.
You can see in this case I have got it to work but sometimes it doesn't work. If that doesn't work and you can't
see it, come over here to MainActivity and right click it on the actual class name and select run MainActivity.
And if that doesn't work you may need to come up to build, and actually rebuild the project.
One of those methods, well you may have to rebuild and then either of those other two methods should actually work.
So I'm just going to right click now and select run MainActivity, and I'm going to run it on my emulator.
Alright, so you can see now that's our main screen with the two buttons, so that's working.
I'm going to tap the PLAY A SINGLE VIDEO button now, and we get our YoutubeActivity launched,
that's the one that we've been testing before.
So when you want to start a new activity in your apps, this is one way to do it.
So that's playing fine. We're getting our Toast messages as you can see, so
that's all working good. I'm going to go back to the menu with the back button,
and this time we're going to go and tap the standalone sub-menu button. That launches our Standalone Activity,
and here's our sub-menu as you can see. Now the title says Standalone Activity, because that's the text we
put in the label in the manifest.
So let's check the single video first. I'm going to tap that button. You can see that our video
got launched again. Now it doesn't start playing automatically,
so you do have to tap the Play icon.
You can you can see that it's running in landscape at the moment, on it's side,
and that's because the Standalone Player's running at full screen.
So I'm going to rotate the device, play it again.
So the Google Standalone Player doesn't allow itself to be destroyed when the orientation changes,
but it also doesn't handle the change itself.
It makes sense in this case because a full screen video really has to run in landscape,
otherwise it wouldn't be full screen.
Now notice that when I'm pressing pause here,
we're not actually getting any Toast notifications. With the Standalone Player there's no capability
in the code for us to get those callbacks.
It's only when we use the YouTubePlayer widget in the YoutubeActivity that enables you to do that.
So that's also working now. So I'm going to go back to the menu.
Let's have a look at the Playlist.
Now notice these arrows, you can't quite see, you'll have to play it a little bit so we can actually see it,
and we've actually got an ad appearing. So let's just wait for that to finish,
and I'll just pause this when I can.
OK, so notice this arrow here. This moves through the Playlist, onto the next video.
Now once again the video doesn't start playing, or didn't start playing automatically, so you can tap on Play as
you saw me do to get it to play. And if I click on next now, this arrow here, it
actually goes to the next video in the Playlist sequence. We'll wait for the ad to finish,
and that's a completely different video to what we saw previously, so I'm just going to pause that, and I
can then go back to the previous video if I wanted to. Now what I wanted to show you,
just wait til we go a little bit further here. Now you can see there it's fairly dull,
but when we get to the start, to the first video of the Playlist, I can't click that anymore. So I'm actually
clicking that but nothing's happening,
as you'd expect because we're on the first video. And I can go forward multiple times, forward again,
and notice it's helpfully telling us at the top there, once this ad finishes,
which is becoming quite annoying, which video we're on, we're on three of seven. Now
eventually by doing that I could get to the last video,
then we wouldn't be able to go forward any further, then I could go back to the previous videos.
So that functionality, in terms of playing the videos in the Playlists and skipping back and forward,
that's actually part and parcel of the YouTube Standalone Player. So that's all working fine.
And our YouTube app's finished. Now in this section we've actually covered quite a lot.
So we saw how to include a third party library in our own apps, when we added the YouTube API jar file
to the libs folder, and we created a reference to it in the build.gradle file.
Now we also checked out the documentation for the API, and the Internet is an excellent resource,
whenever you need any information on how something works or how to use various classes and functions.
And it's not just for third party libraries either.
The Google documentation on Android itself is also a very useful source of information, and they often
supply guides as well as the reference documentation,
so get in the habit of searching for documentation on the classes you use.
We then implemented a couple of interfaces to allow the YouTubePlayer, the YouTubePlayer to call functions
in our code, when something interesting happened during playback.
We did that again as an alternative way of setting a listener on the buttons in our app.
Now the app also used intents to start other activities,
so now we can create more complex apps.
that've got more than one screen.
Now there are other ways to do that, and we're going to be looking at something called a fragment a bit
later, but starting activities using intents is a crucial part of Android programming.
So that's just about the end of this section,
but I'm going to finish it off now with a challenge.
So the challenge is to use the documentation on the YouTube Standalone Player to change the app, so that
the video starts, or the videos start playing automatically after you've tapped the buttons on the Standalone menu.
Now at the moment the videos are queued, and the player has to tap the Play icon to get them to play,
as you saw me do in this video, so you want them to start playing automatically when the button's tapped.
So do that for both the Video and the Playlist,
and in the next video, I'll actually go through my solution.
So I'll see you in the next video.