my error is whan click on youtube play list and display all playlist videos. when click on video then app Stop working. So how to resolve this issue?
package com.app.dataapitest;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.RelativeLayout;
import android.widget.TabHost;
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;
import com.google.api.services.youtube.model.PlaylistItem;
import com.google.api.services.youtube.model.PlaylistItemListResponse;
import com.google.api.services.youtube.model.PlaylistListResponse;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoListResponse;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import Adapters.PlaylistAdapter;
import Adapters.VideolistAdapter;
import static Utils.Constants.YOUTUBE_API_KEY;
public class PlaylistActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView recyclerView;
private VideolistAdapter listAdapter;
public String nextPageToken = null;
Animation slide_down,slide_up;
int page = 0;
private RecyclerView.LayoutManager mLayoutManager;
RelativeLayout loadingLayout;
boolean isLoading = false;
private ArrayList<Video> mPlaylistList = new ArrayList<>();
private final GsonFactory mJsonFactory = new GsonFactory();
private final HttpTransport mTransport = AndroidHttp.newCompatibleTransport();
private YouTube mYoutubeDataApi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_playlist);
Intent intent = getIntent();
final String id = intent.getStringExtra("Id");
Log.d("Id:",id);
recyclerView = (RecyclerView) findViewById(R.id.recyclerViewID);
loadingLayout = (RelativeLayout) findViewById(R.id.loadingRecyclerID);
//Load animation
slide_down = AnimationUtils.loadAnimation(this, R.anim.slide_down);
slide_up = AnimationUtils.loadAnimation(this, R.anim.slide_up);
mYoutubeDataApi = new YouTube.Builder(mTransport, mJsonFactory, null)
.setApplicationName(getResources().getString(R.string.app_name))
.build();
loadingLayout.setVisibility(View.VISIBLE);
loadingLayout.startAnimation(slide_up);
new GetPlaylistAsyncTask(mYoutubeDataApi).execute(id);
// Load more images onScroll end
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Check if end of page has been reached
if( !isLoading && ((LinearLayoutManager)mLayoutManager).findLastVisibleItemPosition() == listAdapter.getItemCount()-1 ){
isLoading = true;
Log.d(TAG , "End has reached, loading more images!");
loadingLayout.startAnimation(slide_up);
loadingLayout.setVisibility(View.VISIBLE);
if (nextPageToken!=null){
new GetPlaylistAsyncTask(mYoutubeDataApi).execute(id,nextPageToken);
}else {
loadingLayout.setVisibility(View.INVISIBLE);
loadingLayout.startAnimation(slide_down);
}
}
}
});
}
public void generateRecyclerView(ArrayList<Video> result){
// Set up RecyclerView
mLayoutManager = new GridLayoutManager(PlaylistActivity.this, 1);
listAdapter = new VideolistAdapter(PlaylistActivity.this,result);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(listAdapter);
listAdapter.setOnItemClickListener(new VideolistAdapter.OnItemClickListener() {
@Override
public void OnItemClick(int position) {
Intent intent = new Intent(PlaylistActivity.this,PlayerActivity.class);
intent.putExtra("id",listAdapter.getItemList().get(position).getId());
intent.putExtra("title", listAdapter.getItemList().get(position).getSnippet().getTitle());
intent.putExtra("description", listAdapter.getItemList().get(position).getSnippet().getDescription());
intent.putExtra("like", listAdapter.getItemList().get(position).getStatistics().getLikeCount().doubleValue());
intent.putExtra("dislike", listAdapter.getItemList().get(position).getStatistics().getDislikeCount().doubleValue());
intent.putExtra("views", listAdapter.getItemList().get(position).getStatistics().getViewCount().doubleValue());
intent.putExtra("duration", listAdapter.getItemList().get(position).getContentDetails().getDuration());
startActivity(intent);
}
@Override
public void OnItemLongClick(int position) {
}
});
}
public class GetPlaylistAsyncTask extends AsyncTask<String, Void, Pair<String, ArrayList<Video>>> {
private static final String TAG = "GetPlaylistAsyncTask";
private final Long YOUTUBE_PLAYLIST_MAX_RESULTS = 10L;
//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, ArrayList<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(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(YOUTUBE_API_KEY)
.setId(TextUtils.join(",", videoIds)).execute();
} catch (IOException e) {
e.printStackTrace();
}
return new Pair(playlistItemListResponse.getNextPageToken(), videoListResponse.getItems());
}
@Override
protected void onPostExecute(Pair<String, ArrayList<Video>> stringArrayListPair) {
super.onPostExecute(stringArrayListPair);
if (stringArrayListPair == null) return;
if (nextPageToken == null){
if (page==0){
generateRecyclerView(stringArrayListPair.second);
}
}else {
listAdapter.addVideos(stringArrayListPair.second);
}
nextPageToken = stringArrayListPair.first;
page++;
isLoading = false;
loadingLayout.setVisibility(View.INVISIBLE);
loadingLayout.startAnimation(slide_down);
}
}
}
Here is player activity
package com.app.dataapitest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
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;
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.google.gson.Gson;
import java.text.DecimalFormat;
import Utils.Constants;
public class PlayerActivity extends YouTubeBaseActivity {
public static final String TAG = PlaylistActivity.class.getSimpleName();
private YouTubePlayerView playerView;
private TextView videoTitle,videoViews,publishTime,videoDescription,likeCount,dislikeCount;
private static final DecimalFormat sFormatter = new DecimalFormat("#,###,###");
private RelativeLayout videoLikes,videoDislikes,download,share;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
Intent intent = getIntent();
final String id = intent.getStringExtra("id");
final String title = intent.getStringExtra("title");
final String description = intent.getStringExtra("description");
final Double like = intent.getDoubleExtra("like",0);
final Double dislike = intent.getDoubleExtra("dislike",0);
final Double views = intent.getDoubleExtra("views",0);
final String duration = intent.getStringExtra("duration");
playerView = (YouTubePlayerView) findViewById(R.id.playerId);
videoTitle = (TextView) findViewById(R.id.videoNameId);
videoViews = (TextView) findViewById(R.id.viewsId);
publishTime = (TextView) findViewById(R.id.publishId);
videoDescription = (TextView) findViewById(R.id.descId);
videoLikes = (RelativeLayout) findViewById(R.id.likeId);
videoDislikes = (RelativeLayout) findViewById(R.id.dislikeId);
download = (RelativeLayout) findViewById(R.id.downloadId);
share = (RelativeLayout) findViewById(R.id.shareId);
likeCount = (TextView) findViewById(R.id.likeCountId);
dislikeCount = (TextView) findViewById(R.id.dislikeCountId);
YouTubePlayer.OnInitializedListener onInitializedListener = new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
youTubePlayer.loadVideo(id);
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
}
};
// initialize video with details
playerView.initialize(Constants.YOUTUBE_API_KEY, onInitializedListener);
videoTitle.setText(title);
videoDescription.setText(description);
// Log.d(TAG,String.valueOf(duration));
// Log.d(TAG,String.valueOf(dislike));
// Log.d(TAG,String.valueOf(views));
// set the video statistics
publishTime.setText(parseDuration(duration));
videoViews.setText(sFormatter.format(views) + " views");
likeCount.setText(sFormatter.format(like));
dislikeCount.setText(sFormatter.format(dislike));
share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Watch \"" + title + "\" on YouTube");
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://www.youtube.com/watch?v=" + id);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
});
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(PlayerActivity.this, "Feature not available yet...", Toast.LENGTH_SHORT).show();
}
});
}
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 +" minutes " + seconds + " seconds";
}
}
Here is player xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
tools:context=".PlayerActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<view
android:id="@+id/playerId"
class="com.google.android.youtube.player.YouTubePlayerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints" />
<RelativeLayout
android:id="@+id/descLayoutId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/playerId">
<TextView
android:id="@+id/videoNameId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="18dp"
android:fontFamily="@font/montserrat"
android:layout_marginStart="18dp"
android:layout_marginEnd="48dp"
android:textStyle="bold"
android:text="Sample video name with chapter description"/>
<RelativeLayout
android:id="@+id/statusId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_below="@+id/videoNameId">
<TextView
android:id="@+id/viewsId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2,234 views"
android:fontFamily="@font/montserrat"
android:layout_marginStart="10dp" />
<TextView
android:id="@+id/publishId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="15 hours ago"
android:fontFamily="@font/montserrat"
android:layout_toEndOf="@+id/viewsId"
android:layout_marginStart="48dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/toolsId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/statusId"
android:padding="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="18dp">
<RelativeLayout
android:id="@+id/likeLayoutId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp">
<RelativeLayout
android:id="@+id/likeId"
android:layout_width="34dp"
android:layout_height="34dp"
android:background="@drawable/circle">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp"
android:src="@drawable/round_thumb_up"/>
</RelativeLayout>
<TextView
android:id="@+id/likeCountId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2K"
android:textSize="10sp"
android:layout_marginTop="4dp"
android:layout_centerInParent="true"
android:fontFamily="@font/montserrat"
android:layout_below="@+id/likeId"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/dislikeLayoutId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="48dp"
android:layout_toEndOf="@+id/likeLayoutId">
<RelativeLayout
android:id="@+id/dislikeId"
android:layout_width="34dp"
android:layout_height="34dp"
android:background="@drawable/circle">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp"
android:src="@drawable/round_thumb_down"/>
</RelativeLayout>
<TextView
android:id="@+id/dislikeCountId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2K"
android:textSize="10sp"
android:layout_marginTop="4dp"
android:layout_centerInParent="true"
android:fontFamily="@font/montserrat"
android:layout_below="@+id/dislikeId"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/downloadLayoutId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="48dp"
android:layout_toEndOf="@+id/dislikeLayoutId">
<RelativeLayout
android:id="@+id/downloadId"
android:layout_width="34dp"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_height="34dp"
android:background="@drawable/circle">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp"
android:src="@drawable/round_download"/>
</RelativeLayout>
<TextView
android:id="@+id/downloadTextId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Download"
android:textSize="10sp"
android:layout_marginTop="4dp"
android:layout_centerInParent="true"
android:fontFamily="@font/montserrat"
android:layout_below="@+id/downloadId"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/shareLayoutId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="48dp"
android:layout_toEndOf="@+id/downloadLayoutId">
<RelativeLayout
android:id="@+id/shareId"
android:layout_width="34dp"
android:layout_height="34dp"
android:background="@drawable/circle">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp"
android:src="@drawable/round_share"/>
</RelativeLayout>
<TextView
android:id="@+id/shareTextId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Share"
android:textSize="10sp"
android:layout_marginTop="4dp"
android:layout_centerInParent="true"
android:fontFamily="@font/montserrat"
android:layout_below="@+id/shareId"/>
</RelativeLayout>
</RelativeLayout>
<ScrollView
android:layout_below="@+id/toolsId"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/descHeaderId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Video Description"
android:textStyle="bold"
android:textSize="14sp"
android:fontFamily="@font/montserrat"
android:layout_marginStart="18dp"/>
<TextView
android:id="@+id/descId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginEnd="18dp"
android:layout_marginTop="8dp"
android:autoLink="phone|web"
android:layout_marginBottom="18dp"
android:layout_below="@+id/descHeaderId"
android:text="Basic video description here"
android:fontFamily="@font/montserrat"/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
</RelativeLayout>
</FrameLayout>