IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

une application pour s'authentifier en asynk task


Sujet :

Android

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Territoire de Belfort (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 2
    Points : 3
    Points
    3
    Par défaut une application pour s'authentifier en asynk task
    Je suis un grand novice en android et je suis en train de faire une petite application pour se loger. J'ai trouvé un bon tutoriel ici, mais il ne fonctionne pas parce que je dois le faire en asynk task.J'ai essayé de faire quelques modifications mais rien ne fonctionne .voilà mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    import org.json.JSONException;
    import org.json.JSONObject;
     
    import android.app.Activity;
     
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
     
    import android.widget.TextView;
     
    import com.example.androidhive.library.DatabaseHandler;
    import com.example.androidhive.library.UserFunctions;
     
     
    public class LoginActivity extends Activity {
    	Button btnLogin;
    	Button btnLinkToRegister;
    	EditText inputEmail;
    	EditText inputPassword;
    	TextView loginErrorMsg;
     
    	// JSON Response node names
    	private static String KEY_SUCCESS = "success";
    	private static String KEY_ERROR = "error";
    	private static String KEY_ERROR_MSG = "error_msg";
    	private static String KEY_UID = "uid";
    	private static String KEY_NAME = "name";
    	private static String KEY_EMAIL = "email";
    	private static String KEY_CREATED_AT = "created_at";
     
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.login);
     
    		// Importing all assets like buttons, text fields
    		inputEmail = (EditText) findViewById(R.id.loginEmail);
    		inputPassword = (EditText) findViewById(R.id.loginPassword);
    		btnLogin = (Button) findViewById(R.id.btnLogin);
    		btnLinkToRegister = (Button) findViewById(R.id.btnLinkToRegisterScreen);
    		loginErrorMsg = (TextView) findViewById(R.id.login_error);
     
    		// Login button Click Event
    		btnLogin.setOnClickListener(new View.OnClickListener() {
     
    			public void onClick(View view) {
    				new LogTask().execute(); 	
    			}
     
    		});
     
    		// Link to Register Screen
    		btnLinkToRegister.setOnClickListener(new View.OnClickListener() {
     
    			public void onClick(View view) {
    				Intent i = new Intent(getApplicationContext(),RegisterActivity.class);
    				startActivity(i);
    				finish();
    			}
    		});
    	}
     
    	private class LogTask extends AsyncTask<String, String, String> {
     
     
     
     
    		protected String doInBackground(String... args) {
    			String email = inputEmail.getText().toString();
    		    String password = inputPassword.getText().toString();
    		    UserFunctions userFunction = new UserFunctions();
    		    Log.d("Button", "Login");
    		    JSONObject json = userFunction.loginUser(email, password);
     
    		    // check for login response
    		    try {
    		        if (json.getString(KEY_SUCCESS) != null) {
    		            loginErrorMsg.setText("");
    		            String res = json.getString(KEY_SUCCESS); 
    		            if(Integer.parseInt(res) == 1){
    		                // user successfully logged in
    		                // Store user details in SQLite Database
    		                DatabaseHandler db = new DatabaseHandler(getApplicationContext());
    		                JSONObject json_user = json.getJSONObject("user");
     
    		                // Clear all previous data in database
    		                userFunction.logoutUser(getApplicationContext());
    		                db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));                        
     
     
    		            }else{
    		                // Error in login
    		                return null;
    		            }
    		        }
    		    } catch (JSONException e) {
    		        e.printStackTrace();
    		    }
     
    		    return "done";
    		}
     
     
    		protected void onPostExecute(String file_url) {
     
    			if(file_url==null) {
    	              loginErrorMsg.setText("Incorrect username/password");
    	       } else if(file_url.equals("done")) {
    	              Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
    	              dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    	              startActivity(dashboard);
    	              finish();
    	       }
     
    		}
     
    	}
    }

  2. #2
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Bonjour,

    je vais essayer de commenter le code tel que je le ferai avec mes "élèves":

    Jusqu'à btnLogin.setOnClickListener tout va bien.. rien à dire... sauf éventuellement passer les membres en "private", et virer les "constantes" qui n'ont rien à faire là (elles dépendent de la tâche, pas de l'activité). Mais c'est mineur.

    Bon... commençons par le début... le OnClick... Déjà le onClick lance une action "métier" (démarrer là tâche de login) en plus:
    1. Il n'y a aucun paramètre de passé à cette tâche.
    2. On ne signale pas à l'utilisateur qu'on fait quelque chose (ce qui peut être pris par l'utilisateur pour "l'application de répond plus").
    Donc déjà, remplacer le code par un truc genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                    // Login button Click Event
    		btnLogin.setOnClickListener(new View.OnClickListener() {
    			public void onClick(View view) {
    				LoginActivity.this.onStartLogin(); 	
    			}
    		});
    Ensuite créer une fonction "onStartLogin()":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    public void onStartLogin()
    {
         String email = inputEmail.getText().toString();
         String password = inputPassword.getText().toString();
         // déjà gérer le cas évident ou il manque un truc ici !
         if (email.length() > 0 && password.length() > 0)
             showProgressDialog();
             new LoginTask().execute(login,password);
         }
    }
    public   void showProgressDialog()
    {
         // TODO: afficher une boite de dialogue avec une spinning bar
    }
    public   void hideProgressDialog()
    {
         // TODO: "finir" la boite de dialogue créée dans 'show'
    }
    public   void onLoginSuccess(String file_url)
    {
         hideProgressDialog();
         Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
         dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         startActivity(dashboard);
         finish();
    }
    public   void onLoginFailed(String err_msg)
    {
         this.loginErrorMsg.setText(err_msg);
         hideProgressDialog();
    }
    Alors, pourquoi une progress-dialog ? Pour d'une part montrer à l'utilisateur qu'on fait quelque chose (l'appli n'est pas dans les choux), et d'autre part, l'empêcher d'aller modifier son texte après coup !
    D'autre part on a créé des fonctions additionelles pour permettre à la tâche de signaler à l'activité le résultat du login (ce sont les fonctions onLoginSuccess et onLoginFailed)...

    Comme toujours: il faut séparer les rôles... Comme tout objet métier, une tâche de background ne devrait jamais avoir à connaitre l'interface.

    Ensuite, attelons nous à la tâche... Déjà on va l'appeler "LoginTask" (log = écrire du log, Login = s'authentifier). Elle n'a plus de référence nécessaire sur l'interface, elle peut se concentrer sur le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         class LoginTask extends AsyncTask<String, String, String> {
               // un petit rajout au passage histoire de garder une trace des erreurs !
               private String error_message = null;
     
    		protected String doInBackground(String... args) {
    		    String email = args[0];
    		    String password = args[1];
    		    Log.d("LoginTask", "Démarrage...");
    Ensuite viennent deux lignes très étonnantes....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    		    UserFunctions userFunction = new UserFunctions();
    		    JSONObject json = userFunction.loginUser(email, password);
    Ces fonctions n'envoient pas d'exception ? C'est étonnant !
    Que se passe-t-il si il n'y a pas de réseau ? Si le serveur ne répond pas ? Si il renvoit un 404 un 500 ?
    A la lecture du code, la post-condition de la fonction "loginUser" est le retour d'un objet json... hors dans tous les cas cité avant, elle ne le pourra physiquement pas (et donc devrait lever une exception !)...

    Donc j'aimerai bien voir un peu ces "UserFunctions"... Quelque chose me dit qu'elles ne sont pas bonnes.
    C'est d'autant plus dommage que le reste est bien protégé contre les exceptions (enfin ... presque).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    		    // check for login response
    		    try {
    		        if (json.getString(KEY_SUCCESS) != null) {
    		            String res = json.getString(KEY_SUCCESS); 
    		            if(Integer.parseInt(res) == 1){
    		                // user successfully logged in
    		                // Store user details in SQLite Database
    		                DatabaseHandler db = new DatabaseHandler(getApplicationContext());
    		                JSONObject json_user = json.getJSONObject("user");
     
    		                // Clear all previous data in database
    		                userFunction.logoutUser(getApplicationContext());
    		                db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
    Ok... maintenant viens l'autre cas de if(Integer.parseInt(res) == 1)
    Et là... on fait juste un "return null" donc on ne dit à personne que ca a foiré quoi !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          	                    }else{
    		                this.error_message = "Login error";
    		            }
    		        }
    Et que se passe-t-il si n'y a pas de string 'success' ? on quitte en disant "done" ? Et si la clé 'success' ne contient pas un entier ? (NumberFormatException => c'est toute la tâche qui va s'arrêter sans le signaler à personne).
    Tout cela me semble bien contradictoire... Ou une fonction réussie (et renvoie une valeur prédéfinie) ou pas (et elle lève alors une exception). On ne choisit pas un cas ou un autre au petit bonheur la chance...
    D'autant qu'en suite on fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
          	    } catch (JSONException e) {
    		        e.printStackTrace();
    		    }
     
    		    return "done";
    		}
    Ce qui veut dire que si une exception (bon ici limitée aux exceptions JSON) a eu lieu (le code "protégé" par le try n'a pas remplit son office), on n'en fait rien du tout, et on retourne "done" comme si de rien n'était !
    Pire encore, on la fait disparaître dans le System.out !

    Tout le code du doInBackground devrait donc ressembler à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    		protected String doInBackground(String... args) {
    		    String email = args[0];
    		    String password = args[1];
    		    Log.d("LoginTask", "Démarrage...");
                        try {
    		        UserFunctions userFunction = new UserFunctions();
    		        JSONObject json = userFunction.loginUser(email, password);
                            if (json.getInt(KEY_SUCCESS) == 1) {
                                DatabaseHandler db = new DatabaseHandler(getApplicationContext());
    		            JSONObject json_user = json.getJSONObject("user");
     
    		            // Clear all previous data in database ??
    		            userFunction.logoutUser(LoginActivity.this);
    		            db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));             
                            } else {
                                this.error_message = "Invalid login";
                            }
                            return "done";
                        } catch (Exception ex) {
                            // oui oui, on catch tout !
                            Log.w("LoginTask","Failed to login",ex);
                            this.error_message = ex.getMessage();
                            return null;
                        }
                     }
    Ensuite on finit par le PostExecute... c'est lui qui est chargé de prévenir l'activité que le login a fini (en bien ou en mal)... Mais pas à lui d'afficher quoique ce soit !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    		protected void onPostExecute(String file_url) {
                         if (this.error_message == null)
                               LoginActivity.this.onLoginSuccess(file_url);
                         else
                               LoginActivity.this.onLoginFailure(this.error_message);
                    }
    Là encore, on vire tout ce qui est "UI logic" de la tâche...
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Territoire de Belfort (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Re,

    Vraiment un grand merci pour votre aide, votre solution marche nickel et vos explications étaient super intéressantes et instructives

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2015
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Les explications sont très claire , mais par contre j'aurais une petite question , il doit normalement avoir une URL avec laquelle s'effectuera l'échanges des données afin de s'authentifier non ? parce que je ne la trouve pas dans le code. Et merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Console] developper une application pour xbox
    Par fan dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 03/02/2011, 13h08
  2. Réponses: 5
    Dernier message: 17/11/2009, 17h17
  3. Réponses: 1
    Dernier message: 06/09/2006, 10h47
  4. [VB.net] Compiler une application pour smartphone
    Par UNi[FR] dans le forum Windows Mobile
    Réponses: 1
    Dernier message: 28/08/2006, 10h49
  5. [VS.Net] créer une application pour le mobile
    Par rudhf dans le forum Visual Studio
    Réponses: 4
    Dernier message: 20/05/2006, 13h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo