android_clients_serveur 1 connectivité orienté clients/serveur tcp et bluetooth notes de cours...
TRANSCRIPT
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 :
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
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
Android_Clients_Serveur4
Client et serveur
• Serveurs TCP
– Exemples
– Requête
Android_Clients_Serveur5
Serveurs
• En mode TCP
• Appels distants en mode TCP/IP– Point à point avec accusé de réception
– telnet, ftp, http, …
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
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
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
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
Android_Clients_Serveur10
Implémentation en Java
• Paquetage java.net
– Principales classes • ServerSocket• Socket• InetAddress• URLConnection• …
– Quelques lignes de sources suffisent …
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
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
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 …
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
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(); } } }
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();
}
}
Android_Clients_Serveur17
Un client « maison », telnet
• telnet localhost 5000– parle // frappe sans écho
• petit outil utile : tcpview
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
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
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.
Android_Clients_Serveur21
Exemple minimaliste !
• Un serveur Web au complet– Un seul client, une seule requête !
• Extrait de
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()); }}
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"); } }
}
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);
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 »
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
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
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);}
}}
Android_Clients_Serveur29
Côté client
• Usage de telnet
• Requêtes GET et POST en Java
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
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();
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();
}
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(); }
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();
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( …);
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.
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
Android_Clients_Serveur38
En « rappel » le cycle de vie
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
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
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
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
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();}
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
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
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;}
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
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) { }} }
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) {
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;}
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();
}
}
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
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
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.
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
–…
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}
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
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
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}
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));
}
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")));
}
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())); }
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()); … }
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));
Android_Clients_Serveur65
JSON, exemple paul et pierre
• [• {• "name": "paul",• "number": 1900• },• {• "name": "pierre",• "number": 1900• }• ]
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"));
…
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"));
Android_Clients_Serveur68
Démonstration
Android_Clients_Serveur69
Conclusion
• Discussions