69
Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre 2013 Avertissement :

Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Embed Size (px)

Citation preview

Page 1: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur1

ConnectivitéOrienté clients/serveur TCP et Bluetooth

Notes de cours

jean-michel Douin, douin au cnam point frversion : 7 Novembre 2013

Avertissement :

Page 2: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur2

Bibliographie utilisée

http://developer.android.com/resources/index.html

http://developer.android.com/reference/android/os/AsyncTask.html

Un ensemble de tutoriels à lire

http://www.vogella.de/android.html

http://www.vogella.de/articles/AndroidPerformance/article.html

Page 3: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur3

Sommaire

• Clients et serveurs TCP– Un Client, une requête– Serveur TCP (HTTP,…)– Clients Bluetooth

• Annexes, cf. NFP121– Format XML,

• API SAX

– Format JSON• json.org

Page 4: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur4

Client et serveur

• Serveurs TCP

– Exemples

– Requête

Page 5: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur5

Serveurs

• En mode TCP

• Appels distants en mode TCP/IP– Point à point avec accusé de réception

– telnet, ftp, http, …

Page 6: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur6

URL …

• URL Uniform Resource Locator une adresse sur internet

– http://jfod.cnam.fr

– http le protocole

– //jfod.cnam.fr le nom de la ressource

– http://jfod.cnam.fr:8999/ds2438/mesures.html

Page 7: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur7

Exemples clients / serveurs

1. Le client s’adresse au serveur– Établit une connexion

2. Le serveur satisfait ses clients– Mode synchrone, analogue à l’appel d’une méthode locale

Client2 ServeurClient1

protocole

Client3

Page 8: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur8

Appels distants protocole « maison »

• Le contexte– Client Java, ou autres

– Serveur en java ou autre– maison : //serveur/….

Client2 serveurJVM

Client1JVM

maison

Client3

Page 9: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur9

Appels distants protocole http

• Le contexte– Client Java(application comme applette), ou autres– Un navigateur

– Serveur en java , ou autres• http: //serveur/index.html• Standard, universel …

Client2 serveurJVM

Client1JVM

http

unnavigateur

Page 10: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur10

Implémentation en Java

• Paquetage java.net

– Principales classes • ServerSocket• Socket• InetAddress• URLConnection• …

– Quelques lignes de sources suffisent …

Page 11: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur11

usage de java.net TCP/IP

• 2 classes essentielles Côté Serveur

– java.net.ServerSocket• Méthode accept() sur une instance de la classe ServerSocket

Côté Client

– java.net.Socket, java.net.SocketAddress• Envoi sur une instance de la classe Socket de données

ServeurJVM

Client1JVM

Page 12: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur12

Connexion / Principes

• Le Serveur attend une requête sur son port– ServerSocket server = new ServerSocket(port)– Socket socket = server.accept();

• Dès la connexion établie, – une instance de la classe Socket est engendrée sur un port temporaire

• Établir une connexion par le client est effectuée par – Socket s = new Socket(Serveur, port)

Serveur

JVM

Client1

JVM

port port

port

Page 13: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur13

2 exemples

• Serveur et client

1. Au protocole « maison »• Le serveur ne connaît que la commande « parle » et répond « bonjour »• Tout autre commande est ignorée !

2. Au protocole http• Seule la méthode GET /index.html HTTP1.0 est possible• Un sous-ensemble donc …

Page 14: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur14

Exemple 1

– Au protocole « maison »• Le serveur ne connaît que la commande « parle » et répond « bonjour »• Tout autre commande est ignorée !

– Client java ou autre

ServeurJVM

Client1JVM

maison: //serveurparle

bonjour

Page 15: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur15

Un serveur avec un protocole « maison »

public class Serveur{

public static void main(String[] args) throws Exception{ ServerSocket serveur = new ServerSocket(5000); while(true) { Socket socket = serveur.accept();

BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream()));

String cmd = in.readLine(); // parle !!! DataOutputStream out = new DataOutputStream( socket.getOutputStream()); if(cmd.equals("parle")){ out.write("bonjour\n".getBytes()); }else{ out.write("commande inconnue ?\n".getBytes()); } socket.close(); } } }

Page 16: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur16

Le client « maison »

public class Client{

public static void main(String[] args) throws Exception{

Socket socket = new Socket("vivaldi.cnam.fr", 5000);

DataOutputStream out= new DataOutputStream( socket.getOutputStream());

out.write(args[0].getBytes());

out.write("\n".getBytes());

BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream()));

System.out.println(in.readLine());

socket.close();

}

}

