Text
Bootcamp Week #7
1. Youtube API
Text
Sabtu, 30 Maret 2019
Taruna
Text
Ilham
Netco Mall BTW Bogor
Buat API Key
Buat Project Android dengan nama : VideoTube
config.java
package com.example.videotube;
public final class Config {
private Config(){
}
public static final String YOUTUBE_API_KEY = "YOUR API KEY";
}
Download Player
Copy paste file jar ke app > libs
Tambahkan di Gradle
implementation files('libs/YouTubeAndroidPlayerApi.jar')
<uses-permission android:name="android.permission.INTERNET"/>
dan Manifest
MainActivity.java
package com.example.videotube;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;
public class MainActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
private static final int RECOVERY_REQUEST = 1;
private YouTubePlayerView youTubeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
youTubeView.initialize(Config.YOUTUBE_API_KEY, this);
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
if (!wasRestored) {
player.cueVideo("fhWaJi1Hsfo"); // Plays https://www.youtube.com/watch?v=fhWaJi1Hsfo
}
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(this, RECOVERY_REQUEST).show();
} else {
String error = String.format(getString(R.string.player_error), errorReason.toString());
Toast.makeText(this, error, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_REQUEST) {
// Retry initialization if user performed a recovery action
getYouTubePlayerProvider().initialize(Config.YOUTUBE_API_KEY, this);
}
}
protected YouTubePlayer.Provider getYouTubePlayerProvider() {
return youTubeView;
}
}
string.xml
<resources>
<string name="app_name">VideoTube</string>
<string name="player_error">Error initializing YouTube player: %s</string>
<string name="seek_to">Jump To</string>
<string name="seek_to_hint">Seconds</string>
</resources>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.youtube.player.YouTubePlayerView
android:id="@+id/youtube_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
Main_Activity.java
package com.example.videotube;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;
public class MainActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
private static final int RECOVERY_REQUEST = 1;
private YouTubePlayerView youTubeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
youTubeView.initialize(Config.YOUTUBE_API_KEY, this);
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
if (!wasRestored) {
player.cueVideo("fhWaJi1Hsfo"); // Plays https://www.youtube.com/watch?v=fhWaJi1Hsfo
}
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(this, RECOVERY_REQUEST).show();
} else {
String error = String.format(getString(R.string.player_error), errorReason.toString());
Toast.makeText(this, error, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_REQUEST) {
// Retry initialization if user performed a recovery action
getYouTubePlayerProvider().initialize(Config.YOUTUBE_API_KEY, this);
}
}
protected YouTubePlayer.Provider getYouTubePlayerProvider() {
return youTubeView;
}
}
Tes Player
Tambahkan di MainActivity.java
private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
private final class MyPlaybackEventListener implements YouTubePlayer.PlaybackEventListener {
@Override
public void onPlaying() {
// Called when playback starts, either due to user action or call to play().
showMessage("Playing");
}
@Override
public void onPaused() {
// Called when playback is paused, either due to user action or call to pause().
showMessage("Paused");
}
@Override
public void onStopped() {
// Called when playback stops for a reason other than being paused.
showMessage("Stopped");
}
@Override
public void onBuffering(boolean b) {
// Called when buffering starts or ends.
}
@Override
public void onSeekTo(int i) {
// Called when a jump in playback position occurs, either
// due to user scrubbing or call to seekRelativeMillis() or seekToMillis()
}
}
private final class MyPlayerStateChangeListener implements YouTubePlayer.PlayerStateChangeListener {
@Override
public void onLoading() {
// Called when the player is loading a video
// At this point, it's not ready to accept commands affecting playback such as play() or pause()
}
@Override
public void onLoaded(String s) {
// Called when a video is done loading.
// Playback methods such as play(), pause() or seekToMillis(int) may be called after this callback.
}
@Override
public void onAdStarted() {
// Called when playback of an advertisement starts.
}
@Override
public void onVideoStarted() {
// Called when playback of the video starts.
}
@Override
public void onVideoEnded() {
// Called when the video reaches its end.
}
@Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
// Called when an error occurs.
}
}
private MyPlayerStateChangeListener playerStateChangeListener;
private MyPlaybackEventListener playbackEventListener;
playerStateChangeListener = new MyPlayerStateChangeListener();
playbackEventListener = new MyPlaybackEventListener();
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
if (!wasRestored) {
player.cueVideo("BLM2Fua8jZI"); // Plays https://www.youtube.com/watch?v=BLM2Fua8jZI
}
}
Menjadi
package com.example.videotube;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;
public class MainActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
private static final int RECOVERY_REQUEST = 1;
private YouTubePlayerView youTubeView;
private MyPlayerStateChangeListener playerStateChangeListener;
private MyPlaybackEventListener playbackEventListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
youTubeView.initialize(Config.YOUTUBE_API_KEY, this);
playerStateChangeListener = new MyPlayerStateChangeListener();
playbackEventListener = new MyPlaybackEventListener();
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
if (!wasRestored) {
player.cueVideo("fhWaJi1Hsfo"); // Plays https://www.youtube.com/watch?v=fhWaJi1Hsfo
}
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(this, RECOVERY_REQUEST).show();
} else {
String error = String.format(getString(R.string.player_error), errorReason.toString());
Toast.makeText(this, error, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_REQUEST) {
// Retry initialization if user performed a recovery action
getYouTubePlayerProvider().initialize(Config.YOUTUBE_API_KEY, this);
}
}
protected YouTubePlayer.Provider getYouTubePlayerProvider() {
return youTubeView;
}
private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
private final class MyPlaybackEventListener implements YouTubePlayer.PlaybackEventListener {
@Override
public void onPlaying() {
// Called when playback starts, either due to user action or call to play().
showMessage("Playing");
}
@Override
public void onPaused() {
// Called when playback is paused, either due to user action or call to pause().
showMessage("Paused");
}
@Override
public void onStopped() {
// Called when playback stops for a reason other than being paused.
showMessage("Stopped");
}
@Override
public void onBuffering(boolean b) {
// Called when buffering starts or ends.
}
@Override
public void onSeekTo(int i) {
// Called when a jump in playback position occurs, either
// due to user scrubbing or call to seekRelativeMillis() or seekToMillis()
}
}
private final class MyPlayerStateChangeListener implements YouTubePlayer.PlayerStateChangeListener {
@Override
public void onLoading() {
// Called when the player is loading a video
// At this point, it's not ready to accept commands affecting playback such as play() or pause()
}
@Override
public void onLoaded(String s) {
// Called when a video is done loading.
// Playback methods such as play(), pause() or seekToMillis(int) may be called after this callback.
}
@Override
public void onAdStarted() {
// Called when playback of an advertisement starts.
}
@Override
public void onVideoStarted() {
// Called when playback of the video starts.
}
@Override
public void onVideoEnded() {
// Called when the video reaches its end.
}
@Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
// Called when an error occurs.
}
}
}
running aplikasi
Custom Player Controls
edit activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.google.android.youtube.player.YouTubePlayerView
android:id="@+id/youtube_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/seek_to_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:hint="@string/seek_to_hint"/>
<Button
android:id="@+id/seek_to_button"
android:text="@string/seek_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
MainActivity.java
private YouTubePlayer player;
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
this.player = player;
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
if (!wasRestored) {
player.cueVideo("BLM2Fua8jZI"); // Plays https://www.youtube.com/watch?v=BLM2Fua8jZI
}
}
final EditText seekToText = (EditText) findViewById(R.id.seek_to_text);
Button seekToButton = (Button) findViewById(R.id.seek_to_button);
seekToButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int skipToSecs = Integer.valueOf(seekToText.getText().toString());
player.seekToMillis(skipToSecs * 1000);
}
});
Download
https://drive.google.com/file/d/1W9TNbTcZ1k36_CK4vQb5Fi9PPNaqimV6/view?usp=sharinghttps://drive.google.com/file/d/1W9TNbTcZ1k36_CK4vQb5Fi9PPNaqimV6/view?usp=sharing
youtube playlist
Library di gradle
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.google.apis:google-api-services-youtube:v3-rev182-1.22.0'
implementation 'com.google.http-client:google-http-client-android:1.20.0'
implementation 'com.google.api-client:google-api-client-android:1.20.0'
implementation 'com.google.api-client:google-api-client-gson:1.20.0'
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
permission manifest
New >
Activity >
Empty Activity
Nama Activity : YouTubeActivity.java
Nama Layout : youtube_activity.xml
Ubah Launcher di Manifest
<activity android:name=".YouTubeActivity"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Menjadi
<activity android:name=".YouTubeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
</activity>
Cari Icon di Google
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/logo"
Copy paste di mipmap
ubah icon di manifest
APiKey.java
public class ApiKey {
public static final String YOUTUBE_API_KEY = "AIzaSyAuLBcD1bC7QmN5pQVFf9lgPpRIqENCQRs";
}
youtube_recycler_view_fragment.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Spinner
android:id="@+id/youtube_playlist_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/youtube_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:layout_below="@id/youtube_playlist_spinner"/>
</RelativeLayout>
youtube_video_card.xml
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
card_view:cardCornerRadius="4dp"
card_view:cardPreventCornerOverlap="true"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/video_thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
tools:src="@drawable/ic_thumb_up" />
<TextView
android:id="@+id/video_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/video_thumbnail"
android:layout_gravity="center_vertical"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="8dp"
android:fontFamily="sans-serif-light"
android:textColor="@android:color/primary_text_light"
android:textSize="18sp"
tools:text="Video Title text that is long enough to make the line wrap around to the next line." />
<RelativeLayout
android:id="@+id/video_stats_line"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/video_title"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp">
<TextView
android:id="@+id/video_view_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:fontFamily="sans-serif-light"
android:textColor="@android:color/primary_text_light"
android:textSize="20sp"
tools:text="119,313" />
<ImageView
android:id="@+id/video_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/video_view_count"
android:src="@drawable/ic_share" />
<TextView
android:id="@+id/video_share_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/video_share"
android:layout_below="@id/video_view_count"
android:layout_marginLeft="8dp"
android:layout_toRightOf="@id/video_share"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:text="Share"
android:textColor="@android:color/primary_text_light"
android:textSize="16sp" />
<ImageView
android:id="@+id/video_thumb_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/video_share"
android:layout_below="@id/video_view_count"
android:layout_toLeftOf="@+id/video_like_count"
android:gravity="center_vertical"
android:src="@drawable/ic_thumb_up" />
<TextView
android:id="@+id/video_like_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/video_share"
android:layout_below="@id/video_view_count"
android:layout_marginLeft="12dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/video_thumb_down"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:textColor="@android:color/primary_text_light"
android:textSize="14sp"
tools:text="99" />
<ImageView
android:id="@+id/video_thumb_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/video_share"
android:layout_below="@id/video_view_count"
android:layout_toLeftOf="@+id/video_dislike_count"
android:gravity="center_vertical"
android:src="@drawable/ic_thumb_down" />
<TextView
android:id="@+id/video_dislike_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/video_share"
android:layout_alignParentRight="true"
android:layout_below="@id/video_view_count"
android:layout_marginLeft="12dp"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:textColor="@android:color/primary_text_light"
android:textSize="14sp"
tools:text="99" />
</RelativeLayout>
<LinearLayout
android:id="@+id/video_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/video_title"
android:layout_alignParentRight="true"
android:layout_marginBottom="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:background="@drawable/semi_transparent_box_with_border"
android:orientation="horizontal">
<TextView
android:id="@+id/video_dutation_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:paddingBottom="4dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="4dp"
android:text="--:--"
android:textColor="@android:color/primary_text_dark" />
</LinearLayout>
<TextView
android:id="@+id/video_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/video_stats_line"
android:layout_marginBottom="8dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="2dp"
android:fontFamily="sans-serif-light"
android:textColor="@android:color/secondary_text_light"
tools:text="This is a sample description of the video item that is long enough to wrap around to the next line." />
</RelativeLayout>
</android.support.v7.widget.CardView>
drawable/semi_transparent_box_with_border.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/semi_transparent_black" />
<stroke
android:width="1dp"
android:color="@android:color/background_light"/>
</shape>
color.xml
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="semi_transparent_black">#90000000</color>
</resources>
String.xml
<resources>
<string name="player_error">Error initializing YouTube player: %s</string>
<string name="seek_to">Jump To</string>
<string name="seek_to_hint">Seconds</string>
<string name="app_name">Nusa Animation</string>
<string name="action_recycler_view">Daftar</string>
</resources>
Styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:spinnerStyle">@style/Widget.AppCompat.Spinner.Underlined</item>
<item name="android:spinnerDropDownItemStyle">@style/Widget.AppCompat.TextView.SpinnerItem</item>
</style>
</resources>
menu/you_tube.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.akoscz.youtube.YouTubeActivity" >
<item android:id="@+id/action_recyclerview"
android:title="@string/action_recycler_view"
android:orderInCategory="101"
app:showAsAction="never" />
</menu>
model/PlaylistVideos.java
package com.example.videotube.model;
import com.google.api.services.youtube.model.Video;
import java.util.ArrayList;
import java.util.List;
public class PlaylistVideos extends ArrayList<Video>{
public final String playlistId;
private String mNextPageToken;
public PlaylistVideos(String id) {
playlistId = id;
}
public void setNextPageToken(String nextPageToken) {
mNextPageToken = nextPageToken;
}
public String getNextPageToken() {
return mNextPageToken;
}
}
GetPlaylistAsyncTask.java
package com.example.videotube;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.PlaylistItem;
import com.google.api.services.youtube.model.PlaylistItemListResponse;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoContentDetails;
import com.google.api.services.youtube.model.VideoListResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public abstract class GetPlaylistAsyncTask extends AsyncTask<String, Void, Pair<String, List<Video>>> {
private static final String TAG = "GetPlaylistAsyncTask";
private static final Long YOUTUBE_PLAYLIST_MAX_RESULTS = 20L;
//see: https://developers.google.com/youtube/v3/docs/playlistItems/list
private static final String YOUTUBE_PLAYLIST_PART = "snippet";
private static final String YOUTUBE_PLAYLIST_FIELDS = "pageInfo,nextPageToken,items(id,snippet(resourceId/videoId))";
//see: https://developers.google.com/youtube/v3/docs/videos/list
private static final String YOUTUBE_VIDEOS_PART = "snippet,contentDetails,statistics"; // video resource properties that the response will include.
private static final String YOUTUBE_VIDEOS_FIELDS = "items(id,snippet(title,description,thumbnails/high),contentDetails/duration,statistics)"; // selector specifying which fields to include in a partial response.
private YouTube mYouTubeDataApi;
public GetPlaylistAsyncTask(YouTube api) {
mYouTubeDataApi = api;
}
@Override
protected Pair<String, List<Video>> doInBackground(String... params) {
final String playlistId = params[0];
final String nextPageToken;
if (params.length == 2) {
nextPageToken = params[1];
} else {
nextPageToken = null;
}
PlaylistItemListResponse playlistItemListResponse;
try {
playlistItemListResponse = mYouTubeDataApi.playlistItems()
.list(YOUTUBE_PLAYLIST_PART)
.setPlaylistId(playlistId)
.setPageToken(nextPageToken)
.setFields(YOUTUBE_PLAYLIST_FIELDS)
.setMaxResults(YOUTUBE_PLAYLIST_MAX_RESULTS)
.setKey(ApiKey.YOUTUBE_API_KEY)
.execute();
} catch (IOException e) {
e.printStackTrace();
return null;
}
if (playlistItemListResponse == null) {
Log.e(TAG, "Failed to get playlist");
return null;
}
List<String> videoIds = new ArrayList();
// pull out the video id's from the playlist page
for (PlaylistItem item : playlistItemListResponse.getItems()) {
videoIds.add(item.getSnippet().getResourceId().getVideoId());
}
// get details of the videos on this playlist page
VideoListResponse videoListResponse = null;
try {
videoListResponse = mYouTubeDataApi.videos()
.list(YOUTUBE_VIDEOS_PART)
.setFields(YOUTUBE_VIDEOS_FIELDS)
.setKey(ApiKey.YOUTUBE_API_KEY)
.setId(TextUtils.join(",", videoIds)).execute();
} catch (IOException e) {
e.printStackTrace();
}
return new Pair(playlistItemListResponse.getNextPageToken(), videoListResponse.getItems());
}
}
GetPlaylistTitlesAsyncTask.Java
package com.example.videotube;
import android.os.AsyncTask;
import android.text.TextUtils;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.PlaylistListResponse;
import java.io.IOException;
/**
* This AsyncTask will get the titles of all the playlists that are passed in as a parameter.
*/
public class GetPlaylistTitlesAsyncTask extends AsyncTask<String[], Void, PlaylistListResponse> {
//see: https://developers.google.com/youtube/v3/docs/playlists/list
private static final String YOUTUBE_PLAYLIST_PART = "snippet";
private static final String YOUTUBE_PLAYLIST_FIELDS = "items(id,snippet(title))";
private YouTube mYouTubeDataApi;
public GetPlaylistTitlesAsyncTask(YouTube api) {
mYouTubeDataApi = api;
}
@Override
protected PlaylistListResponse doInBackground(String[]... params) {
final String[] playlistIds = params[0];
PlaylistListResponse playlistListResponse;
try {
playlistListResponse = mYouTubeDataApi.playlists()
.list(YOUTUBE_PLAYLIST_PART)
.setId(TextUtils.join(",", playlistIds))
.setFields(YOUTUBE_PLAYLIST_FIELDS)
.setKey(ApiKey.YOUTUBE_API_KEY)
.execute();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return playlistListResponse;
}
}
PlaylistCardAdapter.java
package com.example.videotube;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.videotube.model.PlaylistVideos;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoContentDetails;
import com.google.api.services.youtube.model.VideoSnippet;
import com.google.api.services.youtube.model.VideoStatistics;
import com.squareup.picasso.Picasso;
import java.text.DecimalFormat;
public class PlaylistCardAdapter extends RecyclerView.Adapter<PlaylistCardAdapter.ViewHolder> {
private static final DecimalFormat sFormatter = new DecimalFormat("#,###,###");
private final PlaylistVideos mPlaylistVideos;
private final YouTubeRecyclerViewFragment.LastItemReachedListener mListener;
public static class ViewHolder extends RecyclerView.ViewHolder {
public final Context mContext;
public final TextView mTitleText;
public final TextView mDescriptionText;
public final ImageView mThumbnailImage;
public final ImageView mShareIcon;
public final TextView mShareText;
public final TextView mDurationText;
public final TextView mViewCountText;
public final TextView mLikeCountText;
public final TextView mDislikeCountText;
public ViewHolder(View v) {
super(v);
mContext = v.getContext();
mTitleText = (TextView) v.findViewById(R.id.video_title);
mDescriptionText = (TextView) v.findViewById(R.id.video_description);
mThumbnailImage = (ImageView) v.findViewById(R.id.video_thumbnail);
mShareIcon = (ImageView) v.findViewById(R.id.video_share);
mShareText = (TextView) v.findViewById(R.id.video_share_text);
mDurationText = (TextView) v.findViewById(R.id.video_dutation_text);
mViewCountText= (TextView) v.findViewById(R.id.video_view_count);
mLikeCountText = (TextView) v.findViewById(R.id.video_like_count);
mDislikeCountText = (TextView) v.findViewById(R.id.video_dislike_count);
}
}
public PlaylistCardAdapter(PlaylistVideos playlistVideos, YouTubeRecyclerViewFragment.LastItemReachedListener lastItemReachedListener) {
mPlaylistVideos = playlistVideos;
mListener = lastItemReachedListener;
}
// Create new views (invoked by the layout manager)
@Override
public PlaylistCardAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// inflate a card layout
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.youtube_video_card, parent, false);
// populate the viewholder
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
if (mPlaylistVideos.size() == 0) {
return;
}
final Video video = mPlaylistVideos.get(position);
final VideoSnippet videoSnippet = video.getSnippet();
final VideoContentDetails videoContentDetails = video.getContentDetails();
final VideoStatistics videoStatistics = video.getStatistics();
holder.mTitleText.setText(videoSnippet.getTitle());
holder.mDescriptionText.setText(videoSnippet.getDescription());
// load the video thumbnail image
Picasso.with(holder.mContext)
.load(videoSnippet.getThumbnails().getHigh().getUrl())
.placeholder(R.drawable.video_placeholder)
.into(holder.mThumbnailImage);
// set the click listener to play the video
holder.mThumbnailImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/watch?v=" + video.getId())));
}
});
// create and set the click listener for both the share icon and share text
View.OnClickListener shareClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Watch \"" + videoSnippet.getTitle() + "\" on YouTube");
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://www.youtube.com/watch?v=" + video.getId());
sendIntent.setType("text/plain");
holder.mContext.startActivity(sendIntent);
}
};
holder.mShareIcon.setOnClickListener(shareClickListener);
holder.mShareText.setOnClickListener(shareClickListener);
// set the video duration text
holder.mDurationText.setText(parseDuration(videoContentDetails.getDuration()));
// set the video statistics
holder.mViewCountText.setText(sFormatter.format(videoStatistics.getViewCount()));
holder.mLikeCountText.setText(sFormatter.format(videoStatistics.getLikeCount()));
holder.mDislikeCountText.setText(sFormatter.format(videoStatistics.getDislikeCount()));
if (mListener != null) {
// get the next playlist page if we're at the end of the current page and we have another page to get
final String nextPageToken = mPlaylistVideos.getNextPageToken();
if (!isEmpty(nextPageToken) && position == mPlaylistVideos.size() - 1) {
holder.itemView.post(new Runnable() {
@Override
public void run() {
mListener.onLastItem(position, nextPageToken);
}
});
}
}
}
@Override
public int getItemCount() {
return mPlaylistVideos.size();
}
private boolean isEmpty(String s) {
if (s == null || s.length() == 0) {
return true;
}
return false;
}
private String parseDuration(String in) {
boolean hasSeconds = in.indexOf('S') > 0;
boolean hasMinutes = in.indexOf('M') > 0;
String s;
if (hasSeconds) {
s = in.substring(2, in.length() - 1);
} else {
s = in.substring(2, in.length());
}
String minutes = "0";
String seconds = "00";
if (hasMinutes && hasSeconds) {
String[] split = s.split("M");
minutes = split[0];
seconds = split[1];
} else if (hasMinutes) {
minutes = s.substring(0, s.indexOf('M'));
} else if (hasSeconds) {
seconds = s;
}
// pad seconds with a 0 if less than 2 digits
if (seconds.length() == 1) {
seconds = "0" + seconds;
}
return minutes + ":" + seconds;
}
}
YouTubeRecyclerViewFragment.java
package com.example.videotube;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import com.example.videotube.model.PlaylistVideos;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.PlaylistListResponse;
import com.google.api.services.youtube.model.Video;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class YouTubeRecyclerViewFragment extends Fragment {
// the fragment initialization parameter
private static final String ARG_YOUTUBE_PLAYLIST_IDS = "YOUTUBE_PLAYLIST_IDS";
private static final int SPINNER_ITEM_LAYOUT_ID = android.R.layout.simple_spinner_item;
private static final int SPINNER_ITEM_DROPDOWN_LAYOUT_ID = android.R.layout.simple_spinner_dropdown_item;
private String[] mPlaylistIds;
private ArrayList<String> mPlaylistTitles;
private RecyclerView mRecyclerView;
private PlaylistVideos mPlaylistVideos;
private RecyclerView.LayoutManager mLayoutManager;
private Spinner mPlaylistSpinner;
private PlaylistCardAdapter mPlaylistCardAdapter;
private YouTube mYouTubeDataApi;
private ProgressDialog mProgressDialog;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param youTubeDataApi
* @param playlistIds A String array of YouTube Playlist IDs
* @return A new instance of fragment YouTubeRecyclerViewFragment.
*/
public static YouTubeRecyclerViewFragment newInstance(YouTube youTubeDataApi, String[] playlistIds) {
YouTubeRecyclerViewFragment fragment = new YouTubeRecyclerViewFragment();
Bundle args = new Bundle();
args.putStringArray(ARG_YOUTUBE_PLAYLIST_IDS, playlistIds);
fragment.setArguments(args);
fragment.setYouTubeDataApi(youTubeDataApi);
return fragment;
}
public YouTubeRecyclerViewFragment() {
// Required empty public constructor
}
public void setYouTubeDataApi(YouTube api) {
mYouTubeDataApi = api;
}
@SuppressLint("StaticFieldLeak")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
if (getArguments() != null) {
mPlaylistIds = getArguments().getStringArray(ARG_YOUTUBE_PLAYLIST_IDS);
}
// start fetching the playlist titles
new GetPlaylistTitlesAsyncTask(mYouTubeDataApi) {
@Override
protected void onPreExecute() {
super.onPreExecute();
// mProgressDialog.show();
}
@Override
protected void onPostExecute(PlaylistListResponse playlistListResponse) {
// if we didn't receive a response for the playlist titles, then there's nothing to update
if (playlistListResponse == null)
return;
mPlaylistTitles = new ArrayList();
for (com.google.api.services.youtube.model.Playlist playlist : playlistListResponse.getItems()) {
mPlaylistTitles.add(playlist.getSnippet().getTitle());
}
// update the spinner adapter with the titles of the playlists
ArrayAdapter<List<String>> spinnerAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, mPlaylistTitles);
spinnerAdapter.setDropDownViewResource(SPINNER_ITEM_DROPDOWN_LAYOUT_ID);
mPlaylistSpinner.setAdapter(spinnerAdapter);
mProgressDialog.hide();
}
}.execute(mPlaylistIds);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// set the Picasso debug indicator only for debug builds
Picasso.with(getActivity()).setIndicatorsEnabled(BuildConfig.DEBUG);
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.youtube_recycler_view_fragment, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.youtube_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
Resources resources = getResources();
// if (resources.getBoolean(R.bool.isTablet)) {
// // use a staggered grid layout if we're on a large screen device
// mLayoutManager = new StaggeredGridLayoutManager(resources.getInteger(R.integer.columns), StaggeredGridLayoutManager.VERTICAL);
// } else {
// use a linear layout on phone devices
mLayoutManager = new LinearLayoutManager(getActivity());
// }
mProgressDialog = new ProgressDialog(getContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mPlaylistSpinner = (Spinner)rootView.findViewById(R.id.youtube_playlist_spinner);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// if we have a playlist in our retained fragment, use it to populate the UI
if (mPlaylistVideos != null) {
// reload the UI with the existing playlist. No need to fetch it again
reloadUi(mPlaylistVideos, false);
} else {
// otherwise create an empty playlist using the first item in the playlist id's array
mPlaylistVideos = new PlaylistVideos(mPlaylistIds[0]);
// and reload the UI with the selected playlist and kick off fetching the playlist content
reloadUi(mPlaylistVideos, true);
}
ArrayAdapter<List<String>> spinnerAdapter;
// if we don't have the playlist titles yet
if (mPlaylistTitles == null || mPlaylistTitles.isEmpty()) {
// initialize the spinner with the playlist ID's so that there's something in the UI until the GetPlaylistTitlesAsyncTask finishes
spinnerAdapter = new ArrayAdapter(getContext(), SPINNER_ITEM_LAYOUT_ID, Arrays.asList(mPlaylistIds));
} else {
// otherwise use the playlist titles for the spinner
spinnerAdapter = new ArrayAdapter(getContext(), SPINNER_ITEM_LAYOUT_ID, mPlaylistTitles);
}
spinnerAdapter.setDropDownViewResource(SPINNER_ITEM_DROPDOWN_LAYOUT_ID);
mPlaylistSpinner.setAdapter(spinnerAdapter);
// set up the onItemSelectedListener for the spinner
mPlaylistSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// reload the UI with the playlist video list of the selected playlist
mPlaylistVideos = new PlaylistVideos(mPlaylistIds[position]);
reloadUi(mPlaylistVideos, true);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
}
private void reloadUi(final PlaylistVideos playlistVideos, boolean fetchPlaylist) {
// initialize the cards adapter
initCardAdapter(playlistVideos);
if (fetchPlaylist) {
// start fetching the selected playlistVideos contents
new GetPlaylistAsyncTask(mYouTubeDataApi) {
@Override
public void onPostExecute(Pair<String, List<Video>> result) {
handleGetPlaylistResult(playlistVideos, result);
}
}.execute(playlistVideos.playlistId, playlistVideos.getNextPageToken());
}
}
private void initCardAdapter(final PlaylistVideos playlistVideos) {
// create the adapter with our playlistVideos and a callback to handle when we reached the last item
mPlaylistCardAdapter = new PlaylistCardAdapter(playlistVideos, new LastItemReachedListener() {
@Override
public void onLastItem(int position, String nextPageToken) {
new GetPlaylistAsyncTask(mYouTubeDataApi) {
@Override
public void onPostExecute(Pair<String, List<Video>> result) {
handleGetPlaylistResult(playlistVideos, result);
}
}.execute(playlistVideos.playlistId, playlistVideos.getNextPageToken());
}
});
mRecyclerView.setAdapter(mPlaylistCardAdapter);
}
private void handleGetPlaylistResult(PlaylistVideos playlistVideos, Pair<String, List<Video>> result) {
if (result == null) return;
final int positionStart = playlistVideos.size();
playlistVideos.setNextPageToken(result.first);
playlistVideos.addAll(result.second);
mPlaylistCardAdapter.notifyItemRangeInserted(positionStart, result.second.size());
}
/**
* Interface used by the {@link PlaylistCardAdapter} to inform us that we reached the last item in the list.
*/
public interface LastItemReachedListener {
void onLastItem(int position, String nextPageToken);
}
}
YouTubeActivity.java
package com.example.videotube;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.youtube.YouTube;
public class YouTubeActivity extends AppCompatActivity {
private static final String[] YOUTUBE_PLAYLISTS = {
"PLYc1pO20eF3h6Hb91ZpFXNjKqdYTN0HfM",
"PLYc1pO20eF3iIzDcCwqOeyFt7g3_voXz9",
"PLYc1pO20eF3hdduG6oKcLVqLI1zLdgzXy",
"PLYc1pO20eF3jchZ2_7OS9gnjuLMkS58gp",
"PLYc1pO20eF3i0IYKel6iZ6LUctTRSLjTE"
};
private YouTube mYoutubeDataApi;
private final GsonFactory mJsonFactory = new GsonFactory();
private final HttpTransport mTransport = AndroidHttp.newCompatibleTransport();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.youtube_activity);
if(!isConnected()){
Toast.makeText(YouTubeActivity.this,"No Internet Connection Detected",Toast.LENGTH_LONG).show();
}
if (ApiKey.YOUTUBE_API_KEY.startsWith("YOUR_API_KEY")) {
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setMessage("Edit ApiKey.java and replace \"YOUR_API_KEY\" with your Applications Browser API Key")
.setTitle("Missing API Key")
.setNeutralButton("Ok, I got it!", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else if (savedInstanceState == null) {
mYoutubeDataApi = new YouTube.Builder(mTransport, mJsonFactory, null)
.setApplicationName(getResources().getString(R.string.app_name))
.build();
getSupportFragmentManager().beginTransaction()
.add(R.id.container, YouTubeRecyclerViewFragment.newInstance(mYoutubeDataApi, YOUTUBE_PLAYLISTS))
.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.you_tube, menu);
return true;
}
public boolean isConnected() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_recyclerview) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, YouTubeRecyclerViewFragment.newInstance(mYoutubeDataApi, YOUTUBE_PLAYLISTS))
.commit();
return true;
}
return super.onOptionsItemSelected(item);
}
}
youtube_activity.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.videotube.YouTubeActivity"
tools:ignore="MergeRootFrame" />
Hasil Akhir
Download
Bootcamp Week#7 youtube api + android studio
By Maulana Ilham
Bootcamp Week#7 youtube api + android studio
- 914