/[projects]/android/TrainInfo/src/dk/thoerup/traininfo/DepartureList.java
ViewVC logotype

Annotation of /android/TrainInfo/src/dk/thoerup/traininfo/DepartureList.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1053 - (hide annotations) (download)
Tue Sep 14 16:00:57 2010 UTC (13 years, 8 months ago) by torben
File size: 14265 byte(s)
First iteration of metro support
1 torben 237 package dk.thoerup.traininfo;
2    
3 torben 1053 import static dk.thoerup.traininfo.R.string.departurelist_fetcharrivals;
4 torben 835 import static dk.thoerup.traininfo.R.string.departurelist_fetchdepartures;
5     import static dk.thoerup.traininfo.R.string.generic_cancel;
6     import static dk.thoerup.traininfo.R.string.generic_retry;
7    
8 torben 237 import java.text.NumberFormat;
9    
10 torben 336 import android.app.AlertDialog;
11 torben 237 import android.app.Dialog;
12     import android.app.ListActivity;
13     import android.app.ProgressDialog;
14 torben 336 import android.content.DialogInterface;
15 torben 237 import android.content.Intent;
16 torben 1053 import android.graphics.Typeface;
17 torben 239 import android.net.Uri;
18 torben 237 import android.os.AsyncTask;
19     import android.os.Bundle;
20 torben 630 import android.util.Log;
21 torben 982 import android.view.Menu;
22     import android.view.MenuItem;
23 torben 237 import android.view.View;
24 torben 835 import android.view.View.OnClickListener;
25     import android.widget.Button;
26 torben 237 import android.widget.ListView;
27 torben 1053 import android.widget.TableLayout;
28     import android.widget.TableRow;
29 torben 237 import android.widget.TextView;
30 torben 255 import dk.thoerup.traininfo.provider.DepartureProvider;
31 torben 1053 import dk.thoerup.traininfo.provider.MetroProvider;
32 torben 253 import dk.thoerup.traininfo.provider.ProviderFactory;
33 torben 1053 import dk.thoerup.traininfo.provider.MetroProvider.MetroBean;
34     import dk.thoerup.traininfo.provider.MetroProvider.MetroEntry;
35 torben 245 import dk.thoerup.traininfo.util.MessageBox;
36 torben 237
37     public class DepartureList extends ListActivity {
38    
39     public static final int DLG_PROGRESS = 1;
40 torben 982 static final int MENU_MAP = 100;
41     static final int MENU_NOTIFICATIONS = 101;
42 torben 237
43 torben 362
44 torben 237 DepartureListAdapter adapter;
45     DepartureProvider provider;
46 torben 981 DepartureBean departures;
47 torben 237
48 torben 1053 MetroBean metroBean;
49     MetroProvider metro;
50    
51 torben 257 int selectedItemId;
52     //DepartureBean currentDeparture;
53 torben 237
54     ProgressDialog pgDialog;
55 torben 362
56 torben 238 DepartureFetcher fetcher;
57 torben 1053 MetroFetcher metroFetcher;
58 torben 557
59     StationBean station;
60 torben 238
61 torben 835 boolean arrival = false;
62 torben 981
63 torben 1017 int commFailCounter = 0;
64    
65 torben 237 @Override
66     protected void onCreate(Bundle savedInstanceState) {
67     super.onCreate(savedInstanceState);
68     setContentView(R.layout.departurelist);
69    
70     adapter = new DepartureListAdapter(this);
71     setListAdapter(adapter);
72    
73     Intent launchedBy = getIntent();
74 torben 557
75     station = (StationBean) launchedBy.getSerializableExtra("stationbean");
76 torben 239
77 torben 557 ((TextView) findViewById(R.id.stationName)).setText( station.getName() );
78 torben 317
79 torben 557
80     ((TextView) findViewById(R.id.stationAddr)).setText( station.getAddress() );
81 torben 237
82 torben 835 final Button departureBtn = (Button) findViewById(R.id.departurebtn);
83     final Button arrivalBtn = (Button) findViewById(R.id.arrivalbtn);
84 torben 1044 final Button metroBtn = (Button) findViewById(R.id.metrobtn);
85 torben 294
86 torben 1053 final View metroView = findViewById(R.id.metroonly);
87    
88 torben 835 departureBtn.setOnClickListener( new OnClickListener() {
89     @Override
90     public void onClick(View arg0) {
91     arrivalBtn.setBackgroundResource(R.drawable.custom_button);
92     departureBtn.setBackgroundResource(R.drawable.custom_button_hilight);
93 torben 1044 metroBtn.setBackgroundResource(R.drawable.custom_button);
94 torben 1053
95     getListView().setVisibility( View.VISIBLE );
96     metroView.setVisibility( View.GONE );
97 torben 835 arrival = false;
98     startDepartureFetcher();
99     }
100     });
101     arrivalBtn.setOnClickListener( new OnClickListener() {
102     @Override
103     public void onClick(View arg0) {
104     arrivalBtn.setBackgroundResource(R.drawable.custom_button_hilight);
105     departureBtn.setBackgroundResource(R.drawable.custom_button);
106 torben 1044 metroBtn.setBackgroundResource(R.drawable.custom_button);
107 torben 1053
108     getListView().setVisibility( View.VISIBLE );
109     metroView.setVisibility( View.GONE );
110 torben 835 arrival = true;
111     startDepartureFetcher();
112     }
113     });
114    
115 torben 1044 metroBtn.setOnClickListener( new OnClickListener() {
116     @Override
117     public void onClick(View v) {
118     arrivalBtn.setBackgroundResource(R.drawable.custom_button);
119     departureBtn.setBackgroundResource(R.drawable.custom_button);
120     metroBtn.setBackgroundResource(R.drawable.custom_button_hilight);
121 torben 1053
122     getListView().setVisibility( View.GONE );
123     metroView.setVisibility( View.VISIBLE );
124     startMetroFetcher();
125 torben 1044 }
126     });
127 torben 835
128    
129    
130 torben 1044
131 torben 982 // findViewById(R.id.header).setOnClickListener( mapLauncher );
132 torben 237
133 torben 557 int distance = station.getDistance();
134 torben 742 if (distance != 0) {
135     NumberFormat format = NumberFormat.getNumberInstance();
136     format.setMaximumFractionDigits(1);
137     format.setMinimumFractionDigits(1);
138 torben 575
139 torben 742 ((TextView) findViewById(R.id.stationDistance)).setText( format.format((double)distance/1000.0) + " km." );
140     } else {
141     ((TextView) findViewById(R.id.stationDistance)).setVisibility(View.GONE);
142     }
143 torben 552
144 torben 1028 ProviderFactory.purgeOldEntries(); //cleanup before fetching more data
145 torben 1044
146     Log.e("Station", station.toCSV() );
147    
148     if (station.isMetro() == false) {
149     metroBtn.setVisibility( View.GONE );
150     }
151 torben 1028
152 torben 1053 metro = ProviderFactory.getMetroProvider();
153    
154 torben 557 if (station.isRegional() == false && station.isSTrain() == false) {
155 torben 552 getListView().setVisibility( View.GONE );
156 torben 1053 metroView.setVisibility( View.VISIBLE );
157    
158 torben 835 departureBtn.setVisibility( View.GONE );
159     arrivalBtn.setVisibility(View.GONE);
160 torben 1044 metroBtn.setVisibility( View.GONE );
161 torben 552
162 torben 1053 if (savedInstanceState == null) {
163     startMetroFetcher();
164     } else {
165     metroBean = (MetroBean) savedInstanceState.getSerializable("metro");
166     loadMetroData();
167     }
168    
169 torben 257 } else {
170 torben 552 provider = ProviderFactory.getDepartureProvider();
171    
172     if (savedInstanceState == null) {
173     startDepartureFetcher();
174     } else {
175 torben 981 departures = (DepartureBean) savedInstanceState.getSerializable("departures");
176 torben 990
177     if ( (departures != null) && (departures.entries != null) ) {
178     adapter.setDepartures(departures.entries);
179     }
180 torben 982 selectedItemId = savedInstanceState.getInt("selectedItemId");
181    
182     if ( hasNotifications() ) {
183     findViewById(R.id.notifIcon).setVisibility(View.VISIBLE);
184     }
185    
186 torben 552 }
187 torben 257 }
188 torben 237 }
189    
190 torben 982 boolean hasNotifications() {
191     return (departures != null && departures.notifications.size() > 0);
192     }
193    
194 torben 243 @Override
195     public void onSaveInstanceState(Bundle outState)
196     {
197 torben 257 if (pgDialog != null && pgDialog.isShowing())
198     dismissDialog(DLG_PROGRESS);
199 torben 362
200 torben 257 outState.putInt("selectedItemId", selectedItemId);
201    
202 torben 981 outState.putSerializable("departures", departures);
203 torben 1053 outState.putSerializable("metro", metroBean);
204 torben 243 }
205 torben 918
206    
207 torben 243
208 torben 237 @Override
209 torben 918 protected void onDestroy() {
210     super.onDestroy();
211    
212     if (fetcher != null) {
213     fetcher.cancel(true);
214     }
215 torben 1053
216     if (metroFetcher != null) {
217     metroFetcher.cancel(true);
218     }
219 torben 918 }
220    
221     @Override
222 torben 237 protected void onListItemClick(ListView l, View v, int position, long id) {
223     super.onListItemClick(l, v, position, id);
224 torben 362
225     selectedItemId = position;
226 torben 364
227 torben 981 DepartureEntry dep = departures.entries.get(selectedItemId);
228 torben 237
229 torben 362 Intent intent = new Intent(this, TimetableList.class);
230 torben 364 intent.putExtra("departure", dep);
231 torben 362
232     startActivity(intent);
233    
234 torben 237 }
235    
236    
237     @Override
238     protected void onPrepareDialog(int id, Dialog dialog) {
239     super.onPrepareDialog(id, dialog);
240 torben 257
241 torben 237 switch (id) {
242     case DLG_PROGRESS:
243     pgDialog = (ProgressDialog) dialog;
244 torben 835 int messageId = arrival == false ? departurelist_fetchdepartures : departurelist_fetcharrivals;
245     pgDialog.setMessage( getString(messageId) );
246 torben 237 break;
247     }
248     }
249    
250     @Override
251     protected Dialog onCreateDialog(int id) {
252     switch (id) {
253     case DLG_PROGRESS:
254 torben 835
255 torben 237 ProgressDialog dlg = new ProgressDialog(this);
256     dlg.setCancelable(true);
257 torben 362 return dlg;
258 torben 237 default:
259     return super.onCreateDialog(id);
260     }
261     }
262 torben 982
263    
264 torben 336
265 torben 982
266    
267     @Override
268     public boolean onCreateOptionsMenu(Menu menu) {
269     MenuItem item;
270 torben 985
271     item = menu.add(0, MENU_MAP, 0, getString(R.string.departurelist_showonmap) );
272 torben 982 item.setIcon(android.R.drawable.ic_menu_mapmode);
273    
274 torben 985 item = menu.add(0, MENU_NOTIFICATIONS, 0, getString(R.string.departurelist_notifications) );
275 torben 982 item.setIcon(android.R.drawable.ic_menu_info_details);
276    
277    
278     boolean notifEnabled = hasNotifications();
279     item.setEnabled(notifEnabled);
280    
281    
282     return true;
283     }
284    
285     @Override
286     public boolean onOptionsItemSelected(MenuItem item) {
287     boolean res;
288     switch(item.getItemId()) {
289     case MENU_MAP:
290     Uri uri = Uri.parse("geo:" + station.getLatitude() + "," + station.getLongitude());
291     startActivity( new Intent(Intent.ACTION_VIEW, uri));
292     res = true;
293     break;
294     case MENU_NOTIFICATIONS:
295     Intent i = new Intent(this,dk.thoerup.traininfo.NotificationList.class);
296     i.putExtra(NotificationList.EXTRA_NOTIFICATIONS, departures.notifications);
297     startActivity(i);
298     res = true;
299     break;
300     default:
301     res = super.onOptionsItemSelected(item);
302     }
303     return res;
304     }
305    
306 torben 336 void startDepartureFetcher() {
307     showDialog(DLG_PROGRESS);
308     fetcher = new DepartureFetcher();
309 torben 557 fetcher.execute(station.getId());
310 torben 336 }
311 torben 316
312 torben 1053 void startMetroFetcher() {
313     showDialog(DLG_PROGRESS);
314     metroFetcher = new MetroFetcher();
315     metroFetcher.execute(station.getId());
316     }
317    
318 torben 237 class DialogDismisser implements View.OnClickListener {
319    
320     Dialog dlg;
321     public DialogDismisser(Dialog d) {
322     dlg = d;
323     }
324    
325     @Override
326     public void onClick(View v) {
327     if (dlg.isShowing())
328     dlg.dismiss();
329 torben 365 }
330     }
331 torben 238
332 torben 982 /*View.OnClickListener mapLauncher = new View.OnClickListener() {
333 torben 239 @Override
334 torben 557 public void onClick(View v) {
335     Uri uri = Uri.parse("geo:" + station.getLatitude() + "," + station.getLongitude());
336 torben 239 startActivity( new Intent(Intent.ACTION_VIEW, uri));
337     }
338 torben 982 };*/
339 torben 336
340    
341 torben 238
342 torben 310 class DepartureFetcher extends AsyncTask<Integer, Void, Void> {
343 torben 238
344     @Override
345     protected void onPostExecute(Void result) {
346     super.onPostExecute(result);
347    
348 torben 336
349 torben 238 pgDialog.dismiss();
350    
351 torben 1007 if (departures != null) {
352 torben 1017 commFailCounter = 0;
353 torben 917 DepartureList.this.getListView().setVisibility(View.GONE); //Experimental, inspired by http://osdir.com/ml/Android-Developers/2010-04/msg01198.html
354 torben 981 adapter.setDepartures(departures.entries);
355 torben 917 DepartureList.this.getListView().setVisibility(View.VISIBLE);
356    
357 torben 982
358     if ( hasNotifications() ) {
359     findViewById(R.id.notifIcon).setVisibility(View.VISIBLE);
360     }
361    
362 torben 981 if (departures.entries.size() == 0) {
363 torben 906 MessageBox.showMessage(DepartureList.this, "No departures found", true);
364 torben 319 }
365     } else { // communication or parse error
366 torben 1017 commFailCounter++;
367 torben 336 AlertDialog.Builder builder = new AlertDialog.Builder(DepartureList.this);
368     builder.setMessage("Error finding departures");
369     builder.setCancelable(true);
370 torben 1017 if (commFailCounter < 3) {
371     builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
372     public void onClick(DialogInterface dialog, int id) {
373     dialog.dismiss();
374     startDepartureFetcher();
375    
376     }
377     });
378     }
379 torben 561 builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
380 torben 336 public void onClick(DialogInterface dialog, int id) {
381     dialog.dismiss();
382 torben 843 DepartureList.this.finish();
383 torben 336 }
384 torben 630 });
385    
386     try {
387     builder.show();
388     } catch (android.view.WindowManager.BadTokenException e) {
389     Log.i("DepartureList", "BadTokenException"); // this can happen if the user switched away from this activity, while doInBackground was running
390     }
391 torben 319 }
392 torben 238 }
393    
394     @Override
395 torben 310 protected Void doInBackground(Integer... params) {
396 torben 1007 departures = provider.lookupDepartures(params[0], DepartureList.this.arrival);
397 torben 238 return null;
398     }
399    
400     }
401 torben 1053
402     public void loadMetroData() {
403     ((TextView) findViewById(R.id.operations)).setText( metroBean.operationInfo );
404     ((TextView) findViewById(R.id.plan)).setText( metroBean.plan );
405    
406    
407     TableLayout table = (TableLayout) findViewById(R.id.metrotable);
408     table.removeAllViews();
409    
410     TableRow head = new TableRow(this);
411    
412     TextView h1 = new TextView(this);
413     h1.setText("Metro");
414     h1.setTypeface( Typeface.defaultFromStyle(Typeface.BOLD));
415    
416    
417     TableRow.LayoutParams params = new TableRow.LayoutParams();
418     params.span = 2;
419     head.addView(h1, params);
420    
421     TextView h2 = new TextView(this);
422     h2.setText("Om minutte");
423     h2.setTypeface( Typeface.defaultFromStyle(Typeface.BOLD));
424     head.addView(h2);
425    
426    
427    
428     table.addView(head);
429    
430     for (MetroEntry entry : metroBean.entries) {
431     TableRow row = new TableRow(this);
432    
433     Log.e("Test", "" + entry.destination);
434    
435     TextView v1 = new TextView(this);
436     v1.setText( entry.metro );
437     row.addView(v1);
438    
439     TextView v2 = new TextView(this);
440     v2.setText( entry.destination );
441     row.addView(v2);
442    
443     TextView v3 = new TextView(this);
444     v3.setText( entry.minutes );
445     row.addView(v3);
446    
447     table.addView(row);
448    
449     }
450     findViewById(R.id.rootView).requestLayout();
451     }
452    
453     class MetroFetcher extends AsyncTask<Integer, Void, Void> {
454    
455     @Override
456     protected void onPostExecute(Void result) {
457     super.onPostExecute(result);
458    
459    
460    
461     pgDialog.dismiss();
462    
463     if (metroBean != null) {
464     loadMetroData();
465     } else { // communication or parse error
466     commFailCounter++;
467     AlertDialog.Builder builder = new AlertDialog.Builder(DepartureList.this);
468     builder.setMessage("Error finding metro data");
469     builder.setCancelable(true);
470     if (commFailCounter < 3) {
471     builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
472     public void onClick(DialogInterface dialog, int id) {
473     dialog.dismiss();
474     startMetroFetcher();
475    
476     }
477     });
478     }
479     builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
480     public void onClick(DialogInterface dialog, int id) {
481     dialog.dismiss();
482     DepartureList.this.finish();
483     }
484     });
485    
486     try {
487     builder.show();
488     } catch (android.view.WindowManager.BadTokenException e) {
489     Log.i("DepartureList", "BadTokenException"); // this can happen if the user switched away from this activity, while doInBackground was running
490     }
491     }
492     }
493    
494     @Override
495     protected Void doInBackground(Integer... params) {
496     metroBean = metro.lookupMetroInfo(params[0]);
497     return null;
498     }
499    
500     }
501    
502 torben 237 }

  ViewVC Help
Powered by ViewVC 1.1.20