Page 17: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur17

Un client « maison », telnet

• telnet localhost 5000– parle // frappe sans écho

• petit outil utile : tcpview

Page 18: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur18

Exemple 2

• Le protocole HTTP– Les méthodes GET, POST, ….

• Mise en œuvre / démo– Usage d’un client telnet sur un site existant

– Une application Java cliente

– Un serveur en java

Page 19: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur19

Protocole HTTP

• HyperText Transfer Protocol– Au dessus de TCP

• Les Méthodes– GET /index.html HTTP/1.0– HEAD – POST

– PUT– DELETE– TRACE– CONNECT

– Voir http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Page 20: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur20

Côté serveur, méthode accept

ServerSocket listen = new ServerSocket(HTTP_PORT);

while(!stopped()){ try{ Socket socket = listen.accept(); handleRequest(socket); }catch(Exception e){ } }

listen.close();}

listen.accept() est bloquant : au moins un client.

Page 21: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur21

Exemple minimaliste !

• Un serveur Web au complet– Un seul client, une seule requête !

• Extrait de

Page 22: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur22

OneShot Httpd by Hendrik, j2se

public class OneShotHttpd { protected static File docRoot; public final static int HTTP_PORT = 8080;

public static void main(String argv[]){ try{ docRoot = new File("."); ServerSocket listen = new ServerSocket(HTTP_PORT); Socket client = listen.accept(); BufferedReader is = new BufferedReader(new

InputStreamReader(client.getInputStream())); DataOutputStream os = new DataOutputStream(client.getOutputStream()); String request = is.readLine(); StringTokenizer st = new StringTokenizer(request); if((st.countTokens() == 3) && st.nextToken().equals("GET")){ String filename = docRoot.getPath() + st.nextToken(); if(filename.endsWith("/") || filename.equals("")) filename += "index.html"; File file = new File(filename); sendDocument(os,file); } else System.err.println("400 Bad Request"); is.close(); os.close(); client.close(); }catch(IOException ioe){ System.err.println("Error: " + ioe.toString()); }}

Page 23: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur23

OneShot « envoi du document »

public static void sendDocument(DataOutputStream out, File file) throws IOException{

try{ BufferedInputStream in = new BufferedInputStream( new FileInputStream(file)); byte[] buf = new byte[1024]; int len; while((len = in.read(buf,0,1024)) != -1) { out.write(buf,0,len); } in.close(); } catch(FileNotFoundException fnfe) { System.err.println("404 Not Found"); } }

}

Page 24: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur24

OneShot avec Android

• AsyncTask<Params, Progress, Result> Rappel– Réalise une encapsulation d’un Thread et de l’accès à l’écran

• onPreExecute()– Préambule, l’UI exécute cette méthode

• Void doInBackground(String… s){ • }• onProgressUpdate(Progress…p)

– Mise à jour de l’UI à la suite de l’appel de publishProgress

• onPostExecute(Result)– Mise à jour de l’UI à la fin de la méthode doInBackground

OneShotHttpd.main(s);

Page 25: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur25

Côté serveur, un thread à chaque requête

ServerSocket listen = new ServerSocket(HTTP_PORT);

