début implémentation api themoviedb, mais foireux de fou

pull/17/head
louwar 2 years ago
parent 745ecb427c
commit 07bdd4bac2

@ -15,6 +15,8 @@ android {
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
buildTypes {
@ -31,28 +33,34 @@ android {
jvmTarget = '1.8'
}
buildFeatures {
dataBinding true
viewBinding true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.1'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'androidx.core:core-ktx:1.9.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "com.squareup.okhttp3:okhttp:4.9.3"
implementation "com.squareup.okhttp3:logging-interceptor:4.9.3"
implementation "com.google.code.gson:gson:2.8.9"
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'androidx.fragment:fragment-ktx:1.5.6'
implementation 'androidx.multidex:multidex:2.0.1'
}

@ -1,21 +1,10 @@
package fr.iut.cinecool
import retrofit2.Call
import com.google.android.gms.common.api.Response
import com.google.gson.GsonBuilder
import fr.iut.cinecool.interfaces.ApiService
import fr.iut.cinecool.model.MovieResponse
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.security.auth.callback.Callback
class ApiClient {
companion object {
private const val BASE_URL = "https://api.themoviedb.org/3/"
/*private const val BASE_URL = "https://api.themoviedb.org/3/"
fun create(): ApiService {
@ -49,8 +38,8 @@ class ApiClient {
val apiKey = "a97243d7813d31446f6c43284e6854d5"
val call = movieApiService.getPopularMovies(apiKey)
// TO DO
/*call.enqueue(object : Callback<MovieResponse> {
call.enqueue(object : Callback<MovieResponse> {
override fun onResponse(call: Call<MovieResponse>, response: Response<MovieResponse>) {
// Code à exécuter lorsque la réponse est reçue
val movies = response.body()?.results
@ -60,7 +49,7 @@ class ApiClient {
override fun onFailure(call: Call<MovieResponse>, t: Throwable) {
// Code à exécuter en cas d'échec de la requête
}
})*/
})
*/
}
}

@ -5,49 +5,41 @@ import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import fr.iut.cinecool.interfaces.ITheMovieDbApiCallback
import fr.iut.cinecool.model.Movie
import fr.iut.cinecool.model.MovieAPI
import fr.iut.cinecool.services.TheMovieDbApiClient
import retrofit2.Call
import retrofit2.Response
import javax.security.auth.callback.Callback
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.vu_detail)
// Récupération de la référence de l'ImageButton
val backButton: ImageButton =findViewById(R.id.backButton)
// Récupérer l'identifiant du film depuis les extras de l'intent
val movieId = intent.getIntExtra("movieId", -1)
// Ajout d'un listener pour gérer le clic sur le bouton
backButton.setOnClickListener{
// Code à exécuter lorsque l'utilisateur clique sur le bouton de retour
// Par exemple, pour fermer l'activité en cours et revenir à l'activité précédente :
finish()
// Appeler la méthode pour charger les détails du film
// loadMovieDetails(movieId)
}
// Récupération de la référence du TextView
val textView: TextView =findViewById(R.id.titreFilm)
// Modification du texte affiché dans le TextView
textView.text="Titre de la page"
// Récupération des références des ImageView
val imageView2: ImageView =findViewById(R.id.logo)
val imageView3:ImageView=findViewById(R.id.afficheFilm)
// Chargement des images à partir de fichiers ou d'Internet, par exemple :
/*Glide.with(this)
.load(R.drawable.cinema)
.into(imageView2)
Glide.with(this)
.load(R.drawable.imitation_game)
.into(imageView3)*/
// Récupération de la référence du TextView 2
val textView2:TextView=findViewById(R.id.description)
// Modification du texte affiché dans le TextView 2
textView2.text="Contenu de la page"
/*private fun loadMovieDetails(movieId: Int) {
val apiClient = TheMovieDbApiClient(getString(R.string.tmdb_api_key))
apiClient.getMovieDetails(movieId, object : ITheMovieDbApiCallback<MovieAPI> {
override fun onSuccess(result: MovieAPI) {
// Afficher les détails du film dans la vue
titreFilm.text = result.title
description.text = result.overview
Picasso.get().load("https://image.tmdb.org/t/p/w500/${result.posterPath}").into(afficheFilm)
}
override fun onError(error: Throwable) {
// Gérer l'erreur de récupération des détails du film
}
})
}*/
}

