Connexion à une base de données [Résolu/Fermé]

Signaler
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020
-
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020
-
Bonjour,

Alors... j'ai fait pas mal de recherches sur Google pour trouver un tutoriel complet qui explique comment connecter une appli Android à une base de données externe. Mais impossible de trouver ce que je cherche. J'ai vu des tutoriels sur Retrofit, OkHttp, Gson... mais ces tutoriels ne sont pas complets. Ils expliquent juste comment extraire des données précises.

Ce que j'aimerais faire par exemple : Un utilisateur s'inscrit sur l'appli, il remplit des champs dans un formulaire, et lorsqu'il clique sur un bouton VALIDER les informations sont insérées dans la base de données.

Ou encore : Un utilisateur déjà inscrit se connecte, au clique d'un bouton l'appli vérifie si l'utilisateur existe dans la base de données, en fonction de la réponse il est redirigé.

Alors si j'ai bien compris, l'appli fait appel un fichier PHP (fichier à mettre dans l'appli ? dans quel répertoire ? ou sur le serveur de la BDD ?), le fichier PHP se connecte à la BDD (requête à faire dans un XML ou dans un second fichier PHP ?), le fichier PHP renvoie une réponse sous format JSON, Android traite les données JSON. J'ai tout bien comprire ?

Donc je recherche un tutoriel capable de m'expliquer clairement comment faire cela et surtout, si possible, comment adapter le code au clique d'un bouton dans l'appli. Merci d'avance.

6 réponses

Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020

Bon, j'ai trouvé un tutoriel, et j'ai commencé à écrire. En gros j'ai déjà écrit le code pour conditionner l'action au clique du bouton, avec l'intégration des données utilisateurs dans le lien de communication avec la base de données, l'envoie des données à la base au clique. Ci-dessous ce que j'ai déjà fait :
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;

//!\\ Déclaration de la classe. //!\\
/* Déclaration du caractère publique (visible) de cette classe avec l'attribut "public". */
public class Start extends AppCompatActivity
{
    //!\\ Communication (création d'une chaîne "String" pour communiquer des données utilisateur à la base de données). //!\\
    /* Création d'une méthode de classe "String" pour y intégrer des données utilisateur. */
    /* Déclaration du caractère privé (invisible) de cette méthode avec l'attribut "private". */
    /* Déclaration du caractère statique (appel direct de la méthode depuis n'importe où) de cette méthode avec l'attribut "static". */
    /* Déclaration du caractère invariable (non modifiable) de cette méthode avec l'attribut "final". */
    /* Attribution de l'identifiant "UPDATE_URL" à cette méthode. */
    /* Appel de l'Url concernée par la communication des données utilisateur. */
    private static final String	UPDATE_URL = "http://hello-lets-ride.fr/connexion.php";
    /* Création d'une méthode de classe "ProgressDialog" pour initier une barre de chargement. */
    /* Déclaration du caractère publique (visible) de cette méthode avec l'attribut "public". */
    /* Attribution de l'identifiant "progressDialog" à cette méthode. */
    public ProgressDialog progressDialog;
    /* Création d'une méthode de classe "EditText" pour récupérer le pseudo de l'utilisateur. */
    /* Déclaration du caractère privé (invisible) de cette méthode avec l'attribut "private". */
    /* Attribution de l'identifiant "UserEditText" à cette méthode. */
    private EditText UserEditText;
    /* Création d'une méthode de classe "EditText" pour récupérer le mot de passe de l'utilisateur. */
    /* Déclaration du caractère privé (invisible) de cette méthode avec l'attribut "private". */
    /* Attribution de l'identifiant "PassEditText" à cette méthode. */
    private EditText PassEditText;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        //!\\ Affichage de l'activité de la classe parente. //!\\
        setContentView(R.layout.start_activity);

        //!\\ Animation (apparition de l'activité). //!\\
        /* Création d'une méthode de classe "Animation" pour utiliser une animation. */
        /* Déclaration du caractère invariable (non modifiable) de cette méthode avec l'attribut "final". */
        /* Attribution de l'identifiant "startActivity_animation" à cette méthode. */
        /* Appel de l'animation du fichier "apparition.xml". */
        final Animation startActivity_animation = AnimationUtils.loadAnimation(this, R.anim.apparition);
        /* Création d'une méthode de classe "View" pour visualiser l'animation. */
        /* Déclaration du caractère invariable (non modifiable) de cette méthode avec l'attribut "final". */
        /* Attribution de l'identifiant "animationStartActivity_affichage" à cette méthode. */
        /* Appel de la vue "startActivity_conteneurScrollView" concernée par l'animation. */
        final View animationStartActivity_affichage = findViewById(R.id.startActivity_conteneurScrollView);
        /* Association de l'animation à la vue. */
        startActivity_animation.setFillAfter(true);
        /* Lancement de l'animation. */
        animationStartActivity_affichage.startAnimation(startActivity_animation);

        //!\\ Préparation de la page d'attente destinée à l'utilisateur. //!\\
        /* Initialisation de la barre de chargement déclarée dans le parent. */
        progressDialog = new ProgressDialog(this);
        /* Création d'une infobulle à l'attention de l'utilisateur. */
        progressDialog.setMessage("Merci de bien vouloir patienter...");
        progressDialog.setIndeterminate(true);
        progressDialog.setCancelable(false);
        
        /* Appel du champs "startActivity_blocPseudo_champs" de l'activité pour pouvoir récupérer le pseudo de l'utilisateur. */
        /* Association du champs à la méthode "UserEditText" déclarée dans le parent. */
        UserEditText = (EditText) findViewById(R.id.startActivity_blocPseudo_champs);
        /* Appel du champs "startActivity_blocMotDePasse_champs" de l'activité pour pouvoir récupérer le mot de passe de l'utilisateur. */
        /* Association du champs à la méthode "PassEditText" déclarée dans le parent. */
        PassEditText = (EditText) findViewById(R.id.startActivity_blocMotDePasse_champs);

        //!\\ Translation (passage d'une classe à l'autre au clique d'un bouton). //!\\
        /* Création d'une méthode de classe "Button" pour initier une action au clique. */
        /* Déclaration du caractère invariable (non modifiable) de cette méthode avec l'attribut "final". */
        /* Attribution de l'identifiant "startActivity_boutonConnexion" à cette méthode. */
        /* Appel du bouton "startActivity_boutonConnexion" pour écouter son état (clique). */
        final Button startActivity_boutonConnexion = (Button) findViewById(R.id.startActivity_boutonConnexion);
        /* Déclaration de ce qu'il doit se passer au clique du bouton. */
        startActivity_boutonConnexion.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                /* Déclaration de ce qu'il doit se passer si les deux champs sont remplis correctement. */
                int usersize = UserEditText.getText().length();
                int passsize = PassEditText.getText().length();
                if (usersize > 0 && passsize > 0)
                {
                    //!\\ Communication des données utilisateur à la base de données. //!\\
                    /* Affichage de la page d'attente préparée dans le parent. */
                    progressDialog.show();
                    /* Création d'une méthode de classe "String" pour y intégrer le pseudo de l'utilisateur. */
                    /* Attribution de l'identifiant "user" à cette méthode. */
                    /* Intégration du pseudo dans la chaîne. */
                    String user = UserEditText.getText().toString();
                    /* Création d'une méthode de classe "String" pour y intégrer le mot de passe de l'utilisateur. */
                    /* Attribution de l'identifiant "pass" à cette méthode. */
                    /* Intégration du pseudo dans la chaîne. */
                    String pass = PassEditText.getText().toString();
                    /* Transfert des données avec la méthode "doLogin". */
                    doLogin(user, pass);
                }
                /* Sinon... */
                else
                {
                    //!\\ Affichage d'une infobulle à l'utilisateur. //!\\
                    createDialog("Erreur", "L'un des champs est vide. Merci de bien vouloir recommencer.");
                }
                
                /* Création d'une méthode de classe "Intent" pour créer un lien entre les deux classes. */
                /* Attribution de l'identifiant "lien_Start_NOM_DE_LA_CLASSE" à cette méthode. */
                /* Établissement du lien entre "Start.java" et "NOM_DE_LA_CLASSE.java". */
                Intent lien_Start_NOM_DE_LA_CLASSE = new Intent(Start.this, NOM_DE_LA_CLASSE.class);
                /* Lancement de la translation. */
                startActivity(lien_Start_NOM_DE_LA_CLASSE);
            }
        });

        //!\\ Translation (passage d'une classe à l'autre au clique d'un bouton). //!\\
        /* Création d'une méthode de classe "Button" pour initier une action au clique. */
        /* Déclaration du caractère invariable (non modifiable) de cette méthode avec l'attribut "final". */
        /* Attribution de l'identifiant "startActivity_boutonInscription" à cette méthode. */
        /* Appel du bouton "startActivity_boutonInscription" pour écouter son état (clique). */
        final Button startActivity_boutonInscription = (Button) findViewById(R.id.startActivity_boutonInscription);
        /* Déclaration de ce qu'il doit se passer au clique du bouton. */
        startActivity_boutonInscription.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                /* Création d'une méthode de classe "Intent" pour créer un lien entre les deux classes. */
                /* Attribution de l'identifiant "lien_Start_NOM_DE_LA_CLASSE" à cette méthode. */
                /* Établissement du lien entre "Start.java" et "NOM_DE_LA_CLASSE.java". */
                Intent lien_Start_NOM_DE_LA_CLASSE = new Intent(Start.this, NOM_DE_LA_CLASSE.class);
                /* Lancement de la translation. */
                startActivity(lien_Start_NOM_DE_LA_CLASSE);
            }
        });
    }
}


