OK, so moving on now.
Now, we won't be able to run the finished app on our current emulator.
That's because it needs Google's Youtube Player to be installed,
but we are testing failure conditions here, so we can test the failure on our emulator.
But there's one more thing we should do first, and that's to request Internet permissions, just like
we did for the top 10 downloader app.
So I'm going to make a quick change to the manifest file so that we can actually do that.
So we're going to make sure that we're in Android view, select the Manifest's folder, double click on AndroidManifest,
and what we want to do is add the Internet permission, and I'm going to do that just after the manifest's
line before the application part. So I'm going to put the user's permission tag, the name equals, and I'm going
to just type in enough characters, INTE, until Internet comes up.
So I'm going to select that and press enter, making sure that it's specified exactly like that,
and that's why, as I've mentioned before, it's usually a good idea to select it from the the drop-down list rather
than typing it in, because if you type that in any way wrong, it won't work.
And again these permissions are case sensitive so it's best to choose them from the list as I've mentioned, rather
than typing them in.
Now the app's going to fail when we run it on the emulator, but not for the reason you might think. There's
something else that's going to cause it to crash and it's pretty cool.
So let's see what it is. Now we were messing around with Gradle earlier,
so we want to rebuild the project from the build menu, build, rebuild project. OK we're going to
come up here and select run, we'll run it once.
Well actually what I did was, I selected, or left the YouTube Player signing report selected,
that's the last Gradle build task that we selected,
so that's the reason that's come up, which isn't what we want to do here.
So I'm going to just come up here, and I'll select YouTubeActivity from this list here, and now I'm going
to click on run again, and I'm going to actually run this on my Nexus 5 emulator with API 26 that we've
previously installed. Then we're going to run that, and we're going to find that it'll crash.
OK, you can see Youtube Player has stopped and we've got a crash here, and we can open up our logcat. We
could've just left it in the run there to have a look in the run tab,
"An operation is not implemented", so it's a kotlin.NotImplemented error that we've actually got.
And if you click on the error line over here, the link in blue, that actually takes us to line 38, which
in the onInitializationSuccess method, and that's of course the function that we haven't yet implemented.
Now we've used a TODO comment before, so that we didn't forget to add a safe call operator in the top 10
downloader app, but I don't think I've mentioned that TODO comments are automatically tracked, and appear
in the TODO pane at the bottom of the window down here. So that's very useful,
you can click on an entry in there and go straight to the code that relates to the TODO.
So definitely make use of that so you don't forget to come back to something that you intended to do later.
But I'll close that now, but the thing is though here, this isn't a comment,
it's actually a function call. So Kotlin provides this in it's standard library,
and think of it like a TODO comment with attitude.
So it doesn't just appear in the TODO entries, it actually throws an exception if we forget to do it.
So definitely make use of those, they're really very handy and will remind you to update your code or change
your code, if you haven't got around to doing that yet.
In other words there's no chance that you're going to forget to implement this callback, because of actually
the fact that it's crashing. So, what I'm going to do now is comment that line out.
Now it still appears when I've done that in the TODO list,
you can see down there, but I won't get an exception thrown now because that code won't be executed anymore.
Alright, so let's actually try again. Now this time I have to be careful which emulator I use.
Now we want the app to fail, so that we can see what happens when you run it on a device that doesn't
have YouTube installed.
But unfortunately YouTube can't be uninstalled from the emulators that include it. Now at the time I'm recording
this, all the API 26 emulators include YouTube. Now some of the API 24 emulators also include it now.
So what I did was, I created an API 17 emulator using a Nexus 4.
Now if you want to get similar results to me then don't try it on an API 24 or 26 emulator, because
most likely they'll probably include YouTube. So let's try running the app.
So I'm going to run it. This time I'm going to select my Nexus 4 API 17, and we should find we get an error.
And we'll just fast forward this bit so we see it quicker. Alright that's better now,
and you can see the error that we've actually got here.
So it doesn't work because YouTube isn't installed on this emulator.
But now we can see some of the error dialogues that Google have provided as part of this API.
And again we're getting the error message "This app won't run without the YouTube app which is missing
from your device".
Now on a physical device. tapping the Get YouTube App link will take you to the Play Store,
but because the Google Play Services also aren't installed on the emulator, that doesn't work and we just
get a message in the middle of the widget saying "An error occurred while initialising the YouTube Player" after
we try as you can see on the screen there. Now on a tablet with an old version of YouTube Player installed,
you'll get a dialogue that looks something like this:
and you can see the difference there is that the message is updating as opposed to installing this time.
Now after tapping the update YouTube App link,
that'll take you to the Google Play Store, and you see a screen similar to this. Now I
disabled the Google YouTube App on that device, but the update message takes precedence over the Disabled message,
so I can't show you how the Disabled dialogue would take you into the Settings, so that you can enable
YouTube if you disabled it. We'll see that later. Alright, but over all that's pretty cool,
and instead of just displaying an error message, we are actually taking advantage of Google's error
dialogue, to help the user sort out some of the problems for themselves. And we'll see how to automatically
take the user into the settings for our apps when we look at permissions in more detail later.
Alright so we've created the code to cope with failure.
Now let's have a look at what we need to do if initialization was successful, by adding code to the
onInitializationSuccess function.
Now I'm going to go ahead and change the parameter names because p0, p1 and p2 really aren't very informative.
I'm going to rename them to match the documentation we're looking at.
Alright, so rather than going directly to the documentation this time I'm going to search for it, because
that's probably what you'll end up doing when you start experimenting.
So if I switch to a browser, and if I actually do a search here for youtube player, then oninitialization
success, all one word, and generally it's a good idea to include the name of the class and not just the
function when you're searching.
And that's because there's probably hundreds of different classes that have some sort of initialization
success function.
And as you can see we've got quite a few results back, but I generally look at the URL which Google show
just below the title of each result, and the official Google documentation is that developers.google.com.
So that would be the link that I would normally check out first.
Now by being fairly specific in the search, we get the Google documentation as the first result.
So I didn't have to do too much thinking about what to search for either. We're working with the YouTube Player,
and we're interested in the onInitializationSuccess function,
so I just used those two terms as you saw when searching. Now the result was the reference doc for the
interface that defines these two functions,
so let's see what they have to say about the success method.
So we've got this onInitializationSuccess method here,
and if you go down towards the bottom of the page, you can see more details about this.
These are the three parameters that are actually expected.
Now the provider is an object that implements the YouTube Player.Provider interface, which our You
TubePlayerView widget does. So that parameter will contain a reference to our Player widget.
But don't take my word for it. You can log the class name of objects that you get as parameters, to see
what you're really getting, and I'll show you how to do that in a minute.
Now the second parameter is a YouTube Player that we can use to control playback such as pausing or
stopping the video.
Now we're not going to do that, but we will monitor the Player and provide some feedback on what it's doing.
And that brings us to this third parameter: was restored. Now if that's true then we shouldn't start a new video, and
that's because the Player will continue with the one that it was already playing.
Alright, so back to the code.
Now I want to add some logging, so let's add a tag to this class, just below the class definition I'm going to do a private
val TAG equals, then we'll call it YoutubeActivity.
Now we can rename those parameters and log the types of the first two.
So let's go ahead and do that.
So go to our onInitializationSuccess, we'll change p0 here to provider. We'll change the second one,
p1, we'll call that youTubePlayer, and for the third one I'll just start that on the new line, instead of P2,
we'll call this one wasRestored. Alright I'm going to delete that TODO now, because we're actually implementing
that now, and in terms of the code, let's start by logging the types of the first two parameters.
So Log.d
TAG double quotes onInitializationSuccess colon provider is, now we'll add a dollar sign,
Left to right curly braces, provider question mark dot javaClass.
Then on the next line, we'll do a Log.d TAG, and then this second argument will be the same. Actually let's just
copy that entire line, the rest of the line there, like so, and
this time it's going to be onInitializationSuccess youTubePlayer, player is, and it's going to be youTube
Player, youTubePlayer dot, sorry question mark dot javaClass.
And thirdly let's add a Toast message here, so Toast.makeText parentheses,
this, is the context, and the text we want to display will be "Initialized
Youtube Player successfully", that's going to be Toast, Toast.
LENGTH_SHORT this time, parentheses dot show.
And then lastly what we're going to do is put if parentheses,
not wasRestored, then we're going to do a youTubePlayer question mark dot cueVideo.
Then we're going to, in there, we're going to type YOUTUBE_VIDEO_ID. Alright so I've used our normal logging,
and whenever you get an object that's a parameter, you can use this dot javaClass as you can see me using on lines
41 and 42, to find out what kind of object it is. And we'll display a Toast message so that the user knows
that everything's going well so far, and then show the video using the ID we got earlier.
Now as we saw in the documentation, we only want to play a new video if the player isn't resuming playback of
an existing one, so the code check on line 45 checks that wasRestored is false
first. Now to play the video, we call the cueVideo function and provide it with the ID of a video,
and I've used the ID that we copied from the URL from the YouTube site in the previous video.
Now there's a bit more we could do in here,
and in the next video we'll start adding some code to monitor the various events that happen when the
video starts playing. But let's actually see it running first, just before we end the video.
So I'm going to run this time, on the Nexus 5 emulator, so
what I'll do is, I'll just close down this old emulator, and then I'm going to run it.
Then I'm going to select my Nexus 5X API 26, remembering that this particular build includes the YouTube
apps, so our apps should run this time, and we'll just give the emulator time to start up, and then our app should automatically start.
I can see our message there, initialized YouTube successfully. There's my video, and
let's just try that again because we might have had an issue because it was starting the device when I started
the app, so go back and try it again. We're initialized as you can see at the bottom, so that was working fine.
And again I can actually run the, start the video, and you see that is actually working fine, and I can
pause the video as you can see there, pause, and I can resume it and it starts in the same place.
So that's working nicely.
Now if you can't run these emulators on your computer for whatever reason, then connect your Android device
up and test your app on a physical Android device.
Alright so let's finish the video here. In the next video, now that we've got the app running and the
Toast message is working OK,
let's actually have a go at adding some listeners to the YouTube Player, just so we can get some feedback
when various things happen. So I'll see you in the next video.