I. Vue globale▲
L'activité principale appelle l'activité de Login et attend le résultat. Si cette dernière répond et les identifiants sont corrects, alors la fonction startup() sera appelée et la textView affichera les identifiants de l'utilisateur connecté.
II. C'est parti▲
II-A. Création de la base de données▲
Tout d'abord créons la base de données. Voici le script :
-- phpMyAdmin SQL Dump
-- version 2.6.4-pl4
-- http://www.phpmyadmin.net
--
-- Host: localhost
--
-- --------------------------------------------------------
--
-- Création Table `auth_table`
--
CREATE
TABLE
IF
NOT
EXISTS
auth_table (
user_id int
(
10
)
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
username varchar
(
20
)
NOT
NULL
DEFAULT
''
,
password
varchar
(
32
)
NOT
NULL
DEFAULT
''
,
PRIMARY
KEY
(
user_id)
,
UNIQUE
KEY
username (
username)
)
TYPE
=
InnoDB ;
--
-- Insertion Table `auth_table`
--
INSERT
INTO
auth_table (
username, password
)
VALUES
(
'test'
, MD5
(
'pass'
))
;
II-B. Création du script PHP▲
La communication avec la base de données se fait via un script en PHP situé sur votre serveur.
Vous avez donc compris que notre application va communiquer avec le script PHP afin de savoir si l'authentification est correcte.
Voici le script PHP :
<?php
unset($_GET
);
if
( isset($_POST
[
'username'
]
) &&
isset($_POST
[
'password'
]
) ) {
echo '<?xml version="1.0"?>'
.
"
\n
"
;
echo "<login>
\n
"
;
// host doit être remplacé par le serveur de la base de données.
// user représente le nom d'utilisateur de la base de données.
// pass est le mot de passe pour accéder à cette base de données avec cette
// utilisateur.
if
(!@
mysql_connect('host'
,
'user'
,
'pass'
)) {
error
(1
);
}
// database représente le nom d ela base de données
if
(!
mysql_select_db('database'
)) {
error
(2
);
}
if
(get_magic_quotes_gpc()) {
$login
=
stripslashes($_POST
[
'username'
]
);
$pass
=
stripslashes($_POST
[
'password'
]
);
}
else
{
$login
=
$_POST
[
'username'
];
$pass
=
$_POST
[
'password'
];
}
unset($_POST
);
$kid
=
login($login
,
$pass
);
if
($kid
==
-
1
) {
error
(3
);
}
else
{
printf(' <user id="%d"/>'
.
"
\n
"
,
$kid
);
}
echo "</login>"
;
}
function
error
($ec
) {
printf(' <error value="%d"/>'
.
"
\n
"
.
'</login>'
,
$ec
);
die();
}
function
login($login
,
$pass
) {
$select
=
"
SELECT user_id
FROM auth_table
WHERE username = '%s' AND password = '%s'
"
;
$fixedlogin
=
mysql_real_escape_string($login
);
$fixedpass
=
mysql_real_escape_string($pass
);
$query
=
sprintf($select
,
$fixedlogin
,
$fixedpass
);
$result
=
mysql_query($query
);
if
(mysql_num_rows($result
) !=
1
) {
return
-
1
;
}
$row
=
mysql_fetch_row($result
);
return
$row
[
0
];
}
?>
II-C. Création de la vue▲
Ceci étant fait, créons la vue principale (main.xml).
La vue ressemblera à ceci :
Voici le code :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
orientation
=
"vertical"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"fill_parent"
android
:
gravity
=
"center"
>
<TextView
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Username"
/>
<EditText
android
:
id
=
"@+id/username"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
singleLine
=
"true"
android
:
fadingEdge
=
"horizontal"
android
:
layout_marginBottom
=
"20dip"
/>
<TextView
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Password"
/>
<EditText
android
:
id
=
"@+id/password"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
password
=
"true"
android
:
singleLine
=
"true"
android
:
fadingEdge
=
"horizontal"
/>
<LinearLayout
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
orientation
=
"vertical"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"fill_parent"
android
:
gravity
=
"bottom"
>
<Button
android
:
id
=
"@+id/okbutton"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Login"
/>
<Button
android
:
id
=
"@+id/cancelbutton"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"Cancel"
/>
</LinearLayout>
</LinearLayout>
II-D. Activité principale▲
Le code de la page principale est plutôt simple.
En effet, il appelle la page de Login et traite la réponse de cette dernière dans la fonction onActivityResult.
Si l'authentification est correcte, la fonction startup() est appelée.
Voici le code :
package
de.demo.main;
import
android.app.Activity;
import
android.content.Intent;
import
android.os.Bundle;
import
android.widget.TextView;
import
de.demo.login.Login;
public
class
Main extends
Activity
{
private
TextView tv;
public
static
final
int
RESULT_Main =
1
;
public
void
onCreate
(
Bundle icicle)
{
super
.onCreate
(
icicle);
//Appel de la page de Login
startActivityForResult
(
new
Intent
(
Main.this
, Login.class
), RESULT_Main);
tv =
new
TextView
(
this
);
setContentView
(
tv);
}
private
void
startup
(
Intent i)
{
// Récupère l'identifiant
int
user =
i.getIntExtra
(
"userid"
,-
1
);
//Affiche les identifiants de l'utilisateur
tv.setText
(
"UserID: "
+
String.valueOf
(
user)+
" logged in"
);
}
protected
void
onActivityResult
(
int
requestCode, int
resultCode, Intent data)
{
if
(
requestCode ==
RESULT_Main &&
resultCode ==
RESULT_CANCELED)
finish
(
);
else
startup
(
data);
}
}
II-E. Activité secondaire - Login▲
L'activité Login est plus compliquée car il faut communiquer avec le script PHP une fois que les identifiants sont entrés et que l'utilisateur clique sur le bouton OK.
Voici le code commenté :
package
de.demo.login;
import
java.io.IOException;
import
java.io.InputStream;
import
java.security.MessageDigest;
import
java.security.NoSuchAlgorithmException;
import
java.util.ArrayList;
import
java.util.List;
import
javax.xml.parsers.ParserConfigurationException;
import
javax.xml.parsers.SAXParser;
import
javax.xml.parsers.SAXParserFactory;
import
org.apache.http.HttpEntity;
import
org.apache.http.HttpResponse;
import
org.apache.http.NameValuePair;
import
org.apache.http.client.entity.UrlEncodedFormEntity;
import
org.apache.http.client.methods.HttpPost;
import
org.apache.http.impl.client.DefaultHttpClient;
import
org.apache.http.message.BasicNameValuePair;
import
org.apache.http.params.HttpConnectionParams;
import
org.apache.http.protocol.HTTP;
import
org.xml.sax.Attributes;
import
org.xml.sax.InputSource;
import
org.xml.sax.SAXException;
import
org.xml.sax.XMLReader;
import
org.xml.sax.helpers.DefaultHandler;
import
android.app.Activity;
import
android.app.AlertDialog;
import
android.app.ProgressDialog;
import
android.content.Intent;
import
android.os.Bundle;
import
android.os.Looper;
import
android.view.View;
import
android.widget.Button;
import
android.widget.EditText;
import
de.demo.main.R;
public
class
Login extends
Activity
{
// Lien vers votre page php sur votre serveur
private
static
final
String UPDATE_URL =
"http://paddesite.pa.ohost.de/login.php"
;
public
ProgressDialog progressDialog;
private
EditText UserEditText;
private
EditText PassEditText;
public
void
onCreate
(
Bundle savedInstanceState)
{
super
.onCreate
(
savedInstanceState);
setContentView
(
R.layout.main);
// initialisation d'une progress bar
progressDialog =
new
ProgressDialog
(
this
);
progressDialog.setMessage
(
"Please wait..."
);
progressDialog.setIndeterminate
(
true
);
progressDialog.setCancelable
(
false
);
// Récupération des éléments de la vue définis dans le xml
UserEditText =
(
EditText) findViewById
(
R.id.username);
PassEditText =
(
EditText) findViewById
(
R.id.password);
Button button =
(
Button) findViewById
(
R.id.okbutton);
// Définition du listener du bouton
button.setOnClickListener
(
new
View.OnClickListener
(
)
{
public
void
onClick
(
View v)
{
int
usersize =
UserEditText.getText
(
).length
(
);
int
passsize =
PassEditText.getText
(
).length
(
);
// si les deux champs sont remplis
if
(
usersize >
0
&&
passsize >
0
)
{
progressDialog.show
(
);
String user =
UserEditText.getText
(
).toString
(
);
String pass =
PassEditText.getText
(
).toString
(
);
// On appelle la fonction doLogin qui va communiquer avec le PHP
doLogin
(
user, pass);
}
else
createDialog
(
"Error"
, "Please enter Username and Password"
);
}
}
);
button =
(
Button) findViewById
(
R.id.cancelbutton);
// Création du listener du bouton cancel (on sort de l'appli)
button.setOnClickListener
(
new
View.OnClickListener
(
)
{
public
void
onClick
(
View v)
{
quit
(
false
, null
);
}
}
);
}
private
void
quit
(
boolean
success, Intent i)
{
// On envoie un résultat qui va permettre de quitter l'appli
setResult
((
success) ? Activity.RESULT_OK : Activity.RESULT_CANCELED, i);
finish
(
);
}
private
void
createDialog
(
String title, String text)
{
// Création d'une popup affichant un message
AlertDialog ad =
new
AlertDialog.Builder
(
this
)
.setPositiveButton
(
"Ok"
, null
).setTitle
(
title).setMessage
(
text)
.create
(
);
ad.show
(
);
}
private
void
doLogin
(
final
String login, final
String pass)
{
final
String pw =
md5
(
pass);
// Création d'un thread
Thread t =
new
Thread
(
)
{
public
void
run
(
)
{
Looper.prepare
(
);
// On se connecte au serveur afin de communiquer avec le PHP
DefaultHttpClient client =
new
DefaultHttpClient
(
);
HttpConnectionParams.setConnectionTimeout
(
client.getParams
(
), 15000
);
HttpResponse response;
HttpEntity entity;
try
{
// On établit un lien avec le script PHP
HttpPost post =
new
HttpPost
(
UPDATE_URL);
List<
NameValuePair>
nvps =
new
ArrayList<
NameValuePair>(
);
nvps.add
(
new
BasicNameValuePair
(
"username"
, login));
nvps.add
(
new
BasicNameValuePair
(
"password"
, pw));
post.setHeader
(
"Content-Type"
, "application/x-www-form-urlencoded"
);
// On passe les paramètres login et password qui vont être récupérés
// par le script PHP en post
post.setEntity
(
new
UrlEncodedFormEntity
(
nvps, HTTP.UTF_8));
// On récupère le résultat du script
response =
client.execute
(
post);
entity =
response.getEntity
(
);
InputStream is =
entity.getContent
(
);
// On appelle une fonction définie plus bas pour traduire la réponse
read
(
is);
is.close
(
);
if
(
entity !=
null
)
entity.consumeContent
(
);
}
catch
(
Exception e)
{
progressDialog.dismiss
(
);
createDialog
(
"Error"
, "Couldn't establish a connection"
);
}
Looper.loop
(
);
}
}
;
t.start
(
);
}
private
void
read
(
InputStream in)
{
// On traduit le résultat d'un flux
SAXParserFactory spf =
SAXParserFactory.newInstance
(
);
SAXParser sp;
try
{
sp =
spf.newSAXParser
(
);
XMLReader xr =
sp.getXMLReader
(
);
// Cette classe est définie plus bas
LoginContentHandler uch =
new
LoginContentHandler
(
);
xr.setContentHandler
(
uch);
xr.parse
(
new
InputSource
(
in));
}
catch
(
ParserConfigurationException e)
{
}
catch
(
SAXException e)
{
}
catch
(
IOException e)
{
}
}
private
String md5
(
String in)
{
MessageDigest digest;
try
{
digest =
MessageDigest.getInstance
(
"MD5"
);
digest.reset
(
);
digest.update
(
in.getBytes
(
));
byte
[] a =
digest.digest
(
);
int
len =
a.length;
StringBuilder sb =
new
StringBuilder
(
len <<
1
);
for
(
int
i =
0
; i <
len; i++
)
{
sb.append
(
Character.forDigit
((
a[i] &
0xf0
) >>
4
, 16
));
sb.append
(
Character.forDigit
(
a[i] &
0x0f
, 16
));
}
return
sb.toString
(
);
}
catch
(
NoSuchAlgorithmException e)
{
e.printStackTrace
(
);
}
return
null
;
}
private
class
LoginContentHandler extends
DefaultHandler
{
// Classe traitant le message de retour du script PHP
private
boolean
in_loginTag =
false
;
private
int
userID;
private
boolean
error_occured =
false
;
public
void
startElement
(
String n, String l, String q, Attributes a)
throws
SAXException
{
if
(
l ==
"login"
)
in_loginTag =
true
;
if
(
l ==
"error"
)
{
progressDialog.dismiss
(
);
switch
(
Integer.parseInt
(
a.getValue
(
"value"
))
{
case
1
:
createDialog
(
"Error"
, "Couldn't connect to Database"
);
break
;
case
2
:
createDialog
(
"Error"
, "Error in Database: Table missing"
);
break
;
case
3
:
createDialog
(
"Error"
, "Invalid username and/or password"
);
break
;
}
error_occured =
true
;
}
if
(
l ==
"user"
&&
in_loginTag &&
a.getValue
(
"id"
) !=
""
)
// Dans le cas où tout se passe bien on récupère l'ID de l'utilisateur
userID =
Integer.parseInt
(
a.getValue
(
"id"
));
}
public
void
endElement
(
String n, String l, String q) throws
SAXException
{
// on renvoie l'id si tout est ok
if
(
l ==
"login"
)
{
in_loginTag =
false
;
if
(!
error_occured)
{
progressDialog.dismiss
(
);
Intent i =
new
Intent
(
);
i.putExtra
(
"userid"
, userID);
quit
(
true
, i);
}
}
}
public
void
characters
(
char
ch[], int
start, int
length)
{
}
public
void
startDocument
(
) throws
SAXException
{
}
public
void
endDocument
(
) throws
SAXException
{
}
}
}
II-F. Manifest▲
Bon tout est fait il manque juste le manifest et vous pourrez tester votre application d'authentification !
Voici le manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
package
=
"de.demo.main"
android
:
versionCode
=
"1"
android
:
versionName
=
"1.0.0"
>
<application
android
:
icon
=
"@drawable/icon"
android
:
label
=
"LoginDemo"
>
<activity
android
:
name
=
"de.demo.main.Main"
android
:
label
=
"LoginDemo"
>
<intent-filter>
<action
android
:
name
=
"android.intent.action.MAIN"
/>
<category
android
:
name
=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<activity
android
:
name
=
"de.demo.login.Login"
android
:
label
=
"LoginDemo"
>
<intent-filter>
<action
android
:
name
=
"android.intent.action.VIEW"
/>
<category
android
:
name
=
"android.intent.category.DEFAULT"
/>
</intent-filter>
</activity>
</application>
<uses-permission
android
:
name
=
"android.permission.INTERNET"
></uses-permission>
</manifest>
III. Conclusion▲
Et voilà, c'est terminé !
Merci d'avoir suivi ce premier tutoriel et à bientôt ;).
NB : Le code est récupéré du site anddev.org. Les commentaires y ont été ajoutés.
IV. Remerciements▲
Je tiens à remercier tout particulièrement ClaudeLeloupClaudeLeloup pour sa correction orthographique de grande qualité. Ainsi que FeanorinFeanorin pour les améliorations apportées à ce tutoriel.