Il y a beaucoup d'annotations mais c'est pour ne pas me perdre et essayer de comprendre le fonctionnement. D'ailleurs si vous remarquez qu'une annotation est fausse en rapport avec la compréhension du code n'hésitez pas. Ce serait bien si quelqu'un pouvait me dire si je suis sur la bonne voie.

Maintenant il me reste la partie retour serveur->client avec la récupération du résultat, le traitement JSON, puis trouver un moyen de conserver active la connexion de l'utilisateur... je crois que j'ai encore beaucoup de boulot. Et pourtant de l'extérieur l'action semble si simple quand on est à la place de l'utilisateur de l'appli.
Messages postés
14947
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
21 janvier 2021
3 026
Trop de commentaires tue le commentaire...
Je n'ai pas tout regarder (vraiment difficile avec tous ces commentaires) mais quelques remarques:
- bonne pratique de nommage: garder un lié de l'objet utilisé. Ici, Start doit être renommée
StartActivity
.
- je te conseille d'utiliser la lib ButterKnife pour supprimer les
findViewById()
et les
onClickListener()
.
-
private static final String
= définition d'une constante de type String.
- les variables membres sont généralement à mettre en
private
et non en
public
.
- "Création d'une méthode de classe" -> Non, pas pour les variables!
- Pour tester si une String est vide:
TextUtils.isEmpty(string)
.
- progressDialog n'est pas une infobulle. C'est un Loader
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020
>
Messages postés
14947
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
21 janvier 2021

