Vous avez sans doute entendu parler des menaces de la RATP contre le site http://incidents-ratp.com/ qui a pour but de
Vous donner l’accès librement et gratuitement aux informations concernant vos transports en communs
Quoi qu’il en soit, Benoît est en train de développer une application iPhone pour accéder plus rapidement aux informations trafic des transports en commun.
Et il m’a suggéré de faire la même chose pour Android. J’ai plein de trucs importants à faire, mais une envie soudaine de coder m’a pris.
Hier, j’ai commencé. Et il me paraît intéressant pour tous les développeurs en herbe de dire combien un tel développement consomme de temps. Hier, j’ai donc passé 4 heures pour traiter les tâches suivantes.
Découvrir le service web
J’ai d’abord regardé l’API du service. C’est encore un peu sommaire.
La liste des incidents est obtenu par un appel REST, dans le format de son choix (XML ou json).
Je me dis que Java permettra de parser sans problème le XML.
(15 min)
Préparer mon environnement
Ensuite, je perds un peu de temps à réinitialiser mon Eclipse avec le dernier plugin de développement Android.
Pas vraiment utile, vu que je vais me baser sur une ancienne version du SDK, afin de couvrir le maximum de matériels.
(15 min)
Initier un nouveau projet
Ça s’est l’affaire d’un ou deux clics 
J’utilise bitbucket pour outiller ma gestion de configuration.
Je laisse l’interface vide pour le moment.
(10 min)
Faire le client de service web
Je crée ensuite un modèle objet pour un Incident. Il est très simple. Oui, j’utilise des variables de classe publiques. Je n’ai jamais compris la convention des getters&setters. Alors, pour un développement mobile, j’évite les lourdeurs. (30 min)
[code]
public class Incident {
int uid;
String status;
String ligne;
int votePlus;
int voteEnded;
int voteMinus;
String reason;
Date lastModified;
}
[/code]
Il me faut évidemment un client du service web. Cela se fait très simplement avec Apache HttpClient qui fait partie du framework Android. (20 min).
[code]
public class IncidentProvider {
private static final String TAG = "IncidentProvider";
public void refresh(URI uri) throws ClientProtocolException, IOException,
SAXException {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(uri);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
refresh(entity.getContent());
}
}
[/code]
Je passe ensuite au mappage du résultat dans des objets Incident. Je pensais au début faire du castor/Jaxb/etc. mais c’est trucs sont trop lourds pour un mobile. De base dans le framework, on a du SAX:
[code]
public class IncidentProvider implements ContentHandler {
private Incident mIncident;
ArrayList@lt;incident@gt; incidents;
/* buffers */
private StringBuffer mBuffer;
[...]
public void refresh(InputStream in) throws IOException, SAXException {
Xml.parse(in, Encoding.UTF_8, this);
}
public void startDocument() throws SAXException {
mIncidents = new ArrayList@lt;Incident@gt;();
}
public void startElement(String uri, String name, String qName,
Attributes atts) throws SAXException {
if ("resource".equals(name)) {
mIncident = new Incident();
}
mBuffer = new StringBuffer();
}
public void endElement(String uri, String name, String qName)
throws SAXException {
if ("status".equals(name)) {
mIncident.status = mBuffer.toString();
} else if ("vote_plus".equals(name)) {
mIncident.setVotePlus(mBuffer.toString());
} else if ("vote_minus".equals(name)) {
mIncident.setVoteMinus(mBuffer.toString());
} else if ("vote_ended".equals(name)) {
mIncident.setVoteEnded(mBuffer.toString());
} else if ("reason".equals(name)) {
mIncident.reason = mBuffer.toString();
} else if ("line".equals(name)) {
mIncident.ligne = mBuffer.toString();
} else if ("last_modified_time".equals(name)) {
mIncident.setLastModified(mBuffer.toString());
} else if ("uid".equals(name)) {
mIncident.setUID(mBuffer.toString());
} else if ("resource".equals(name)) {
mIncidents.add(mIncident);
}
}
public void characters(char chars[], int start, int length)
throws SAXException {
mBuffer.append(chars, start, length);
}
[/code]
(1h avec les tests unitaires et l’écriture des setters dont j’ai besoin)
Affichage dans une liste
Je modifie ensuite l’interface pour ajouter une ListView qui présentera les résultats.
C’est là dessus que j’ai passé le plus de temps (2h). J’ai d’abord cru que je devrais écrire mon propre Adapter, alors que j’ai finalement pu utiliser le ArrayAdapter. Ensuite, j’ai mal compris comment celui-ci utilisait le TexteView.
Et c’est le « bonheur » du développement XML. Il faut exécuter dans l’émulateur (plusieurs secondes à chaque fois) pour avoir un message d’erreur pas toujours très clair… ou bien une appli qui fonctionne mais n’affiche rien.
In fine
Mais j’ai fini par faire marcher cette partie.

Et ce soir, j’avais mieux à faire