Mon Application Android pour les horaires de la CTS

13 décembre 2009 par Gaëtan Laisser une réponse »

Amis Strasbourgeois bonsoir …
Après un WE chargé sur Strasbourg, j’ai remarqué que la Compagnie des Transports de Strasbourg (CTS) avais mis en place un site web intéressant en temps réel (semble-t-il) pour calculer les horaires des BUS/Trams du réseau urbain.

L’autre partie du service « Temps Réel » se fait par SMS par envoi du code de la station à un numéro surtaxé … :s. Ayant un forfait 3G, je vais pas claquer un SMS surtaxé si je peux accéder au web gratuitement (quel radin ;) ), mais le site est assez bof depuis mon navigateur, et c’est assez lent …

Ayant acheté un G1 dans le but de dev des applis, j’en ai profité pour faire ce que je sais (apparemment) faire de mieux … parser des sites web pour en extraire des informations, dans ce cas précis, les horaires des transports en commun.

L’application ressemble à ceci : (super moche je sais, mais elle fait sont boulot … c’est l’essentiel).

android-CTSPour le code source, j’ai tenté de faire au plus simple (traduction : le code est aussi beau que le screenshot fournit plus haut ^^, pour ma décharge, je dirais que j’ai tout mis dans un fichier histoire de ne pas à avoir trop de fichier à fournir ici).

Si vous avez des idées pour améliorer l’appli je suis open ;) (à part si c’est pour me recycler et changer de métier :s). Je pense changer l’appli en widget (si j’ai le temps …).

Pour les fichiers, tout d’abord le main.java

  1. package eu.gaetangrigis.cts;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.util.Calendar;
  7. import java.util.regex.Matcher;
  8. import java.util.regex.Pattern;
  9.  
  10. import android.app.Activity;
  11. import android.app.Dialog;
  12. import android.app.TimePickerDialog;
  13. import android.app.TimePickerDialog.OnTimeSetListener;
  14. import android.os.Bundle;
  15. import android.view.View;
  16. import android.view.View.OnClickListener;
  17. import android.view.View.OnFocusChangeListener;
  18. import android.view.ViewGroup.LayoutParams;
  19. import android.widget.Button;
  20. import android.widget.EditText;
  21. import android.widget.TableLayout;
  22. import android.widget.TableRow;
  23. import android.widget.TextView;
  24. import android.widget.TimePicker;
  25.  
  26. import org.apache.http.HttpResponse;
  27. import org.apache.http.client.methods.HttpGet;
  28. import org.apache.http.client.ClientProtocolException;
  29. import org.apache.http.client.HttpClient;
  30. import org.apache.http.impl.client.DefaultHttpClient;
  31.  
  32. public class Main extends Activity {
  33.     /** Called when the activity is first created. */
  34.  private Button check;
  35.  private Button clear;
  36.  private TextView t;
  37.  private EditText station;
  38.  private EditText heure;
  39.  private EditText minute;
  40.  private TableLayout table;
  41.  
  42.  private int mHeure;
  43.  private int mMinute;
  44.  private TimePickerDialog.OnTimeSetListener mTimeSetListener;
  45.  
  46.  final Calendar c = Calendar.getInstance();
  47.  
  48.     @Override
  49.     public void onCreate(Bundle savedInstanceState) {
  50.         super.onCreate(savedInstanceState);
  51.         setContentView(R.layout.main);
  52.  
  53. //Recuperation des champs
  54.         table = (TableLayout)findViewById(R.id.maTable);
  55.         station = (EditText)findViewById(R.id.idStation);
  56.         heure = (EditText)findViewById(R.id.heure);
  57.         minute = (EditText)findViewById(R.id.minute);
  58.      check=(Button)findViewById(R.id.check);
  59.      clear=(Button)findViewById(R.id.clear);
  60.         t =(TextView) findViewById(R.id.information);
  61.  
  62. //Texte par défaut
  63.         mHeure = c.get(Calendar.HOUR_OF_DAY);
  64.         mMinute = c.get(Calendar.MINUTE);
  65.         t.setText("Entrez les informations demandées");
  66.         station.setText("75");
  67.         mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
  68.          public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
  69.              mHeure = hourOfDay;
  70.              mMinute = minute;
  71.              updateTime();
  72.          }
  73.      };
  74.  
  75.         updateTime();
  76.   check.setOnClickListener(new OnClickListener() {public void onClick(View v) {startResearch();}});
  77.   clear.setOnClickListener(new OnClickListener() {public void onClick(View v) {clearResearch();}});
  78.   heure.setOnFocusChangeListener(new OnFocusChangeListener() {public void onFocusChange(View v, boolean hasFocus) {if(hasFocus)showDialog(0);}});
  79.   minute.setOnFocusChangeListener(new OnFocusChangeListener() {public void onFocusChange(View v, boolean hasFocus) {if(hasFocus)showDialog(0);}});
  80.     }
  81.    
  82.     public void clearResearch()
  83.     {
  84.      table.removeAllViews();
  85.     }
  86.    
  87.     public void startResearch()
  88.     {
  89.      t.setText("Recherche en cours");
  90.         HttpGet site   = new HttpGet("http://tr.cts-strasbourg.fr/HorTRweb/ResultatsHoraires.aspx?arret="+station.getText()+"&type=TOUS&heure="+heure.getText()+"&min="+minute.getText());
  91.         HttpClient cli = new DefaultHttpClient();
  92.         HttpResponse resp;
  93.         String res;
  94.         String content=new String();
  95.         String ret = new String();
  96.         boolean dTab=false;
  97.         try {
  98.          resp = cli.execute(site);
  99.          BufferedReader read = new BufferedReader(new InputStreamReader(resp.getEntity().getContent()));
  100.          while((res=read.readLine())!=null)
  101.          {
  102.           if(res.matches(".*<table class=.depart.*")){dTab=true;}
  103.           if(dTab==true&&res.matches(".*</table>.*")){dTab=false;break;}
  104.           if(dTab==true){content+=res;}
  105.          }
  106.          Pattern p = Pattern.compile("<td[^>]*>([^<]*)</td><td[^>]*>([^<]*)</td><td[^>]*>([^<]*)</td>");
  107.          Matcher m = p.matcher(content);
  108.          while(m.find())
  109.          {
  110.           for(int i=1;i<=m.groupCount();i++){ret+=m.group(i)+" ";}
  111.           table.addView(addTextRow(ret));
  112.           ret="";
  113.          }
  114.         }
  115.         catch (ClientProtocolException e) {t.setText(e.getMessage());}
  116.   catch (IOException e) {t.setText(e.getMessage());}
  117.   finally{t.setText("Recherche terminé");}
  118.     }
  119.    
  120.     public TableRow addTextRow(String text)
  121.     {
  122.      TableRow tr = new TableRow(this);
  123.         TextView tt = new TextView(this);
  124.         tt.setText(text);
  125.         tr.addView(tt);
  126.   return tr;
  127.     }
  128.    
  129.     @Override
  130.     protected Dialog onCreateDialog(int id) {
  131.         switch (id) {
  132.         case 0:
  133.    return new TimePickerDialog(this,
  134.                     mTimeSetListener, mHeure, mMinute, false);
  135.         }
  136.         return null;
  137.     }
  138.    
  139.     public void updateTime()
  140.     {
  141.      String add="";
  142.         heure.setText(mHeure+"");
  143.         if(mMinute<10)
  144.          add="0";
  145.         minute.setText(add+mMinute);
  146.     }
  147. }