while(!stopped()){ try{ new Connection(listen.accept()); // création d’une instance }catch(Exception e){ } }

listen.close();}

Chaque requête engendre la création d’une instance de la classe ConnectionEt chaque instance créée engendre à son tour un « Thread »

Page 26: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur26

Côté serveur, à chaque Connection un Thread

public class Connexion extends Thread{…public Connexion(Socket s){ this.s = s; start(); }

public void run(){ try{ BufferedReader is = new BufferedReader( new InputStreamReader(s.getInputStream()));

DataOutputStream os = new DataOutputStream(s.getOutputStream());

// analyse du contenu au bon protocole HTTP // envoi du document

Page 27: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur27

Côté serveur, accept « peut-être »

ServerSocket listen = new ServerSocket(HTTP_PORT); listen.setSoTimeout(TIME_OUT); while(!stopped()){ try{ new Connection(listen.accept()); }catch(SocketTimeoutException e){ // ici délai de garde échu }catch(Exception e){ } } listen.close();}

Par défaut l’appel de accept est bloquantMéthode accept avec délai de garde

exception SocketTimeoutException à l’échéance

Page 28: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur28

Schéma avec Un Pool de Thread

class WebServer { // 2004 JavaOneSM Conference | Session 1358ThreadPool pool = new ThreadPool(7);

public static void main(String[] args) {ServerSocket socket = new ServerSocket(80);while (true) {

final Socket s = socket.accept();Runnable r = new Runnable() {

public void run() {BufferedReader is = new BufferedReader(

new InputStreamReader(s.getInputStream())); DataOutputStream os =

new DataOutputStream(s.getOutputStream()); // analyse du contenu au bon protocole HTTP // envoi du document

}};

pool.execute(r);}

}}

Page 29: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur29

Côté client

• Usage de telnet

• Requêtes GET et POST en Java

Page 30: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur30

Requête GET avec telnet

• Un client telnet et un site du Cnam

– telnet jfod.cnam.fr 80• GET /index.html HTTP/1.0 ( frappe sans écho)

HTTP/1.0 200 OKLast-Modified: Thu, 08 Feb 2007 14:55:29 GMTDate: Thu, 08 Mar 2007 10:33:55 GMTServer: Brazil/1.0Content-Length: 7624Content-Type: text/htmlConnection: close

<HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

…..

Le résultat est retourné, le source du fichier index.html précédé de quelques informations

Page 31: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur31

Requête GET en Java

• L’essentiel

– Créer une URL– Ouvrir une connexion

• Écrire et lire sur les flots associés

• Classe java.net.URL• Classe java.net.URLConnection

– URL url = new URL("http://jfod.cnam.fr/index.html" );– URLConnection connection = url.openConnection();

Page 32: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur32

Requête GET au complet

public void testGET()throws Exception{ URL url = new URL("http://jfod.cnam.fr/index.html" ); URLConnection connection = url.openConnection();

BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()));

String inputLine = in.readLine(); while(inputLine != null){ System.out.println(inputLine); inputLine = in.readLine(); } in.close();

}

Page 33: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur33

Requête GET avec paramètres

public void testGET()throws Exception{ URL url = new URL("http://jfod.cnam.fr:8999/ds2438/?listAll=on" );

URLConnection connection = url.openConnection(); connection.setDoInput(true);

BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()));

String inputLine = in.readLine(); while(inputLine != null){ System.out.println(inputLine); inputLine = in.readLine(); } in.close(); }

Page 34: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur34

Requête POST

URL url = new URL("http://jfod.cnam.fr/index.html"); URLConnection connection = url.openConnection(); connection.setDoInput(true);

connection.setDoOutput(true);

PrintWriter out = new PrintWriter(connection.getOutputStream()); out.print("listAll=on");

out.close(); BufferedReader in = new BufferedReader( new

InputStreamReader(connection.getInputStream())); String inputLine = in.readLine(); while(inputLine != null){ System.out.println(inputLine); inputLine = in.readLine(); } in.close();

Page 35: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur35

Classes utiles

• InetAddress– Adresse IP en « clair »

• URL– Pour Uniform Resource Locator, sur le www

• URLConnection– Une classe abstraite, super classe de toutes les classes établissant un

lien entre une application et une URL

– Sous-classes• HttpURLConnexion, JarURLConnection

– Patron Fabrique afin d’écrire son propre gestionnaire de protocole• Voir http://monge.univ-mlv.fr/~roussel/RESEAUJAVA/java.url2.html• Méthode URLConnection.setContentHandlerFactory( …);

Page 36: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur36

En résumé

• Classe d’accès aux informations – indépendante du protocole choisi

• Lecture écriture en 7 étapes

1. Après avoir créé l’URL.

2. Obtenir l’instance URLConnection.

3. Installer les capacités en sortie de cette instance de URLConnection.

4. Ouvrir le flot en entrée.

5. Obtenir le flot en sortie.

6. Écrire sur ce flot.

7. Fermer celui-ci.

Page 37: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur37

Android

• Android

– Toute requête doit être effectuée en dehors de l’UIThread:

– En conséquence, usage de

• AsyncTask

• Service + Thread

Page 38: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur38

En « rappel » le cycle de vie

Page 39: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur39

En Rappel: AsyncTask<Params, Progress, Result>

Avec la classe,

AsyncTask<Params, Progress, Result>– http://developer.android.com/reference/android/os/AsyncTask.html

• Nous avons – Un thread et l’accès à l’UIThread

• Un thread : pour le traitement en tâche de fond• Une mise à jour de l’UI incluse

• Les paramètres génériques sont– Params type des paramètres transmis au Thread– Progress type des paramètres en cours de traitement transmis au Handler– Result type du résultat pour l’appelant

Page 40: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur40

Résumé: AsyncTask<Params, Progress, Result>

• Depuis l’UIThread – création d’une instance et appel de la méthode execute

• Exemple new WebAsyncTask().execute(url1, url2, url3);

• AsyncTask<Params, Progress, Result> – Réalise une encapsulation d’un Thread et de l’accès à l’écran

Méthodes• onPreExecute()

– Préambule, l’UI exécute cette méthode

• Result doInBackground(Params…p)– Le contenu de cette méthode s’exécute dans un autre Thread

• onProgressUpdate(Progress…p)– Mise à jour de l’UI à la suite de l’appel de publishProgress

• onPostExecute(Result)– Mise à jour de l’UI à la fin de la méthode doInBackground

Page 41: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur41

AsyncTask et réseau, exemples

• Lire une page sur le web HTTP, requête GET– private class LirePageHTML extends AsyncTask<String,Void,String>{

Schéma

onPreExecute Afficher une fenêtre d’informations, ProgressDialog

doInBackGround Ouvrir une connexion, avec un échec éventuel

onPostExecute Informer l’utilisateur

Page 42: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur42

Lire une page Web www.cnam.fr

• Si j’ai la permission … de naviguer sur le web– <uses-permission android:name="android.permission.INTERNET"></uses-permission>

– Une IHM simple

– L’accès au web est une opération coûteuse alors héritons de AsyncTask

Page 43: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur43

Une classe interne héritant de AsyncTask

protected String doInBackground(String... args) { builder = new StringBuilder(); try { HttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(args[0]); HttpResponse response = client.execute(httpGet); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); if (statusCode == 200) { HttpEntity entity = response.getEntity(); InputStream content = entity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(content)); String line; while ((line = reader.readLine()) != null) { builder.append(line); } } else {error = "Failed to download file";} } catch (Exception e) {error = e.getMessage();}

return builder.toString();}

Page 44: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur44

Autres exemples, essai d’architecture

• 1) Ouverture d’une connexion TCP– Obtention d’un flux (OutputStream)– Le flux reste ouvert

