S4 : BDD distante via une API REST

This commit is contained in:
Erwann PHILIPPE 2026-02-04 15:47:28 +01:00
parent 102a28da49
commit bf3797f5d8
9 changed files with 154 additions and 7 deletions

View file

@ -3,8 +3,8 @@
<component name="deploymentTargetSelector"> <component name="deploymentTargetSelector">
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DIALOG" />
<DropdownSelection timestamp="2026-02-03T14:43:08.366675Z"> <DropdownSelection timestamp="2026-02-04T13:11:46.468249700Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=QGP7K78LKBMVZTRC" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=QGP7K78LKBMVZTRC" />

View file

@ -38,4 +38,6 @@ dependencies {
androidTestImplementation libs.ext.junit androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core androidTestImplementation libs.espresso.core
implementation 'com.google.code.gson:gson:2.11.0' implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.squareup.retrofit2:retrofit:2.11.0'
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
} }

View file

@ -10,7 +10,8 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Coach"> android:theme="@style/Theme.Coach"
android:usesCleartextTraffic="true">
<activity <activity
android:name=".view.MainActivity" android:name=".view.MainActivity"
android:exported="true"> android:exported="true">
@ -21,5 +22,5 @@
</intent-filter> </intent-filter>
</activity> </activity>
</application> </application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest> </manifest>

View file

@ -0,0 +1,30 @@
package com.example.coach.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class CoachApi {
private static final String API_URL = "http://10.0.2.2/rest_coach/";
private static Retrofit retrofit = null;
private static Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create();
public static Retrofit getRetrofit()
{
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
public static Gson getGson() {
return gson;
}
}

View file

@ -0,0 +1,20 @@
package com.example.coach.api;
import com.example.coach.model.Profil;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
public interface IRequestApi {
@GET("profil")
Call<ResponseApi<List<Profil>>> getProfils();
@FormUrlEncoded
@POST("profil")
Call<ResponseApi<Integer>> creerProfil(@Field("champs") String profilJson);
}

View file

@ -0,0 +1,31 @@
package com.example.coach.api;
public class ResponseApi<T> {
private int code;
private String message;
private T result;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
}

View file

@ -18,8 +18,8 @@ public class Profil {
private Integer taille; private Integer taille;
private Integer age; private Integer age;
private Integer sexe; private Integer sexe;
private double img; private transient double img;
private int indice; private transient int indice;
private Date dateMesure; private Date dateMesure;
/** /**

View file

@ -1,9 +1,22 @@
package com.example.coach.presenter; package com.example.coach.presenter;
import android.util.Log;
import androidx.annotation.NonNull;
import com.example.coach.api.CoachApi;
import com.example.coach.api.IRequestApi;
import com.example.coach.api.ResponseApi;
import com.example.coach.contract.ICalculView; import com.example.coach.contract.ICalculView;
import com.example.coach.model.Profil; import com.example.coach.model.Profil;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* 'presenter' dédié à la vue affichant le calcul de l'img * 'presenter' dédié à la vue affichant le calcul de l'img
@ -30,6 +43,54 @@ public class CalculPresenter {
public void creerProfil(Integer sexe, Integer poids, Integer taille, Integer age) public void creerProfil(Integer sexe, Integer poids, Integer taille, Integer age)
{ {
Profil profil = new Profil(poids, taille, age, sexe, new Date()); Profil profil = new Profil(poids, taille, age, sexe, new Date());
vue.AfficherResultat(profil.getImage(), profil.getImg(), profil.getMessage(), profil.normal()); String profilJson = CoachApi.getGson().toJson(profil);
IRequestApi api = CoachApi.getRetrofit().create(IRequestApi.class);
Call<ResponseApi<Integer>> call = api.creerProfil(profilJson);
call.enqueue(new Callback<ResponseApi<Integer>>() {
@Override
public void onResponse(Call<ResponseApi<Integer>> call, Response<ResponseApi<Integer>> response) {
Log.d("API", "code : " + response.body().getCode() +
" message : " + response.body().getMessage() +
" result : " + response.body().getResult()
);
if(response.isSuccessful() && response.body().getResult() == 1){
vue.AfficherResultat(profil.getImage(), profil.getImg(), profil.getMessage(), profil.normal());
}else{
Log.e("API", "Erreur API: " + response.code());
}
}
@Override
public void onFailure(Call<ResponseApi<Integer>> call, @NonNull Throwable throwable) {
Log.e("API", "Échec d'accès à l'api", throwable);
}
});
}
public void chargerDernierProfil()
{
IRequestApi api = CoachApi.getRetrofit().create(IRequestApi.class);
Call<ResponseApi<List<Profil>>> call = api.getProfils();
call.enqueue(new Callback<ResponseApi<List<Profil>>>() {
@Override
public void onResponse(Call<ResponseApi<List<Profil>>> call, Response<ResponseApi<List<Profil>>> response) {
List<Profil> profils = response.body().getResult();
if(profils != null && !profils.isEmpty()){
Profil dernier = Collections.max(
profils,
(p1, p2) -> p1.getDateMesure().compareTo(p2.getDateMesure())
);
vue.remplirChamps(dernier.getPoids(), dernier.getTaille(), dernier.getAge(), dernier.getSexe());
}
}
@Override
public void onFailure(Call<ResponseApi<List<Profil>>> call, Throwable throwable) {
Log.e("API", "Échec d'accès à l'api", throwable);
}
});
} }
} }

View file

@ -100,6 +100,8 @@ public class MainActivity extends AppCompatActivity implements ICalculView {
chargeObjetsGraphiques(); chargeObjetsGraphiques();
presenter = new CalculPresenter(this); presenter = new CalculPresenter(this);
btnCalc.setOnClickListener(v -> btnCalcClic()); btnCalc.setOnClickListener(v -> btnCalcClic());
presenter.chargerDernierProfil();
} }
/** /**