In the previous recipe, we retrieved search results from YouTube and displayed them in a list and detail fragment. The entries found represent videos, so it would be nice if we were able to play them as well in our app. Let's find a way to do this.
Since we do know the video ID, it is not that difficult to compose a URL for it and load them in a web view; however, Google provides an easier solution for this and offers the YouTube Android Player API for this purpose. It has a couple of limitations but is interesting enough to explore.
To go through this recipe, you need to complete the previous recipe as this one picks up where we left off. While I recommend you to test the app on a physical phone and tablet, you can, of course, use Genymotion as well.
If you are using virtual devices, then Google apps (and the YouTube app on which the API and the player depend) will be missing, and the app will fail for that reason. You need to download and install them on the virtual device first.
Let's see how we can extend the app using the following steps, so it can play back a video for us:
YouTubeAndroidPlayerApi.jar
file in the libs
folder and copy it.libs
folder within the app
module and paste the YouTubeAndroidPlayerApi.jar
file.build.gradle
file may have already been prepared to include any files in the lib
file; however if it is not, add the dependency:compile fileTree(dir: 'libs', include: ['YouTubeAndroidPlayerApi.jar'])
MainActivity
class, add a static tag for the player fragment that we are going to create. Also add the private member for YouTubePlayerFragment
and a public member to store the YouTube player if the initialization succeeds:public static String TAG_PLAYER_FRAGMENT = "PLAYER"; private YouTubePlayerFragment mPlayerFragment; public YouTubePlayer mYouTubePlayer = null;
activity_main.xml
in the layout-large
directory, change the height of the detail fragment to 300dp
, and add YouTubePlayerFragment
to it. The preview might complain as it is not aware of how things should be rendered, but that is not really an issue as long as the package is being recognized, which will be the case if you have completed steps 5 and 6 successfully:<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/main_container"> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="300dp"android:layout_height="match_parent"android:background="@android:color/holo_orange_light"android:id="@+id/main_container_for_list_fragment"></FrameLayout> <FrameLayout android:id="@+id/main_container_for_detail_fragment"android:background="@android:color/holo_blue_light"android:layout_marginLeft="300dp"android:layout_width="match_parent"android:layout_height="300dp"></FrameLayout> <fragment android:name="com.google.android.youtube.player.YouTubePlayerFragment" android:id="@+id/main_youtube_player_fragment"android:layout_marginTop="300dp"android:layout_marginLeft="300dp"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="3"/> </FrameLayout>
onCreateView
, just before ft.commit
, find the container for the player fragment and initialize YouTuberPlayer
:mPlayerFragment = (YouTubePlayerFragment) getFragmentManager().findFragmentById( R.id.main_youtube_player_fragment);if (mPlayerFragment != null) { ft.add(mPlayerFragment, TAG_PLAYER_FRAGMENT); mPlayerFragment.initialize("Your API key", new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess( YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean isRestored) { mYouTubePlayer = youTubePlayer;} @Override public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) { Log.d(this.getClass().toString(), youTubeInitializationResult.toString()); }); }
DetailFragment
, add an on click handler for the Play button in the onCreateView
method, just before returning the view object:view.findViewById(R.id.detail_button_play).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { playVideo();} });
playVideo
method in DetailFragment
. If the player fragment is there (on devices with large screens) and has been initialized, it will play the video; if it is not there (on devices with smaller screens), we will create a player fragment, initialize it, and add it to the stack:private void playVideo(){ if (getActivity() != null && ((MainActivity)getActivity()).mYouTubePlayer != null){ ((MainActivity)getActivity() ).mYouTubePlayer.cueVideo(mVideo.getId()); } else { FragmentTransaction ft = getFragmentManager().beginTransaction(); YouTubePlayerFragment playerFragment = new YouTubePlayerFragment(); ft.add(R.id.main_container_for_list_fragment, playerFragment, MainActivity.TAG_DETAILS_FRAGMENT); ft.addToBackStack(MainActivity.TAG_PLAYER_FRAGMENT); ft.commit(); playerFragment.initialize("Your API key", new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean isRestored) { if (!isRestored) { youTubePlayer.cueVideo(mVideo.getId()); } } @Override public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) { Log.d(this.getClass().toString(), youTubeInitializationResult.toString()); } }); } }
And with that, we have added a simple but fully functional implementation to play the selected video.