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).
Pour 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
-
package eu.gaetangrigis.cts;
-
-
import java.io.BufferedReader;
-
import java.io.IOException;
-
import java.io.InputStreamReader;
-
import java.util.Calendar;
-
import java.util.regex.Matcher;
-
import java.util.regex.Pattern;
-
-
import android.app.Activity;
-
import android.app.Dialog;
-
import android.app.TimePickerDialog;
-
import android.app.TimePickerDialog.OnTimeSetListener;
-
import android.os.Bundle;
-
import android.view.View;
-
import android.view.View.OnClickListener;
-
import android.view.View.OnFocusChangeListener;
-
import android.view.ViewGroup.LayoutParams;
-
import android.widget.Button;
-
import android.widget.EditText;
-
import android.widget.TableLayout;
-
import android.widget.TableRow;
-
import android.widget.TextView;
-
import android.widget.TimePicker;
-
-
import org.apache.http.HttpResponse;
-
import org.apache.http.client.methods.HttpGet;
-
import org.apache.http.client.ClientProtocolException;
-
import org.apache.http.client.HttpClient;
-
import org.apache.http.impl.client.DefaultHttpClient;
-
-
public class Main extends Activity {
-
/** Called when the activity is first created. */
-
private Button check;
-
private Button clear;
-
private TextView t;
-
private EditText station;
-
private EditText heure;
-
private EditText minute;
-
private TableLayout table;
-
-
private int mHeure;
-
private int mMinute;
-
private TimePickerDialog.OnTimeSetListener mTimeSetListener;
-
-
final Calendar c = Calendar.getInstance();
-
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.main);
-
-
//Recuperation des champs
-
table = (TableLayout)findViewById(R.id.maTable);
-
station = (EditText)findViewById(R.id.idStation);
-
heure = (EditText)findViewById(R.id.heure);
-
minute = (EditText)findViewById(R.id.minute);
-
check=(Button)findViewById(R.id.check);
-
clear=(Button)findViewById(R.id.clear);
-
t =(TextView) findViewById(R.id.information);
-
-
//Texte par défaut
-
mHeure = c.get(Calendar.HOUR_OF_DAY);
-
mMinute = c.get(Calendar.MINUTE);
-
t.setText("Entrez les informations demandées");
-
station.setText("75");
-
mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
-
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
-
mHeure = hourOfDay;
-
mMinute = minute;
-
updateTime();
-
}
-
};
-
-
updateTime();
-
check.setOnClickListener(new OnClickListener() {public void onClick(View v) {startResearch();}});
-
clear.setOnClickListener(new OnClickListener() {public void onClick(View v) {clearResearch();}});
-
heure.setOnFocusChangeListener(new OnFocusChangeListener() {public void onFocusChange(View v, boolean hasFocus) {if(hasFocus)showDialog(0);}});
-
minute.setOnFocusChangeListener(new OnFocusChangeListener() {public void onFocusChange(View v, boolean hasFocus) {if(hasFocus)showDialog(0);}});
-
}
-
-
public void clearResearch()
-
{
-
table.removeAllViews();
-
}
-
-
public void startResearch()
-
{
-
t.setText("Recherche en cours");
-
HttpGet site = new HttpGet("http://tr.cts-strasbourg.fr/HorTRweb/ResultatsHoraires.aspx?arret="+station.getText()+"&type=TOUS&heure="+heure.getText()+"&min="+minute.getText());
-
HttpClient cli = new DefaultHttpClient();
-
HttpResponse resp;
-
String res;
-
String content=new String();
-
String ret = new String();
-
boolean dTab=false;
-
try {
-
resp = cli.execute(site);
-
BufferedReader read = new BufferedReader(new InputStreamReader(resp.getEntity().getContent()));
-
while((res=read.readLine())!=null)
-
{
-
if(res.matches(".*<table class=.depart.*")){dTab=true;}
-
if(dTab==true&&res.matches(".*</table>.*")){dTab=false;break;}
-
if(dTab==true){content+=res;}
-
}
-
Pattern p = Pattern.compile("<td[^>]*>([^<]*)</td><td[^>]*>([^<]*)</td><td[^>]*>([^<]*)</td>");
-
Matcher m = p.matcher(content);
-
while(m.find())
-
{
-
for(int i=1;i<=m.groupCount();i++){ret+=m.group(i)+" ";}
-
table.addView(addTextRow(ret));
-
ret="";
-
}
-
}
-
catch (ClientProtocolException e) {t.setText(e.getMessage());}
-
catch (IOException e) {t.setText(e.getMessage());}
-
finally{t.setText("Recherche terminé");}
-
}
-
-
public TableRow addTextRow(String text)
-
{
-
TableRow tr = new TableRow(this);
-
TextView tt = new TextView(this);
-
tt.setText(text);
-
tr.addView(tt);
-
return tr;
-
}
-
-
@Override
-
protected Dialog onCreateDialog(int id) {
-
switch (id) {
-
case 0:
-
return new TimePickerDialog(this,
-
mTimeSetListener, mHeure, mMinute, false);
-
}
-
return null;
-
}
-
-
public void updateTime()
-
{
-
String add="";
-
heure.setText(mHeure+"");
-
if(mMinute<10)
-
add="0";
-
minute.setText(add+mMinute);
-
}
-
}
Puis le main.xml (qui définit l’interface graphique)
-
<?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"
-
>
-
<TextView
-
android:layout_width="fill_parent"
-
android:layout_height="wrap_content"
-
android:id="@+id/information"
-
android:text=""
-
/>
-
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:orientation="horizontal"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
>
-
<TextView
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:text="Code de la station : "
-
/>
-
<EditText
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:id="@+id/idStation"
-
android:text=""
-
/>
-
</LinearLayout>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:orientation="horizontal"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
>
-
<TextView
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:text="Heure voulue : "
-
/>
-
<EditText
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:id="@+id/heure"
-
/>
-
<TextView
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:text="h"
-
/>
-
<EditText
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:id="@+id/minute"
-
/>
-
</LinearLayout>
-
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:orientation="horizontal"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
>
-
<Button
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:text="Check"
-
android:id="@+id/check"
-
/>
-
<Button
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:text="Clear"
-
android:id="@+id/clear"
-
/>
-
</LinearLayout>
-
-
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:id="@+id/maTable"
-
android:layout_width="fill_parent"
-
android:layout_height="wrap_content"
-
>
-
</TableLayout>
-
</LinearLayout>
et enfin le Manifest.xml (pour ne pas oublier les permissions d’accès au net)
-
<?xml version="1.0" encoding="utf-8"?>
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-
package="eu.gaetangrigis.cts"
-
android:versionCode="1"
-
android:versionName="1.0">
-
<application android:icon="@drawable/icon" android:label="@string/app_name">
-
<activity android:name=".Main"
-
android:label="@string/app_name">
-
<intent-filter>
-
<action android:name="android.intent.action.MAIN" />
-
<category android:name="android.intent.category.LAUNCHER" />
-
</intent-filter>
-
</activity>
-
-
</application>
-
<uses-sdk android:minSdkVersion="4" />
-
-
<uses-permission android:name="android.permission.INTERNET" />
-
</manifest>
















