Projet "dépann'Tout" : Accès aux données présentes sur un serveur
Contexte
Suite du contexte de l'auto-entrepreneur avec sa société Dépann'tout.
Devant le succès de son activité, l'auto-entrepreneur a investi dans du matériel informatique sur lequel il disposera d'un logiciel permettant la prise de rendez-vous(ses interventions), la gestion commerciale et la comptabilité. Ainsi, la prise de rendez-vous sera assurée par son épouse dans un premier temps.
Les rendez-vous(les interventions) seront enregistrés dans une base de données. Chaque jour les rendez-vous du jour seront transférés vers le mobile, ainsi l'auto-entrepreneur pourra continuer de gérer ses interventions. En fin de journée, les interventions seront transmises vers le serveur web.
Principe général du transfert du serveur de données vers me mobile
Préparation du travail côté serveur : création d'un service web
- Créer la base de données (bdReparTout par exemple, le nom peut-être différent que sur le client avec SQLite) avec les tables clients et rendez-vous. Créer plusieurs clients avec des rendez-vous.
- Avec NetBeans, créer une nouvelle application web : ReparTout
- Dans cette application, créer le dossier include pour les scripts qui seront à inclure
- Dans include :
- Recopier la classe ConnexionBDD (présente sur le Drive), l'adapter pour votre base de données (modifier, le nom de user, le mot de passe et le nom de la base de données)
- Écrire le script chargementClasses.inc.php qui assurera le chargement des classe nécessaires :
<?php /* Chargement des classes nécessaires */ spl_autoload_register('chargerClasse'); function chargerClasse($classe) { require "include/".$classe.".php"; }
- 5. Écrire le script php getLesRendezVous.php au niveau de la racine de l'application
<?php /* Recherche des rendez-vous du jour, avec les clients concernés – Format JSON */ include_once 'include/chargementClasses.inc.php'; try { $laConnexion = new ConnexionBDD(); $sql = 'SELECT … ;'; **//à compléter** $reponse = $laConnexion->dbh()->query($sql);// Exécution requête // Formatage de la réponse en un tableau associatif $output = array("lesRendezVous"=>$reponse->fetchAll(PDO::FETCH_ASSOC)); } catch (Exception $e) { die('Erreur : ' . $e->getMessage()); } // Formatage du tableau en JSON echo(json_encode($output)); ?>
- 6. Tester à l'aide d'un navigateur (url : http://localhost/PHPProjects/ReparTout/getLesRendezVous.php), La réponse au format JSON doit s'afficher.
- 7. Tester également l'accès à votre service au niveau du périphérique Android. Pour cela,
- rechercher l'adresse IP de votre poste de travail
- accéder au navigateur du périphérique Android, et taper la même url que précédemment en remplaçant localhost par l'adresse IP du serveur web.
Jalon1 : vous devez voir s'afficher les rdv du jour au format JSON
Compléter l'application Android DepannTout (Travail côté Client)
Afin de ne pas perdre tout le travail réalisé à cause d'une fausse manipulation, dupliquer l'application.
L'auto-entrepreneur va (en cliquant sur un bouton) importer automatiquement les rdv du jour en provenance du serveur. Cette importation va automatiquement mettre à jour les clients (si il y a des rdv avec de nouveaux clients) et les interventions (avec les rdv pris).
Autorisations
Il est nécessaire d'autoriser l'application à accéder à Internet, pour cela, ajouter les lignes suivantes au niveau du fichier manifests/AndroidManifest.xml, avant la balise </manifest> :
<!-- Internet Permissions --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
À l'intérieur de la balise <application, avant sa fermeture, ajouter l'attribut :
android:usesCleartextTraffic="true"
Installation de la bibliothèque Volley
La bibliothèque Volley facilite la gestion asynchrone des appels réseaux.https://google.github.io/volley/
Pour l'intégrer au projet, il faut modifier le fichier build.gradle.kts (module app). Il faut ajouter la ligne suivante dans les dépendances : implementation(libs.volley)
dependencies { implementation(libs.appcompat) implementation(libs.material) implementation(libs.activity) implementation(libs.constraintlayout) testImplementation(libs.junit) androidTestImplementation(libs.ext.junit) androidTestImplementation(libs.espresso.core) implementation(libs.volley) }
Création d'une classe Importation
Créer une nouvelle empty view activity appelée Importation. Ajouter un titre et un bouton Quitter. Écrire le code du bouton Quitter. Tester
Cette classe nous permettra de gérer le transfert de données depuis le serveur. Mettre cette classe au même niveau que les classes xxxActivity.java
Au niveau de l'activity Main, ajouter le bouton “Importer les rendez-vous”, écrire le code correspondant (un clic sur ce bouton lancera l'activité Importation.)
Importation des données avec le module Volley
Reprendre l'activité Importation.
Créer la méthode importer suivante : (NB : remplacer adressIPServeurWeb par l'adresse IP repérée précédemment)
// url de la requête au serveur String url = "http://adressIPServeurWeb/ReparTout/getLesRendezVous.php"; RequestQueue queue = Volley.newRequestQueue(this); Log.i("volley-requete","volley1 ok"); JSONObject jsonObject = null; // objet JSON envoyé au serveur //Requête envoyée au serveur JsonObjectRequest jsonObjectRequest = new JsonObjectRequest( Request.Method.GET, url, jsonObject, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Toast.makeText(getApplicationContext(), "Réponse serveur : "+response.toString(), Toast.LENGTH_LONG).show(); Log.i("volley-requete",response.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getApplicationContext(), "ça a planté!", Toast.LENGTH_SHORT).show(); Log.e("volley-requete","volley erreur réponse : " + error.getMessage()); } } ); // Add the request to the RequestQueue. queue.add(jsonObjectRequest); Log.i("volley-requete","fin ok");
adressIPServeurWeb est à remplacer par l'adresse IP 10.0.2.2 car le périphérique de l'émulateur Android n'interprète pas le localhost de la machine hôte. 10.0.2.2 est un alias pour accéder à l’hôte local de votre ordinateur à partir d’un émulateur Android.
Après envoi de la requête au serveur, 2 écouteurs sont créés, ils seront sollicités selon le succès ou l'échec de la requête.
L'objet RequestQueue gère la file d'attente des requêtes.
Exploitation(partielle) des données importées
Note: l'exploitation ici ne concerne que les données des clients
Dans la classe Importation, créer une nouvelle méthode appelée integrerLesDonnees, qui aura besoin d'un paramètre de type JSONObject.
Cette méthode va récupérer le fichier json envoyé par le serveur, et recopier les données dans la collection lesClients dans un premier temps :
ArrayList<Client> lesClients = new ArrayList<Client>(); try { JSONArray array = new JSONArray(jsonObject.getString("lesRendezVous")); Log.i("httphab", "taille du tableau " + array.length()); // Chaque objet JSON devient un objet de type Client, rangé dans la collection for (int i = 0; i < array.length(); i++) { // On récupère un objet JSON du tableau JSONObject obj = new JSONObject(array.getString(i)); // On fait le lien Client - Objet JSON Client unClient = new Client(); unClient.setIdDistant(obj.getInt("id")); unClient.setNom(obj.getString("nom")); unClient.setPrenom(obj.getString("prenom")); unVlient.setAdresse(obj.getString("adresse")); // … Log.i("httphab", "unClient " + unClient.toString()); // On ajoute unClient à la liste lesClients.add(unClient); } } catch (JSONException e) { Log.e("volley erreur", "*** JSONException, integrerLesDonnees ***" ); e.printStackTrace(); } Toast.makeText(getApplicationContext(), "Nb clients transférés : " + lesClients.size(), Toast.LENGTH_SHORT).show();
Afficher les données récupérées
Afficher les données dans une listView comme la liste des articles du projet Inventaire :
- Ajouter une LinearLayout, avec 3 TextView pour les intitulés de colonnes (id, nom et prénom), puis ajouter une ListView pour la liste des clients.
- Créer une Layout (ligne_client par exemple) avec une LinearLayout comprenant 3 TextView.
- Pour afficher les clients, on pourra utiliser la classe SimpleAdapter
Extrait du constructeur (cf https://developer.android.com/reference/android/widget/SimpleAdapter.html )
Les données à afficher doivent être dans une List de Maps. Il faudra donc reformater notre collection lesClients :
ArrayList<HashMap<String,String>> lesClientsHM = new ArrayList<>(); For (Client unClient : lesClients) { HashMap<String,String> hashMap=new HashMap<>();//creation d'une map hashMap.put("id",Integer.toString(unClient.getId())); hashMap.put("nom",unClient.getNom()); hashMap.put("prenom",unClient.getPrenom()); lesClientsHM.add(hashMap);//ajout dans la collection }
L'affichage se fera ensuite ainsi :
ListAdapter adapter = new SimpleAdapter( ListeClientsActivity.this, lesClientsHM, R.layout.ligne_Client, // new String[] { "id", "nom" , "prenom"}, new int[] { R.id.tvIdC, R.id.tvNomC, R.id.tvPrenomC }); // maj listview de activity_liste_Clients ListView lvHab = (ListView) findViewById(R.id.lvHab) ; lvHab.setAdapter(adapter);
Les clients seront ensuite à intégrer dans la base de données SQLite s'ils n'existaient pas déjà. Ajouter le même traitement pour les interventions. Fonctionnalités à développer, à montrer et projet à déposer sur gitea(commit à chaque niveau qui fonctionne) :
- niveau 1(5 points) : affichage des clients concernés par les rdv du jour
- niveau 2(10 points) : mise à jour des clients dans la base de données côté client(android) - contrôle avec l'affichage des clients
- niveau 3(15 points) : traitement des rdv avec mise à jour des interventions dans la base de données côté client(android) - contrôle avec l'affichage des interventions
- niveau 4(20 points) : exportation des interventions sur le serveur(éventuellement nouvelles ou modifiées)