• 2) Envois de données sur le flux– En fonction des opérations de l’utilisateur

• Règle : l’ouverture de la connexion et l’envoi de données se font sur des threads

• Une solution :– Ouverture d’une connexion TCP : dans une sous classe d’AsyncTask– Envoi de données : dans un thread en attente sur une file (SynchronousQueue)

– java.util.concurrent.SynchronousQueue

Page 45: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur45

Un schéma d’une architecture possible

UIThread

AsyncTask

Un Thread

Réseau

SynchronousQueue

offer take

2) Envoi de données

1) Obtention de la connexion

Page 46: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur46

Obtention de la connexion, AsyncTask

protected void onPreExecute() { dialog = ….);}

protected DataOutputStream doInBackground(String... args) {boolean result = true;try{ InetAddress addr = InetAddress.getByName(args[0]); int port = Integer.parseInt(args[1]); int timeout = Integer.parseInt(args[2]); SocketAddress sockaddr = new InetSocketAddress(addr, port); this.socket = new Socket(); socket.connect(sockaddr, timeout); out= new DataOutputStream(socket.getOutputStream());

}catch(Exception e){ erreur = e.getMessage();result= false;}return out;}

Page 47: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur47

Envoi de données depuis l’UIThread

// ici à chaque clic des données sont envoyées vers la file// les boutons de l’IHM contiennent la commande à envoyer au serveur

public void onClickCommand(View v){

String cmd = v.getContentDescription().toString() + "\n";

try {

sender.offer(cmd.getBytes());

} catch (Exception e) {

}

}

UIThreadoffer

Page 48: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur48

Envois de données, vers la file