Merci. J'ai trouvé un autre tuto : https://houssem-lahiani.blogspot.com/2016/04/android-et-les-bases-de-donnees.html Mais le problème de ce tuto, comme beaucoup d'autres, c'est que les auteurs ne commentent pas assez leurs codes alors que cela permettrait une meilleure compréhension. Parce que la plupart du temps ils disent de créer tel ou tel fichier et d'y copier / coller les codes. C'est un peu dommage parce que le but c'est quand même d'apprendre.
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020
>
Messages postés
14947
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
21 janvier 2021

Quand tu dis que les variables membres sont généralement à mettre en privée tu veux dire des variables "enfants" ?
Messages postés
14947
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
21 janvier 2021
3 026
A force de regarder 40 milles tutos, tu vas te perdre.
Pour accéder à une BDD centralisée sur un serveur depuis une app Android, il te faut:
- côté serveur
. une BDD
. des scripts de connexion à cette BDD et d'accès au données (en PHP ou tout autre langage serveur)
- côté mobile
. les urls des scripts serveur
. un moteur de requête type OkHttp
. un parser pour transformer tes réponses serveur en objets métier

Quand tu dis que les variables membres sont généralement à mettre en privée tu veux dire des variables "enfants" ?
Je vais dire non car "variable enfant" ne fait pas partie de la terminologie en programmation. On parle bien de membres