@ -0,0 +1,75 @@
package fr.iut.cinecool
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MovieDetailFragment : Fragment() {
/*
private lateinit var binding: FragmentMovieDetailBinding
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?, savedInstanceState: Bundle?): View
{
binding = FragmentMovieDetailBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
super.onViewCreated(view, savedInstanceState)
val movieId = arguments?.getInt(ARG_MOVIE_ID)
// Appel de l'API pour récupérer les détails du film
CoroutineScope(Dispatchers.IO).launch {
val response = movieId?.let { MovieApiService().getMovieDetails(it) }
withContext(Dispatchers.Main)
{
if (response != null) {
if (response.isSuccessful)
{
val movie = response.body()
if (movie != null)
{
// Affichage des détails du film dans l'interface utilisateur
binding.titreFilm.text = movie.title
binding.description.text = movie.overview
binding.afficheFilm.load("https://image.tmdb.org/t/p/w500${movie.posterPath}") // Utilisation de la librairie Coil pour charger l'image
}
} else
{
Toast.makeText(
requireContext(),
getString(R.string.error_loading_movie),
Toast.LENGTH_SHORT
).show()
}
}
}
}
// Ajout d'un écouteur de clic pour le bouton de retour
binding.backButton.setOnClickListener {
requireActivity().onBackPressed()
}
}
companion object {
private const val ARG_MOVIE_ID = "movie_id"
fun newInstance(movieId: Int): MovieDetailFragment {
val args = Bundle().apply {
putInt(ARG_MOVIE_ID, movieId)
}
return MovieDetailFragment().apply {
arguments = args
}
}
}*/
}

@ -0,0 +1,25 @@
package fr.iut.cinecool
import fr.iut.cinecool.services.TheMovieDbApiClient
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
object RetrofitClient {
private const val BASE_URL = "https://api.themoviedb.org/3/"
private val okHttpClient = OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build()
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
val api: TheMovieDbApiClient = retrofit.create(TheMovieDbApiClient::class.java)
}

@ -1,15 +0,0 @@
package fr.iut.cinecool.interfaces
import fr.iut.cinecool.model.Movie
import fr.iut.cinecool.model.MovieResponse
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
interface ApiService {
@GET("movie/popular")
fun getPopularMovies(@Query("api_key") apiKey: String): Call<MovieResponse>
}

@ -0,0 +1,6 @@
package fr.iut.cinecool.interfaces
interface ITheMovieDbApiCallback<T> {
fun onSuccess(result: T)
fun onError(error: Throwable)
}

@ -0,0 +1,12 @@
package fr.iut.cinecool.interfaces
import fr.iut.cinecool.model.Movie
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query
interface ITheMovieDbService {
@GET("movie/{movieId}")
fun getMovieDetails(@Path("movieId") movieId: Int, @Query("api_key") apiKey: String): Call<Movie>
}

@ -1,7 +0,0 @@
package fr.iut.cinecool.model
import com.google.gson.annotations.SerializedName
// MovieResponse pour stocker la réponse JSON de l'API :
data class MovieResponse(
@SerializedName("results") val movies: List<Movie>
)

@ -0,0 +1,57 @@
package fr.iut.cinecool.services
import fr.iut.cinecool.interfaces.ITheMovieDbApiCallback
import fr.iut.cinecool.interfaces.ITheMovieDbService
import fr.iut.cinecool.model.MovieAPI
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class TheMovieDbApiClient(apiKey: String) {
private val service: ITheMovieDbService = Retrofit.Builder()
.baseUrl("https://api.themoviedb.org/3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ITheMovieDbService::class.java)
private val apiKeyInterceptor = Interceptor { chain ->
val url = chain.request().url.newBuilder()
.addQueryParameter("tmdb_api_key", apiKey)
.build()
val request = chain.request().newBuilder()
.url(url)
.build()
chain.proceed(request)
}
private val client: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(apiKeyInterceptor)
.build()
/*fun getMovieDetails(movieId: Int, callback: ITheMovieDbApiCallback<MovieAPI>) {
service.getMovieDetails(movieId).enqueue(object : Callback<MovieAPI> {
override fun onResponse(call: Call<MovieAPI>, response: Response<MovieAPI>) {
if (response.isSuccessful) {
val result = response.body()
if (result != null) {
callback.onSuccess(result)
} else {
callback.onError(Throwable("Empty response body"))
}
} else {
callback.onError(Throwable("Error ${response.code()}: ${response.message()}"))
}
}
override fun onFailure(call: Call<MovieAPI>, t: Throwable) {
callback.onError(t)
}
})
}*/
}

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

@ -14,7 +14,7 @@
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/Back_arrow" />
app:srcCompat="@drawable/back_arrow" />
<TextView
android:id="@+id/titreFilm"

@ -41,7 +41,7 @@
android:scaleType="fitCenter"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/Filtrage"
app:srcCompat="@drawable/filtrage"
tools:layout_editor_absoluteY="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"

@ -9,4 +9,6 @@
<string name="hello_first_fragment">Hello first fragment</string>
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
<string name="error_loading_movie">erreur de chargement des films</string>
<string name="tmdb_api_key">a97243d7813d31446f6c43284e6854d5</string>
</resources>

@ -2,5 +2,5 @@
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
id 'org.jetbrains.kotlin.android' version '1.8.20-RC2' apply false
}
Loading…
Cancel
Save