안드로이드 자바
[Java][Android] 안드로이드 Java로 유튜브 검색 구현하기
teamnova
2025. 4. 21. 13:31
728x90
안녕하세요
youtube API를 사용해서 유튜브 검색을 하는 방법을 알아보도록 하겠습니다.
https://stickode.tistory.com/331
[JAVA][Android] Youtube API 사용법
이번에는 유튜브 API 를 사용해보겠습니다. https://stickode.com/detail.html?no=2714 스틱코드 stickode.com 위의 포스트를 즐겨찾기 하시면 'Activity_Youtube.java' 를 입력하여, 해당 코드를 사용할 수 있습니다. 1.
stickode.tistory.com
API 발급 방법입니다. 참고하시길 바랍니다.
build.gradle 파일에 다음의 depencies를 추가해주세요.
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation libs.converter.gson
implementation 'com.github.bumptech.glide:glide:4.13.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
implementation libs.cardview
35로 변경해주세요
compileSdk 35
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:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="12dp"
tools:context=".MainActivity">
<!-- 검색창 -->
<EditText
android:id="@+id/search_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="검색어를 입력하세요"
android:padding="12dp"
android:background="@android:drawable/edit_text"
android:layout_marginBottom="8dp"
android:inputType="text" />
<!-- 검색 버튼 -->
<Button
android:id="@+id/search_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="검색"
android:layout_marginBottom="12dp" />
<!-- RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/video_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
item_video.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:id="@+id/video_thumbnail"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/video_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Video Title"
android:textSize="16sp"
android:textStyle="bold"
android:paddingTop="8dp"
android:paddingBottom="4dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
MainActivity
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
private EditText searchInput;
private Button searchButton;
private RecyclerView recyclerView;
private VideoAdapter adapter;
private final String API_KEY = ""; // 🔑 유튜브 API 키로 교체하세요
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchInput = findViewById(R.id.search_input);
searchButton = findViewById(R.id.search_button);
recyclerView = findViewById(R.id.video_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new VideoAdapter(this);
recyclerView.setAdapter(adapter);
searchButton.setOnClickListener(v -> {
String query = searchInput.getText().toString().trim();
if (!query.isEmpty()) {
searchYoutubeVideos(query);
} else {
Toast.makeText(MainActivity.this, "검색어를 입력해주세요", Toast.LENGTH_SHORT).show();
}
});
}
private void searchYoutubeVideos(String query) {
YoutubeApiService apiService = ApiClient.getClient().create(YoutubeApiService.class);
Call<YoutubeResponse> call = apiService.searchVideos(
"snippet",
query,
"video",
20,
API_KEY
);
call.enqueue(new Callback<YoutubeResponse>() {
@Override
public void onResponse(Call<YoutubeResponse> call, Response<YoutubeResponse> response) {
if (response.isSuccessful() && response.body() != null) {
List<VideoItem> videos = response.body().getItems();
adapter.setVideoList(videos);
} else {
Toast.makeText(MainActivity.this, "검색 실패", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<YoutubeResponse> call, Throwable t) {
Toast.makeText(MainActivity.this, "네트워크 오류: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
ApiClient
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
private static Retrofit retrofit = null;
private static final String BASE_URL = "https://www.googleapis.com/youtube/v3/";
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
VideoAdapter
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
private static Retrofit retrofit = null;
private static final String BASE_URL = "https://www.googleapis.com/youtube/v3/";
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
VideoItem
public class VideoItem {
private Snippet snippet;
public Snippet getSnippet() {
return snippet;
}
public void setSnippet(Snippet snippet) {
this.snippet = snippet;
}
public static class Snippet {
private String title;
private Thumbnails thumbnails;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Thumbnails getThumbnails() {
return thumbnails;
}
public void setThumbnails(Thumbnails thumbnails) {
this.thumbnails = thumbnails;
}
}
public static class Thumbnails {
private Medium medium;
public Medium getMedium() {
return medium;
}
public void setMedium(Medium medium) {
this.medium = medium;
}
public static class Medium {
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
}
}
YoutubeApiService
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface YoutubeApiService {
@GET("search")
Call<YoutubeResponse> searchVideos(
@Query("part") String part,
@Query("q") String query,
@Query("type") String type,
@Query("maxResults") int maxResults,
@Query("key") String apiKey
);
}
YoutubeResponse
import java.util.List;
public class YoutubeResponse {
private List<VideoItem> items;
public List<VideoItem> getItems() {
return items;
}
public void setItems(List<VideoItem> items) {
this.items = items;
}
}
시연영상