@+ 
Buno, Modo CS-CCM 
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai... 
The urgent is done, the impossible is underway. For miracles, provide for a delay...
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020

Ok merci. Je vais donc reprendre étape par étape avec ta liste.
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020

Salut,

Alors, j'ai trouvé un tutoriel sur PDO pour faire des requêtes SQL. Il semblerait que cette nouvelle méthode de requête soit de plus en plus privilégiée par rapport aux anciennes. Avec ce tutoriel qui, je le précise, n'est pas orienté développement Android mais plus développement web j'ai réalisé un premier jet pour le script PHP avec lequel mon appli communiquera. Mais comme le tutoriel est orienté web il faudra sûrement que je trouve comment l'adapter pour le développement Android. J'entends par là faire en sorte que les infos récupérées par le script soit renvoyé à l'appli. Pour l'instant le script traite tout en local malheureusement. Voici ce que j'ai écrit :
<?php
try // Connection à la base de données.
{
$bdd = new PDO('mysql:host=localhost;dbname=xxxxxxxxxx', 'xxxxxxxxxx', 'xxxxxxxxxx');
}
catch (Exception $erreur) // En cas d'erreur de connexion à la base de données.
{
die('Erreur de connection à la base de données. Merci de bien vouloir ré-essayer.' . $erreur->getMessage());
}

// Vérification de l'existence du pseudo et du mot de passe.
$requete = $bdd->prepare('SELECT COUNT(*) AS existence FROM utilisateurs WHERE pseudo = :pseudo AND password = :password');
$requete->bindValue(':pseudo', $_POST['pseudo'], PDO::PARAM_STR);
$requete->bindValue(':password', $_POST['password'], PDO::PARAM_STR);
$data = $requete->execute();
$requete->closeCursor();

// Si le pseudo et le mot de passe existent.
if($data['existence'] != 0)
{
echo 'Connection effectuée avec succès.';
}
// Si le pseudo ou/et le mot de passe n'existent pas.
else
{
echo 'Désolé mais les informations que vous avez renseigné n'existent pas. Merci de bien vouloir ré-essayer. Si vous êtes un nouvel utilisateur merci de bien vouloir vous inscrire.';
}
?>


J'espère être sur la bonne voie.
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020

P.S. : Lorsque l'utilisateur sera connecté, pour qu'il le reste tout au long de sa navigation il faudra sûrement que je mette en place une session, pour cela j'ai cru comprendre que je pouvais utiliser des
SharedPreferences
. Je me trompe ?
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020

J'enchaîne les posts. ^^ Bon, j'ai modifié un peu mon script PHP :
<?php
	try // Connection à la base de données.
	{
		$bdd = new PDO('mysql:host=localhost;dbname=', '', '');
	}
	catch (Exception $erreur) // En cas d'erreur de connexion à la base de données.
	{
		die('Erreur de connection à la base de données. Merci de bien vouloir ré-essayer.' . $erreur->getMessage());
	}

	// Vérification de l'existence du pseudo et du mot de passe.
	$requete = $bdd->prepare('SELECT COUNT(*) AS existence FROM utilisateurs WHERE pseudo = :pseudo AND password = :password');
	$requete->bindValue(':pseudo', $_POST['pseudo'], PDO::PARAM_STR);
	$requete->bindValue(':password', $_POST['password'], PDO::PARAM_STR);
	$data = $requete->execute();
	$requete->closeCursor();
	$output = $requete;
	 
	echo(json_encode($output));
?>
Messages postés
14947
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
21 janvier 2021
3 026
Entendons-nous bien. Ici, on va traiter du développement Android, donc côté mobile.
Pour la partie PHP, merci de poster dans le forum adéquat: https://forums.commentcamarche.net/forum/php-155
Messages postés
182
Date d'inscription
mardi 24 avril 2012
Statut
Membre
Dernière intervention
7 novembre 2020
>
Messages postés
14947
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
21 janvier 2021

C'est fait. Et quelqu'un m'aide. Je vais mettre ce sujet en résolu, j'en ferai un nouveau topic pour chaque étape. :-)