728x90
안녕하세요. 오늘은 YOUTUBE API를 사용해서 유뷰트 비디오를 검색하고, 그에 맞는 정보를 받아와서 리싸이클러뷰에 담아주는 방법을 알아보도록 하겠습니다.
다음의 포스팅을 참고하셔서 YOUTUBE API를 먼저 설정해주세요.
https://stickode.tistory.com/331
build.gradle 파일에 다음의 depencies를 추가해주세요.
implementation 'com.github.bumptech.glide:glide:4.15.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
main.xml 파일입니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<!--검색어 입력창-->
<EditText
android:id="@+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
android:layout_marginEnd="13dp"
android:ems="10"
android:inputType="textPersonName"
android:text=""
app:layout_constraintEnd_toStartOf="@+id/button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--검색버튼-->
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="22dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="47dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/recyclerview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/search"
app:layout_constraintTop_toTopOf="parent" />
<!--리싸이클러뷰-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="23dp"
android:layout_marginEnd="23dp"
android:layout_marginBottom="36dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
다음은 리싸이클러뷰 item을 담아줄 item_utube.xml 파일입니다.
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
android:orientation="horizontal" >
<!-- 썸네일 이미지뷰-->
<ImageView
android:id="@+id/titleImage"
android:layout_width="200dp"
android:layout_height="100dp"
android:src="@color/cardview_dark_background"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"></ImageView>
<!-- 제목표시 텍스트뷰-->
<TextView
android:id="@+id/titleText"
android:layout_width="200dp"
android:layout_height="50dp"
android:ellipsize="end"
android:maxLines="2"
android:text="title"
app:layout_constraintStart_toEndOf="@+id/titleImage"
app:layout_constraintTop_toTopOf="parent"></TextView>
<!-- 날짜표시 텍스트뷰-->
<TextView
android:id="@+id/dateText"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:singleLine="true"
android:text="time"
app:layout_constraintStart_toStartOf="@+id/titleText"
app:layout_constraintTop_toBottomOf="@+id/titleText"></TextView>
</androidx.constraintlayout.widget.ConstraintLayout>
main.java 파일입니다.
package com.example.youtubesearch;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.nfc.Tag;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import javax.security.auth.login.LoginException;
public class MainActivity extends AppCompatActivity {
EditText search;
Button button;
RecyclerView recyclerview;
UtubeAdapter utubeAdapter;
AsyncTask<?, ?, ?> searchTask;
ArrayList<SearchData> sdata = new ArrayList<SearchData>();
final String serverKey="본인의 유튜브 API 키를 입력해주세요";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
search = findViewById(R.id.search);
button = findViewById(R.id.button);
recyclerview= findViewById(R.id.recyclerview);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
recyclerview.setLayoutManager(mLinearLayoutManager);
//버튼 클릭시 검색한 정보를 가져옴.
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
searchTask = new searchTask().execute();
}
});
}
private class searchTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
try {
paringJsonData(getUtube()); //비동기로 가져온 데이터를 파싱
} catch (JSONException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
utubeAdapter = new UtubeAdapter(MainActivity.this, sdata);
recyclerview.setAdapter(utubeAdapter);
utubeAdapter.notifyDataSetChanged(); //가져온 데이터 리싸이클러뷰에 업데이트
}
}
//검색한 결과들을 json 객체로 생성
public JSONObject getUtube() throws IOException {
String originUrl = "https://www.googleapis.com/youtube/v3/search?"
+ "part=snippet&q=" + search.getText().toString()
+ "&key="+ serverKey+"&maxResults=50";
String myUrl = String.format(originUrl);
URL url = new URL(myUrl);
HttpURLConnection connection =(HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.connect();
String line;
String result="";
InputStream inputStream=connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer response = new StringBuffer();
while ((line = reader.readLine())!=null){
response.append(line);
}
System.out.println("검색결과"+ response);
result=response.toString();
JSONObject jsonObject = new JSONObject();
try {
jsonObject = new JSONObject(result);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
//json 객체 파싱
private void paringJsonData(JSONObject jsonObject) throws JSONException {
//재검색할때 데이터들이 쌓이는걸 방지하기 위해 리스트를 초기화 시켜준다.
sdata.clear();
JSONArray contacts = jsonObject.getJSONArray("items");
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String kind = c.getJSONObject("id").getString("kind"); // 종류를 체크하여 playlist도 저장
if(kind.equals("youtube#video")){
// 유튜브 비디오 검색
vodid = c.getJSONObject("id").getString("videoId");
}else{
// 유튜브 채널검색
vodid = c.getJSONObject("id").getString("playlistId");
}
String title = c.getJSONObject("snippet").getString("title"); //유튜브 제목
String changString = stringToHtmlSign(title);
String date = c.getJSONObject("snippet").getString("publishedAt") //등록날짜
.substring(0, 10);
String imgUrl = c.getJSONObject("snippet").getJSONObject("thumbnails")
.getJSONObject("default").getString("url"); //썸네일 이미지 URL값
String channel = c.getJSONObject("snippet").getString("channelTitle");
//JSON으로 파싱한 정보들을 객체화 시켜서 리스트에 담아준다.
sdata.add(new SearchData(vodid, changString, imgUrl, date));
}
}
String vodid = "";
//영상 제목을 받아올때 " ' 문자가 그대로 출력되기 때문에 다른 문자로 대체
private String stringToHtmlSign(String str) {
return str.replaceAll("&", "[&]")
.replaceAll("[<]", "<")
.replaceAll("[>]", ">")
.replaceAll(""", "'")
.replaceAll("'", "'");
}
}
받아온 데이터를 담아줄 SearchData.java 파일입니다.
package com.example.youtubesearch;
public class SearchData {
String videoId;
String title;
String ImageUrl;
String publishedAt;
public SearchData(String videoId, String title, String ImageUrl,
String publishedAt) {
super();
this.videoId = videoId;
this.title = title;
this.ImageUrl = ImageUrl;
this.publishedAt = publishedAt;
}
public String getVideoId() {
return videoId;
}
public void setVideoId(String videoId) {
this.videoId = videoId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageUrl() {
return ImageUrl;
}
public void setImageUrl(String imageUrl) {
this.ImageUrl = imageUrl;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
UtubeAdapter.java 파일입니다.
package com.example.youtubesearch;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class UtubeAdapter extends RecyclerView.Adapter<UtubeAdapter.UtubeViewHolder> {
ArrayList<SearchData> mList;
Context context;
public UtubeAdapter(Context context, ArrayList<SearchData> list) {
this.context = context;
this.mList = list;
}
public class UtubeViewHolder extends RecyclerView.ViewHolder{
ImageView titleImage;
TextView titleText;
TextView dateText;
public UtubeViewHolder(@NonNull View itemView) {
super(itemView);
this.titleImage=itemView.findViewById(R.id.titleImage);
this.titleText=itemView.findViewById(R.id.titleText);
this.dateText=itemView.findViewById(R.id.dateText);
}
}
@NonNull
@Override
public UtubeAdapter.UtubeViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
//item_utube xml파일을 객체화
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_utube, viewGroup, false);
UtubeAdapter.UtubeViewHolder holder = new UtubeAdapter.UtubeViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull UtubeAdapter.UtubeViewHolder viewholder, int position) {
//영상제목 세팅
viewholder.titleText.setText(mList.get(position).getTitle());
//날짜 세팅
viewholder.dateText.setText(mList.get(position).getPublishedAt());
//이미지를 넣어주기 위해 이미지url을 가져온다.
String imageUrl = mList.get(position).getImageUrl();
//영상 썸네일 세팅
Glide.with(viewholder.titleImage)
.load(imageUrl)
.into(viewholder.titleImage);
}
@Override
public int getItemCount() {
return (null != mList ? mList.size() : 0);
}
}
실행 결과 화면입니다.
'안드로이드 자바' 카테고리의 다른 글
[Android][Java] 글자에 색을 입혀보기 ( Spannable 사용하기) (0) | 2023.08.06 |
---|---|
[Android][Java] EditText 에서 작성 가능한 숫자 범위 제한하기 (0) | 2023.08.05 |
[Java][Android] TextView 클릭 시 효과(ripple)주기 (0) | 2023.08.01 |
[Android][Java] 아두이노 블루투스 모듈과 통신하는법 (0) | 2023.07.31 |
[Android][Java] 리사이클러뷰 최하단 이동 (0) | 2023.07.23 |