public class Sender extends Thread{ private BlockingQueue<byte[]> queue; public Sender(){ queue = new SynchronousQueue<byte[]>(); this.start(); } public boolean offer(byte[] cmd){ return queue.offer(cmd); } public void close(){ this.interrupt(); } public void run(){ while(!isInterrupted()){ try { byte[] cmd = queue.take(); // lecture bloquante out.write(cmd); }catch (Exception e) { }} }

Page 49: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur49

Une connexion Bluetooth

• Recherche d’un périphérique bluetooth aux alentours– Hypothèse : Nous connaissons l’adresse physique du périphérique

• 00-19-EF-01-17-9C (obtenu ipconfig /all sous windows)

– Cette recherche doit s’effectuer dans un thread• Alors héritons de AsyncTask

• Au clic– new ConnexionBT().execute("00:19:EF:01:17:9C");

private class ConnexionBT extends AsyncTask<String,String,BluetoothSocket>{

protected void onPreExecute() {

protected BluetoothSocket doInBackground(String... args) {

protected void onPostExecute(BluetoothSocket btSocket) {

Page 50: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur50

onPreExecute : Patience, doInBackground : Recherche

protected void onPreExecute() { dialog = ProgressDialog.show(BTClientActivity.this, "connexion Bluetooth", " patientez ", true);

}

protected BluetoothSocket doInBackground(String... args) { try{ this.btDevice = btAdapter.getRemoteDevice(args[0]); btSocket =

btDevice.createRfcommSocketToServiceRecord(MY_UUID); btAdapter.cancelDiscovery(); btSocket.connect();

}catch(Exception e){ erreur = e.getMessage(); btSocket= null; } return btSocket;}

Page 51: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur51

onPostExecute(BluetoothSocket btSocket)

protected void onPostExecute(BluetoothSocket btSocket) {

try {

os = btSocket.getOutputStream();

//

} catch (IOException e) {

erreur = e.getMessage();

e.printStackTrace();

}finally{

dialog.dismiss();

}

}

Page 52: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur52

Première conclusion

• Serveurs et service

• Client et lecture de flux au format XML et JSON

– XML, SAX rappels cf. supports NFP121

– JSON

Page 53: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur53

SAX

XML DocumentXML Document

<?xml version=“1.0”?>

<addressbook>

</addressbook>

<person>

</person>

<name>John Doe</name>

<email>[email protected]</email>

<person>

</person>

<name>Jane Doe</name>

<email>[email protected]</email>

SAX ObjectsSAX Objects

ParserParser startDocument

ParserParser startElement

ParserParser startElement & characters

ParserParser startElement & characters

ParserParser endElement

ParserParser startElement

ParserParser startElement & characters

ParserParser startElement & characters

ParserParser endElement

ParserParser endElement & endDocument

Page 54: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur54

Implémenter les Handlers d'évènements du parseur

                                                                           

DefaultHandler

Il implémente ces différents Handler avec des méthodes vides, de sorte que l'on peut surcharger seulement celles qui nous intéressent.

Page 55: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur55

org.xml.sax.ContentHandler

Toutes les applications SAX doivent implanter un ContentHandler

Méthodes :

–public void startDocument() throws SAXException

–public void endDocument() throws SAXException

–public void startElement(String nspURI, String localName, String qName, Attributes atts) throws SAXException

–public void characters(char[] ch, int start, int length) throws SAXException

–…

Page 56: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur56

Un exemple: les stations Vélib

– http://www.velib.paris.fr– http://www.velib.paris.fr/service/carto– http://www.velib.paris.fr/service/stationdetails/{number}

Page 57: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur57

http://www.velib.paris.fr/service/carto

<carto>

<markers><marker name="00901 - STATION MOBILE 1" number="901" address="ALLEE DU BELVEDERE PARIS 19 - 0 75000 Paris -" fullAddress="ALLEE DU BELVEDERE PARIS 19 - 0 75000 Paris - 75000 PARIS" lat="48.892745582406675" lng="2.391255159886939" open="1" bonus="0"/>

<marker name="03011 - TURBIGO" number="3011" address="55 RUE TURBIGO -" fullAddress="55 RUE TURBIGO - 75003 PARIS" lat="48.86558781525867"lng="2.356094545731025" open="1" bonus="0"/>

Analyse des attributs

de la balise marker en SAX -> méthode startElement

Page 58: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur58

http://www.velib.paris.fr/service/stationdetails/3011

<station><available>21</available>

<free>10</free>

<total>31</total>

<ticket>1</ticket>

</station>

Analyse du contenu

de la balise station en SAX -> des méthodes startElement, endElement, characters

Page 59: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur59

Les stations Vélib: suite

• Les Classes, un premier découpage– StationVelib,

• toutes les infos d’une station, (adresse, longitude, latitude,…)

– InfoStation, • les informations comme le nombre de vélo et d’emplacements disponibles,...

– ListeDesStationsVelib• La gestion de la liste des stations

– http://www.velib.paris.fr/service/carto– http://www.velib.paris.fr/service/stationdetails/{number}

Page 60: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur60

Initialisation du « parser »

class ParserXML extends DefaultHandler {

public ParserXML(InputStream in) throws Exception{

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser sp = spf.newSAXParser();

XMLReader xr = sp.getXMLReader();

xr.setContentHandler(this);

xr.parse(new InputSource(in));

}

Page 61: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur61

startElement un extrait

// Création d’une instance de la classe StationVelib// depuis XML en Java

public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {

super.startElement(uri, localName, qName, attributes); if(qName.equals("marker")){ StationVelib station = new StationVelib(); station.setName(attributes.getValue("name")); station.setNumber(Integer.parseInt(attributes.getValue("number"))); station.setAddress(attributes.getValue("address")); station.setLatitude(Double.parseDouble(attributes.getValue("lat"))); station.setLongitude(Double.parseDouble(attributes.getValue("lng")));

}

Page 62: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur62

Une Info à chaque Station

class ParserXML extends DefaultHandler {

private StringBuffer current; // la valeur

public ParserXML(int ID){URL url = new URL(URL_VELIB_INFO + ID);

SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp; sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(this); xr.parse(new InputSource(url.openStream())); }

Page 63: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur63

A chaque noeud

public void startElement (String uri, String localName, String qName,Attributes attributes) throws SAXException {

super.startElement(uri, localName, qName, attributes); current = new StringBuffer();

}

public void characters (char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); current.append(new String(ch, start, length));

}

public void endElement (String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if(qName.equals("available")){ available = Integer.parseInt(current.toString()); … }

Page 64: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur64

XML plutôt verbeux, JSON plutôt concis

• JSON JavaScript Object Notation – www.json.org/

– JSONArray– JSONObject

JSONArray jsonArray = new JSONArray();

JSONObject jsonObject = new JSONObject();

jsonObject.put( "name", "paul");

jsonObject.put("number", 1900);

jsonArray.put(jsonObject);

// pierre idem

System.out.println(jsonArray.toString(2));

Page 65: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur65

JSON, exemple paul et pierre

• [• {• "name": "paul",• "number": 1900• },• {• "name": "pierre",• "number": 1900• }• ]

Page 66: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur66

JSON Lecture

InputStream in = …;Reader r = new InputStreamReader(in);

BufferedReader br = new BufferedReader(r);

StringBuffer sb = new StringBuffer();

String str;

while((str = br.readLine()) != null) {

sb.append(str);

}

r.close();

JSONArray jsonarray = new JSONArray(sb.toString());

JSONObject jsonObject = (JSONObject)jsonStations.get(i);

Auditeur a = new Auditeur ();

a.setName(jsonObject.getString("name"));

Page 67: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur67

StationVelib, lecture JSON

JSONArray jsonStations = new JSONArray(sb.toString());

for(int i=0; i< jsonStations.length(); i++){

JSONObject jsonObject = (JSONObject)jsonStations.get(i);

StationVelib st = new StationVelib();

st.setName(jsonObject.getString("name"));

st.setNumber(jsonObject.getInt("number"));

st.setAddress(jsonObject.getString("address"));

st.setFullAddress(jsonObject.getString("fullAddress"));

st.setLatitude(jsonObject.getDouble("lat"));

st.setLongitude(jsonObject.getDouble("lng"));

st.setOpen(jsonObject.getBoolean("open"));

st.setBonus(jsonObject.getBoolean("bonus"));

Page 68: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur68

Démonstration

Page 69: Android_Clients_Serveur 1 Connectivité Orienté clients/serveur TCP et Bluetooth Notes de cours jean-michel Douin, douin au cnam point fr version : 7 Novembre

Android_Clients_Serveur69

Conclusion

• Discussions