Android Tutorial: How To Integrate YouTube Videos Into Your App

By Scott Cooper

This tutorial aims to give a comprehensive guide on incorporating the YouTube library in your Android application as well as providing examples of the various ways it can be used to display YouTube content. We’ll also be taking a look at some of the pitfalls and limitations of the library and ways to get around them. To give some visual examples I’ve whipped up a quick app. You can also view the source code.

I’ll be referring back to the source code of this application throughout this tutorial so it’s best to keep it open.

If you want to see what this library is capable of in a real world application, then check out my Riddio on the Play Store.


Now that we have the shameless plugging out of the way, we can move onto the setup. The YouTube library acts as a way to hook into the functionality of the main YouTube app, and therefore won’t work without it. To be able to use the library your device must have version 4.2.16 of the mobile YouTube app (or higher) installed.

You will also (obviously) need to download the library file itself. For this tutorial we will be using version 1.2.1.

Before you can start using the library, you will need to register your application with Google and get a developer key. The developer key will be used throughout the entirety of this tutorial and you won’t get far without it. Google Developers have created a pretty good guide on registering your application. Once you have the key, create a new string resource called DEVELOPER_KEY that you can use through the application.

Also, since we're going to be using network calls to talk to the YouTube server we need to add permission in AndroidManifest.xml, place this line just above the opening application tag:

<uses-permission android:name="android.permission.INTERNET" />

Finally, you’re going to need some YouTube videos, and by videos I mean video ID’s, but what exactly is the ID of a YouTube video?

Everything that comes after ?v= is the ID of that video, something like this: Hf13wwA8o8o.

If you check 'YouTubeContent', in the source code, you can see where I list the ID’s used in this application.