Puis le main.xml (qui définit l’interface graphique)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:orientation="vertical"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="fill_parent"
  6.     >
  7. <TextView  
  8.     android:layout_width="fill_parent"
  9.     android:layout_height="wrap_content"
  10.     android:id="@+id/information"
  11.     android:text=""
  12.     />
  13.    
  14. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  15.     android:orientation="horizontal"
  16.     android:layout_width="wrap_content"
  17.     android:layout_height="wrap_content"
  18.     >
  19.     <TextView  
  20.      android:layout_width="wrap_content"
  21.      android:layout_height="wrap_content"
  22.      android:text="Code de la station : "
  23.      />
  24.  <EditText  
  25.      android:layout_width="wrap_content"
  26.      android:layout_height="wrap_content"
  27.   android:id="@+id/idStation"
  28.   android:text=""
  29.   />
  30. </LinearLayout>
  31. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  32.     android:orientation="horizontal"
  33.     android:layout_width="wrap_content"
  34.     android:layout_height="wrap_content"
  35.     >
  36.     <TextView  
  37.      android:layout_width="wrap_content"
  38.      android:layout_height="wrap_content"
  39.      android:text="Heure voulue : "
  40.      />
  41.  <EditText  
  42.      android:layout_width="wrap_content"
  43.      android:layout_height="wrap_content"
  44.   android:id="@+id/heure"
  45.   />
  46.  <TextView  
  47.      android:layout_width="wrap_content"
  48.      android:layout_height="wrap_content"
  49.      android:text="h"
  50.      />
  51.  <EditText
  52.      android:layout_width="wrap_content"
  53.      android:layout_height="wrap_content"
  54.   android:id="@+id/minute"
  55.   />
  56. </LinearLayout>
  57.  
  58. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  59.     android:orientation="horizontal"
  60.     android:layout_width="wrap_content"
  61.     android:layout_height="wrap_content"
  62.     >
  63.  <Button  
  64.      android:layout_width="wrap_content"
  65.      android:layout_height="wrap_content"
  66.   android:text="Check"
  67.   android:id="@+id/check"
  68.   />
  69.  <Button  
  70.      android:layout_width="wrap_content"
  71.      android:layout_height="wrap_content"
  72.   android:text="Clear"
  73.   android:id="@+id/clear"
  74.   />
  75. </LinearLayout>
  76.  
  77. <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  78.     android:id="@+id/maTable"
  79.     android:layout_width="fill_parent"
  80.     android:layout_height="wrap_content"
  81.     >
  82. </TableLayout>
  83. </LinearLayout>

et enfin le Manifest.xml (pour ne pas oublier les permissions d’accès au net)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.       package="eu.gaetangrigis.cts"
  4.       android:versionCode="1"
  5.       android:versionName="1.0">
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">
  7.         <activity android:name=".Main"
  8.                   android:label="@string/app_name">
  9.             <intent-filter>
  10.                 <action android:name="android.intent.action.MAIN" />
  11.                 <category android:name="android.intent.category.LAUNCHER" />
  12.             </intent-filter>
  13.         </activity>
  14.  
  15.     </application>
  16.     <uses-sdk android:minSdkVersion="4" />
  17.  
  18. <uses-permission android:name="android.permission.INTERNET" />
  19. </manifest>
Publicité

Laisser un commentaire