static {
        addItem(new YouTubeVideo("tttG6SdnCd4", "Open in the YouTube App"));
        addItem(new YouTubeVideo("x-hH_Txxzls", "Open in the YouTube App in fullscreen"));
        addItem(new YouTubeVideo("TTh_qYMzSZk", "Open in the Standalone player in fullscreen"));
        addItem(new YouTubeVideo("tttG6SdnCd4", "Open in the Standalone player in \"Light Box\" mode"));
        addItem(new YouTubeVideo("x-hH_Txxzls", "Open in the YouTubeFragment"));
        addItem(new YouTubeVideo("TTh_qYMzSZk", "Hosting the YouTubeFragment in an Activity"));
        addItem(new YouTubeVideo("tttG6SdnCd4", "Open in the YouTubePlayerView"));
        addItem(new YouTubeVideo("x-hH_Txxzls", "Custom \"Light Box\" player with fullscreen handling"));
        addItem(new YouTubeVideo("TTh_qYMzSZk", "Custom player controls"));


Extract the contents of the YouTube zip file you downloaded earlier and locate the libs folder. Contained within this folder is the YouTube library, simply copy the .jar file from this directory into your project's lib directory, typically located at appname/app/libs/.  

Once the .jar is in there it should appear in your project structure on the left of the screen in Android Studio, if you can't see a folder structure then use the drop down at the top of this pane and select Project.

Checking for YouTube

As previously mentioned, the library depends on the main YouTube application so it’s necessary to check whether it exists on the device before we start trying to use it.

We can check by using the 'YouTubeApiServiceUtil' class. It’s best to do this as soon as possible, but only where necessary. If you’re only using the library as a small part of your app it would probably be best to check just before you attempt to utilise it. The reason for this is because if the app is missing the user will be presented with a dialog.

You can find sample code for this in the onCreate method in MainActivity

//Check for any issues
final YouTubeInitializationResult result = YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(this);

if (result != YouTubeInitializationResult.SUCCESS) {
    //If there are any issues we can show an error dialog.
    result.getErrorDialog(this, 0).show();

Let's Begin

Now that we’ve established that the YouTube app is installed, we can start using it! Firstly we’ll focus on displaying thumbnails. The library provides a new view: YouTubeThumbnailView, which we’ll be using to display thumbnails of videos.

We can define this in XML and then get access to it in your class, like any other view. In the sample application I’ve used it to display thumbnails on each row in the list. The XML of which looks like this:


    <!-- Video Thumbnail -->

    <!-- Video Title -->


This layout is inflated and used in the VideoListAdapter, where the rest of the magic occurs! Unfortunately the YouTubeThumbnailView isn’t quite as straight forward as the standard ImageView, there’s a bit more code involved in making it display an image. Fortunately it’s not that complex, plus it also downloads it and handles the bitmap itself.

To load an image into a ThumbnailView, you need a ThumbnailLoader. The job of the Loader is to take the ID of the video and load the Thumbnail for that video. When you call .initialize() on the ThumbnailView you provide the developer key you got earlier, and a callback listener. The two callback methods are used to associate a Loader with a ThumbnailView.

    public void onInitializationSuccess(YouTubeThumbnailView view, YouTubeThumbnailLoader loader) {
        mLoaders.put(view, loader);
        loader.setVideo((String) view.getTag());

    public void onInitializationFailure(YouTubeThumbnailView thumbnailView, YouTubeInitializationResult errorReason) {
        final String errorMessage = errorReason.toString();
        Toast.makeText(mContext, errorMessage, Toast.LENGTH_LONG).show();

All of the logic is contained within the getView method of VideoListAdapter. If the view is null then we create it by inflating the layout, in doing so we initialise the YouTubeThumbnailView. When the ThumbnailView is initialised we get a callback to either onInitializationSuccess or onInitializationFailure. If it's a failure then we can simply display a message, or handle it in your own way. If it's a success then we put the Loader and the ThumbnailView into the map to be used again later. We also call setVideo which runs to the server to retrieve the Thumbnail.

The next time we try to create this view, we can simply retrieve the loader from the map and call setVideo on it again. This is called the View Holder pattern and we use it to reduce the overhead of finding the views everytime getView is called, my sample app only has a few rows so it doesn’t have too much effect but it’s still best practise. For a more up-to date way you should probably use the RecyclerView as it forces the View Holder pattern.

Ok so now we have a list of videos with thumbnails, now we just need a way of watching them. In the demo app, each video opens in a different method or variation on a method. For ease of readability I’ve condensed all logic to the onListItemClicked method within the VideoListFragment. I’ll be going through each switch case in detail, explaining what it does and its usefulness.

YouTube App

One of the easiest ways to open a YouTube video is to simply direct the user to the actual YouTube app, this has the benefit of providing the user with an interface they (hopefully) are familiar with, along with all of the information related to the video. Let’s have a look at the code:

This functionality hasn’t always been available so it’s necessary to check if the YouTube app is capable of handling an intent. To do this we’re using a utility class called YouTubeIntents, specifically a method called canResolvePlayVideoIntent. If this method returns true then we know we can use YouTubeIntents to create our intent and the YouTube app knows how to handle it. Calling YouTubeIntents.createPlayVideoIntent passing in the developer key and the ID of the video to player will return an intent, use this in combination with startActivity and you’re good to go. It should look something like this:

Eden Agency on YouTube

To take this further, you can also specify some options when creating the intent. Take the second switch case for example:

case 1:
  if (YouTubeIntents.canResolvePlayVideoIntentWithOptions(getActivity())) {
    //Opens in the YouTube app in fullscreen and returns to this app once the video finishes
    startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(context,, true, true));

This is pretty much the same as the previous method except for the differing method names and the two boolean values. The first value specifies whether or not to play the video in fullscreen which forces the user into landscape mode, the second value specifies whether the user should be automatically returned to your application once the video has finished, if it’s false then they have to press the back button to return themselves.

Full screen YouTube videos in Android App

Although it’s one of the easier methods, sending the user to a different app can break the user experience and take a few seconds more to play the video as the YouTube app has to be loaded first.


This method is just as easy as the previous, but doesn’t require the user to leave your app. For most people, this will be the best way of playing videos. Let’s see the code

case 2:
    //Opens in the StandAlonePlayer, defaults to fullscreen

There’s no check this time as we’re not opening a separate application but instead, using the YouTubeStandalonePlayer to open an activity within our application. The method createVideoIntent takes a Context, the developer key and the video ID, and will display a video much like opening in the YouTube app in fullscreen, though it should load a bit quicker as we aren’t also doing any unnecessary loading.

YouTubeStandalonePlayer in Android App

There’s a second createVideoIntent that takes a few extra parameters which helps to customise the player a bit.

case 3:
    //Opens in the StandAlonePlayer but in "Light box" mode
        DEVELOPER_KEY,, 0, true, true));

Additional to the previous three parameters, we have an integer that denotes the millisecond to start the video at, a boolean value that tells the video to autoplay or not, and a second boolean that specifies “Lightbox” mode when true, or fullscreen when false. Here’s a preview of what Lightbox mode looks like.

YouTubeStandalonPlayer mode

If you’re wanting a fullscreen video that doesn’t mean leaving your app then the StandalonePlayer is for you, if you don’t want fullscreen and aren’t that bothered about including any other information alongside your video then the Lightbox mode is probably best suited. The only downside to this method is that you’re stuck with either a fullscreen video, or a video that’s on-top of your existing layout, what if you wanted to include some information about the video that the user can read as they watch.


his is where the YouTubePlayerSupportFragment comes in. I’m using this version and not the YouTubePlayerFragment as my sample application has a minimum SDK version of 7, Fragments were introduced in SDK version 15 so it’s necessary to use the support versions to enable backwards compatibility. Basically, if your app supports an SDK version lower than 15 then use the SupportFragment, if not then use the normal one, other than that there’s no difference between them.

Here’s the code for this video:

You should notice that I’m using a different Fragment to the one I mentioned above, this is because I have created my own Fragment that extends from YouTubeSupportFragment called YouTubeFragment. This allows me to use the existing functionality by encapsulate the initialization and video handling logic within it.

Firstly I create a new instance of the Fragment and pass the video id as an argument. Once the Fragment is created I extract the video ID and store it as a class value, then I call the initialize method passing in the developer key and an initialization listener. Much like the YouTubeThumbnailView, the YouTubeVideoPlayer wants a callback listener that handles onInitializationSuccess and onInitializationFailure.

In this example, a failure will simply Toast an error message, but let’s have a look at what happens when the initialization completes:

    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean restored) {

        if (mVideoId != null) {
            if (restored) {
            } else {

Passed into this method is an instance of YouTubePlayer which will be used to display the video. All we need to do is check that we have a video Id to load, then check if the player is being restored. The restored value will be true if the player is being restored from a previously saved state, it’s usually the case that a restored player should continue playing the same video from where it left off. If the player is not being restored then call loadVideo passing in the videoId, this will load and play the video.

Here’s what the YouTubeFragment looks like:

YouTube Fragment in Android App

The benefit of using a Fragment is that you can include it any layout you want, much like a regular Fragment. The downside is that unless you have a dedicated Activity hosting the Fragment, it’s difficult to controls its size and position. As you can see from the example, the Fragment takes up the whole screen but only a portion of it is used to actually display the video to keep the aspect ratio. What if you wanted the Fragment to only be as big as the video itself, or display some information alongside the video? We’ll address that in the next section.

Hosting the YouTubeFragment

Like any Fragment, the YouTubeFragment can be hosted by an Activity, and by hosted I mean declared in XML.

case 5:
   //Opens in Custom Activity
   final Intent fragIntent = new Intent(getActivity(), YouTubeFragmentActivity.class);

Like any Activity, we start it by creating an intent and calling startActivity. This will open the YouTubeFragmentActivity, named so because it’s hosting our Fragment. If we check the XML layout file for his Activity,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""

    <!-- YouTube Fragment -->
        android:layout_alignParentTop="true" />

    <!-- You could put anything here -->
        android:textSize="18sp" />


You can see that the Fragment that has been declared, has been given the name "com.eden.youtubesample.fragment.YouTubeFragment", which is the package name for our YouTubeFragment class. This means that when the layout is inflated, an instance of YouTubeFragment is also created and placed within our layout.

Due to the framework creating the Fragment for us it called the default empty constructor, this means we need to get hold of it within our Activity in order to invoke the initialize method with the videoId. This is where the setVideoId method comes in. It allows us to call initialize whenever want without creating a new instance of the Fragment, that way we can reuse the same Fragment over and over if we needed to. To see how we get the instance check onCreate in YouTubeFragmentActivity.

Once you load the YouTubeFragmentActivity it should look something like this.

YouTube Fragment in Android App

The upside to hosting the Fragment instead of just adding it to the current layout, is that you can have a video playing in a complex layout when in portrait, then switch to fullscreen when in landscape. Try it out by rotating the app to landscape mode.

One of the benefits of a Fragment is its reusability, it’s easier to change the content of an existing Fragment than it is to create a new Activity each time you want to display similar content. If you wanted a way to display quickly and efficiently display YouTube videos in a list then you would probably want to use and reuse a Fragment. But what if you wanted to display one video somewhere in your app, or displaying videos weren’t an important aspect.


The YouTubePlayerView is a widget you can place in your XML layout or create an instance of in code much like we’ve been doing with the YouTubePlayerFragment. That’s because the YouTubePlayerFragment is using the YouTubePlayerView under the hood, wrapping it in a convenient Fragment. The View can be seen as an alternative to the Fragment which allows for a reduction in setup code and as it’s not a Fragment, you don’t have to deal with an of the nuances that come with Fragment lifecycles.

We can declare the YouTubePlayerView in our layout like so: activity_youtube.xml, as you can tell it’s a lot similar to our previous layout file. We inflate this layout in YouTubeActivity and get an instance of the View in onCreate. It’s important to note that any Activity that wants to make use of a YouTubePlayerView must extend from YouTubBaseActivity. Like any object that comes with this library, we need to initialize it with the developer key and provide a listener. The onSuccessListener is much the same as the YouTubeFragments implementation though this time we’re using some Flags to control some aspects of the video player.

The FullscreenControlFlags allow you to control when the player becomes fullscreen and what happens once it does. Here’s how we’re using the Flags in the sample application:

    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean restored) {

        //Here we can set some flags on the player

        //This flag tells the player to switch to landscape when in fullscreen, it will also return to portrait
        //when leaving fullscreen

        //This flag tells the player to automatically enter fullscreen when in landscape. Since we don't have
        //landscape layout for this activity, this is a good way to allow the user rotate the video player.

        //This flag controls the system UI such as the status and navigation bar, hiding and showing them
        //alongside the player UI

        if (mVideoId != null) {
            if (restored) {
            } else {

The Flag FULLSCREEN_FLAG_CONTROL_ORIENTATION forces the application into landscape mode when the player has gone fullscreen, this is useful in this situation because this Activity has been locked to portrait in the manifest as we don’t have a landscape layout. Without this flag the application would not rotate and the video player would stay the same size and orientation.

The second Flag FULLSCREEN_FLAG_CONTROL_ORIENTATION tells the player to enter fullscreen when we are in landscape and the third Flag FULLSCREEN_FLAG_CONTROL_SYSTEM_UI makes the system UI appear and disappear alongside the video UI whilst it’s fullscreen. 

Fragment with Fullscreen flag turned on

As you can see, visually this is essentially the same as the previous method. The upside to using the YouTubePlayerView is that it’s easier for the system to load a view as opposed to the view inside a Fragment, you can also reuse the view inside your Activity if you have multiple videos you can play. The downside is that the Activity hosting the view must extend from YouTubeBaseActivity, this can be problematic if your Activity needs to extend from another type of Activity, such as AppCompatActivity or ListActivity.

Custom Lightbox

As I previously mentioned, I quite like the Lightbox mode for it’s cinematic-esque appearance. If you checked out Riddio then it’s likely you already noticed that I’ve created a custom version of this that’s a bit more versatile. Since I’m nice, I’ve included the code necessary to achieve this view in the sample application, you can steal the code from here: CustomLightboxActivity and activity_youtube_lightbox.

I’m using the YouTubePlayerView along with the YouTubeBaseActivity to display a video in the center of the screen, I’m also applying a semi-transparent black color to the root layout that gives darkens the rest of the viewport, this gives more focus to the VideoPlayer.

In the CustomLightboxActivity it’s most of the same code used in previous examples with a bit of extra magic to handle rotation, saving instance state and logic handling. I’ll pick out the interesting parts here. First up it’s the root layout:

final RelativeLayout relativeLayout = (RelativeLayout) findViewById(;
        relativeLayout.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

We set a click listener on the RelativeLayout at the root of our layout so that the user can click outside the video to dismiss the video, to make things easier we can simply hook into the same logic that occurs when the back button is pressed as it’s doing the same thing.

I’m also using onSaveInstanceState to store the position of the current video so that it can be restored when resuming this Activity. This functionality is done through this code:

protected void onCreate(Bundle bundle) {

    if (bundle != null) {
        millis = bundle.getInt(KEY_VIDEO_TIME);
protected void onSaveInstanceState(Bundle outState) {

    if (mPlayer != null) {
          outState.putInt(KEY_VIDEO_TIME, mPlayer.getCurrentTimeMillis());

One important thing to note is that this Activity has been set to not recreate when rotated by specifying so in the manifest. This means that although the YouTubePlayerView will resize itself to match_parent for the current orientation, the player won’t rebuffer as it is not being recreated. This is a very nice feature to implement if you expect the user will be switching orientations whilst viewing videos, this is also how the YouTube app itself functions.

YouTube app on Android

Custom Player Controls

The last example in this tutorial will focus on the different player styles and how you can control the YouTubePlayer with your own widgets. As such I’m simply going to follow the previous method of hosting a View within a YouTubeActivity. Check out the activity_youtube_controls layout and CustomYouTubeControlsActivity.

Here I’m using a RadioGroup to allow the user to between PlayerStyles on the fly, of which there are three:

  • DEFAULT: The Default player style used on all of the previous examples.
  • MINIMAL: Similar to Default but with a smaller time bar and only Play/Pause buttons.
  • CHROMELESS: No UI whatsoever, useful if you want to prevent user interaction or implement your own UI controls.

 To set the PlayerStyle I’m using a switch case in the RadioGroups onCheckedChanged listener:

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked && mPlayer != null) {
            switch (buttonView.getId()) {

 And to control Playback I’m simply calling play and pause on the YouTubePlayer like so:

    public void onClick(View v) {
        if (v == playButton) {
        } else if (v == pauseButton) {

In theory, you could create your own custom UI to completely replace the YouTubePlayer UI, the only pitfall is that you can’t overlay the VideoPlayer with anything. This is further discussed in the Pitfalls section below. 


Video ID Extraction

One of the more difficult thing to do is extracting Video ID’s on the fly. Let’s say you retreive a list of YouTube video URLs from a web service, you’re going to need to extract the video ID out of each URL to be able to play each one correctly.  It’s quite easy to write a regular expression to achieve this but you quickly encounter problems with YouTube’s varying URL formats.

For an idea of the number of ways a video url can appear:

It would be handy if there was a Utility class in the library that handled this for you. If you feel the same then head over toGoogle Issues and star my enhancement request.

Video Overlay

I touched upon this in the Custom Player Controls section. If anything, wait let emphasize that a bit more .. ANYTHINGoverlays the video player then it won’t play. Simple as that. This is likely to prevent you from overlaying videos with your own advertisements or playing videos in the background, where the user can’t pause it. This does have the drawback of also preventing you from creating your own interface however, then again it could be one of the intended consequences.

Minimum Size

Similar to the previous point, if the player is not above a minimum size then it won’t play then either. To quote the documentation: “Note that while videos are playing, this View has a minimum size of 200x110 dp. If you make the view any smaller, videos will automatically stop playing. Also, it is not permitted to overlay the view with other views while a video is playing.”

Various Addressable Bugs

There are a number of ways you can intentionally crash your app using this API, one of which I accidently discovered. If you try to quit an Activity whilst in fullscreen mode the app will crash if you are on Android 5.0 or greater, but works perfectly on 4.4.4 and below. It’s also possible to crash if the user requests closed captioning when it’s not available.

 One of the main ways that crashes will occur is if you don’t handle the state of the YouTubePlayer correctly, it can release itself without warning and attempting to invoke any state changing operation on it will cause a DeadObjectException. Currently there is no way to check whether or not the player has been released before invoking an operation. If you think there should be a way then star my other issue.

Unsolvable Bugs

While we’re on the topic of bugs, it’s best to mention that you will encounter crashes and errors that you cannot diagnose and cannot fix. If you’re lucky enough to catch it while debugging, or have a crash reporting tool you are likely to get crash reports with compiled stack traces, giving you little to no indication of why your app crashed or the sequence of events that caused it to occur. You can minimize this by carefully managing the VideoPlayer state.

Video Restrictions

One of the more frustrating issues is videos being age restricted, presenting you with the a warning view.

It’s been suggested to Google to use the age of the person that’s currently logged into the YouTube app,  which shouldn’t be too difficult to do as the API already heavily relies on it. You can’t test whether or not a video is age restricted so you can’t filter them out, you also can’t get around this other than simply directing the user to the YouTube app via the first method in this tutorial. Once again, please help get the ball rolling on a fix for this problem by starring this issue.

Topics Not Covered

This example has been more about demonstrating the various ways of playing videos using the API, but it’s also capable of quite a bit more than that. Here are some of its other features that aren’t discussed in this post.


That’s right, it’s possible to upload videos to YouTube in your app. This relies on the user being logged into the main YouTube application but it allows you to record a video or pick one from the gallery, then upload it without leaving the app. 


You can also create intents to send the user to the profile or any YouTube user. I haven’t had a chance to play around with this so there might be more to it than it sounds. 


Admittidly this should have been part of this example. It’s possible to play playlists by passing a playlist ID into a playPlaylist method.

If I get enough interest or annoying emails I may be tempted to do a follow-up post and update the sample app with some further examples.

That concludes this (lengthy) tutorial, I’ve tried to cover everything the library is capable of in regards to video playback so it might be a little shallow in content in some areas. If you want any more information or have some feedback then feel free to email me.

Ps. The word YouTube appears 82 times in this post, including this one.

comments powered by Disqus

We're Hiring - C#.NET Web Developer

By Sophie Hardbattle

We're looking for a new web developer to join the Eden Agency team.

Read more

We're Hiring - Unity Game Developer

By Sophie Hardbattle

Eden Agency are looking for another member of the development team.

Read more

Yorkshire Virtual Reality Meetup

By Adam Taglietti

We're hosting the Yorkshire VR event. Meet up with other enthusiasts and try the latest technology including the Microsoft HoloLens and the Oculus Rift with Touch controllers.

Read more

Top AR/VR Developers

By Adam Taglietti

Clutch has named us one of the top AR/VR developers.

Read more

Introducing PowerUp

By Sophie Hardbattle

Introducing PowerUp -- our new virtual reality solution for events.

Read more