/[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 1423 - (hide annotations) (download)
Mon May 2 17:14:29 2011 UTC (13 years ago) by torben
File size: 18115 byte(s)
Remove completed todo's - we actually can differentiate between comm errors and downed backend site
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 1066 import dk.thoerup.android.traininfo.common.DepartureBean;
31     import dk.thoerup.android.traininfo.common.DepartureEntry;
32     import dk.thoerup.android.traininfo.common.MetroBean;
33     import dk.thoerup.android.traininfo.common.MetroBean.MetroEntry;
34 torben 1408 import dk.thoerup.android.traininfo.common.StationEntry;
35 torben 255 import dk.thoerup.traininfo.provider.DepartureProvider;
36 torben 1053 import dk.thoerup.traininfo.provider.MetroProvider;
37 torben 253 import dk.thoerup.traininfo.provider.ProviderFactory;
38 torben 245 import dk.thoerup.traininfo.util.MessageBox;
39 torben 237
40     public class DepartureList extends ListActivity {
41    
42     public static final int DLG_PROGRESS = 1;
43 torben 982 static final int MENU_MAP = 100;
44     static final int MENU_NOTIFICATIONS = 101;
45 torben 1057 static final int MENU_METROMAP= 102;
46 torben 237
47 torben 362
48 torben 237 DepartureListAdapter adapter;
49     DepartureProvider provider;
50 torben 981 DepartureBean departures;
51 torben 237
52 torben 1053 MetroBean metroBean;
53     MetroProvider metro;
54    
55 torben 257 int selectedItemId;
56     //DepartureBean currentDeparture;
57 torben 237
58     ProgressDialog pgDialog;
59 torben 362
60 torben 238 DepartureFetcher fetcher;
61 torben 1053 MetroFetcher metroFetcher;
62 torben 557
63 torben 1066 StationEntry station;
64 torben 238
65 torben 1250 String trainType = "REGIONAL";
66    
67 torben 835 boolean arrival = false;
68 torben 981
69 torben 1017 int commFailCounter = 0;
70    
71 torben 237 @Override
72     protected void onCreate(Bundle savedInstanceState) {
73     super.onCreate(savedInstanceState);
74     setContentView(R.layout.departurelist);
75    
76     adapter = new DepartureListAdapter(this);
77     setListAdapter(adapter);
78    
79     Intent launchedBy = getIntent();
80 torben 557
81 torben 1066 station = (StationEntry) launchedBy.getSerializableExtra("stationbean");
82 torben 239
83 torben 557 ((TextView) findViewById(R.id.stationName)).setText( station.getName() );
84 torben 317
85 torben 557
86     ((TextView) findViewById(R.id.stationAddr)).setText( station.getAddress() );
87 torben 237
88 torben 835 final Button departureBtn = (Button) findViewById(R.id.departurebtn);
89     final Button arrivalBtn = (Button) findViewById(R.id.arrivalbtn);
90 torben 1044 final Button metroBtn = (Button) findViewById(R.id.metrobtn);
91 torben 1250 final Button regionalBtn = (Button) findViewById(R.id.regionalbtn);
92     final Button stogBtn = (Button) findViewById(R.id.stogbtn);
93 torben 294
94 torben 1053 final View metroView = findViewById(R.id.metroonly);
95    
96 torben 835 departureBtn.setOnClickListener( new OnClickListener() {
97     @Override
98     public void onClick(View arg0) {
99     arrivalBtn.setBackgroundResource(R.drawable.custom_button);
100     departureBtn.setBackgroundResource(R.drawable.custom_button_hilight);
101 torben 1044 metroBtn.setBackgroundResource(R.drawable.custom_button);
102 torben 1053
103     getListView().setVisibility( View.VISIBLE );
104     metroView.setVisibility( View.GONE );
105 torben 835 arrival = false;
106     startDepartureFetcher();
107     }
108     });
109     arrivalBtn.setOnClickListener( new OnClickListener() {
110     @Override
111     public void onClick(View arg0) {
112     arrivalBtn.setBackgroundResource(R.drawable.custom_button_hilight);
113     departureBtn.setBackgroundResource(R.drawable.custom_button);
114 torben 1044 metroBtn.setBackgroundResource(R.drawable.custom_button);
115 torben 1053
116     getListView().setVisibility( View.VISIBLE );
117     metroView.setVisibility( View.GONE );
118 torben 835 arrival = true;
119     startDepartureFetcher();
120     }
121     });
122    
123 torben 1250 regionalBtn.setOnClickListener( new OnClickListener() {
124     @Override
125     public void onClick(View arg0) {
126     regionalBtn.setBackgroundResource(R.drawable.custom_button_hilight);
127     stogBtn.setBackgroundResource(R.drawable.custom_button);
128     metroBtn.setBackgroundResource(R.drawable.custom_button);
129    
130     departureBtn.setVisibility( View.VISIBLE );
131     arrivalBtn.setVisibility( View.VISIBLE );
132    
133     getListView().setVisibility( View.VISIBLE );
134     metroView.setVisibility( View.GONE );
135     trainType = "REGIONAL";
136     startDepartureFetcher();
137     }
138     });
139     stogBtn.setOnClickListener( new OnClickListener() {
140     @Override
141     public void onClick(View arg0) {
142     regionalBtn.setBackgroundResource(R.drawable.custom_button);
143     stogBtn.setBackgroundResource(R.drawable.custom_button_hilight);
144     metroBtn.setBackgroundResource(R.drawable.custom_button);
145    
146    
147     departureBtn.setVisibility( View.VISIBLE );
148     arrivalBtn.setVisibility( View.VISIBLE );
149    
150     getListView().setVisibility( View.VISIBLE );
151     metroView.setVisibility( View.GONE );
152     trainType = "STOG";
153     startDepartureFetcher();
154     }
155     });
156    
157    
158    
159 torben 1044 metroBtn.setOnClickListener( new OnClickListener() {
160     @Override
161     public void onClick(View v) {
162 torben 1250 regionalBtn.setBackgroundResource(R.drawable.custom_button);
163     stogBtn.setBackgroundResource(R.drawable.custom_button);
164 torben 1044 metroBtn.setBackgroundResource(R.drawable.custom_button_hilight);
165 torben 1053
166 torben 1250 departureBtn.setVisibility( View.GONE );
167     arrivalBtn.setVisibility( View.GONE );
168    
169 torben 1053 getListView().setVisibility( View.GONE );
170     metroView.setVisibility( View.VISIBLE );
171     startMetroFetcher();
172 torben 1044 }
173     });
174 torben 835
175    
176    
177 torben 1044
178 torben 982 // findViewById(R.id.header).setOnClickListener( mapLauncher );
179 torben 237
180 torben 1066 int distance = station.getCalcdist();
181 torben 742 if (distance != 0) {
182     NumberFormat format = NumberFormat.getNumberInstance();
183     format.setMaximumFractionDigits(1);
184     format.setMinimumFractionDigits(1);
185 torben 575
186 torben 742 ((TextView) findViewById(R.id.stationDistance)).setText( format.format((double)distance/1000.0) + " km." );
187     } else {
188     ((TextView) findViewById(R.id.stationDistance)).setVisibility(View.GONE);
189     }
190 torben 552
191 torben 1028 ProviderFactory.purgeOldEntries(); //cleanup before fetching more data
192 torben 1044
193     Log.e("Station", station.toCSV() );
194    
195     if (station.isMetro() == false) {
196     metroBtn.setVisibility( View.GONE );
197     }
198 torben 1028
199 torben 1053 metro = ProviderFactory.getMetroProvider();
200    
201 torben 1250 if (station.isRegional() == false ) {
202     regionalBtn.setVisibility(View.GONE);
203     }
204    
205     if (station.isStrain() == false ) {
206     stogBtn.setVisibility(View.GONE);
207     }
208    
209     if (station.isRegional() == true && station.isStrain() == false ) {
210     if ( station.isMetro() == false )
211     regionalBtn.setVisibility(View.GONE);
212     trainType = "REGIONAL";
213     }
214    
215     if (station.isRegional() == false && station.isStrain() == true) {
216     if (station.isMetro() == false)
217     stogBtn.setVisibility(View.GONE);
218    
219     stogBtn.setBackgroundResource(R.drawable.custom_button_hilight);
220     trainType = "STOG";
221    
222     }
223    
224    
225 torben 1066 if (station.isRegional() == false && station.isStrain() == false) {
226 torben 552 getListView().setVisibility( View.GONE );
227 torben 1053 metroView.setVisibility( View.VISIBLE );
228    
229 torben 835 departureBtn.setVisibility( View.GONE );
230     arrivalBtn.setVisibility(View.GONE);
231 torben 1250 metroBtn.setVisibility( View.GONE );
232 torben 552
233 torben 1250
234    
235 torben 1053 if (savedInstanceState == null) {
236     startMetroFetcher();
237     } else {
238     metroBean = (MetroBean) savedInstanceState.getSerializable("metro");
239     loadMetroData();
240     }
241    
242 torben 257 } else {
243 torben 552 provider = ProviderFactory.getDepartureProvider();
244    
245     if (savedInstanceState == null) {
246     startDepartureFetcher();
247     } else {
248 torben 981 departures = (DepartureBean) savedInstanceState.getSerializable("departures");
249 torben 990
250     if ( (departures != null) && (departures.entries != null) ) {
251     adapter.setDepartures(departures.entries);
252     }
253 torben 982 selectedItemId = savedInstanceState.getInt("selectedItemId");
254    
255     if ( hasNotifications() ) {
256     findViewById(R.id.notifIcon).setVisibility(View.VISIBLE);
257     }
258    
259 torben 552 }
260 torben 257 }
261 torben 237 }
262    
263 torben 982 boolean hasNotifications() {
264     return (departures != null && departures.notifications.size() > 0);
265     }
266    
267 torben 243 @Override
268     public void onSaveInstanceState(Bundle outState)
269     {
270 torben 257 if (pgDialog != null && pgDialog.isShowing())
271     dismissDialog(DLG_PROGRESS);
272 torben 362
273 torben 257 outState.putInt("selectedItemId", selectedItemId);
274    
275 torben 981 outState.putSerializable("departures", departures);
276 torben 1053 outState.putSerializable("metro", metroBean);
277 torben 243 }
278 torben 918
279    
280 torben 243
281 torben 237 @Override
282 torben 918 protected void onDestroy() {
283     super.onDestroy();
284    
285     if (fetcher != null) {
286     fetcher.cancel(true);
287     }
288 torben 1053
289     if (metroFetcher != null) {
290     metroFetcher.cancel(true);
291     }
292 torben 918 }
293    
294     @Override
295 torben 237 protected void onListItemClick(ListView l, View v, int position, long id) {
296     super.onListItemClick(l, v, position, id);
297 torben 362
298     selectedItemId = position;
299 torben 364
300 torben 981 DepartureEntry dep = departures.entries.get(selectedItemId);
301 torben 237
302 torben 362 Intent intent = new Intent(this, TimetableList.class);
303 torben 364 intent.putExtra("departure", dep);
304 torben 362
305     startActivity(intent);
306    
307 torben 237 }
308    
309    
310     @Override
311     protected void onPrepareDialog(int id, Dialog dialog) {
312     super.onPrepareDialog(id, dialog);
313 torben 257
314 torben 237 switch (id) {
315     case DLG_PROGRESS:
316     pgDialog = (ProgressDialog) dialog;
317 torben 835 int messageId = arrival == false ? departurelist_fetchdepartures : departurelist_fetcharrivals;
318     pgDialog.setMessage( getString(messageId) );
319 torben 237 break;
320     }
321     }
322    
323     @Override
324     protected Dialog onCreateDialog(int id) {
325     switch (id) {
326     case DLG_PROGRESS:
327 torben 835
328 torben 237 ProgressDialog dlg = new ProgressDialog(this);
329     dlg.setCancelable(true);
330 torben 362 return dlg;
331 torben 237 default:
332     return super.onCreateDialog(id);
333     }
334     }
335 torben 982
336    
337 torben 336
338 torben 982
339    
340     @Override
341     public boolean onCreateOptionsMenu(Menu menu) {
342     MenuItem item;
343 torben 985
344     item = menu.add(0, MENU_MAP, 0, getString(R.string.departurelist_showonmap) );
345 torben 982 item.setIcon(android.R.drawable.ic_menu_mapmode);
346    
347 torben 985 item = menu.add(0, MENU_NOTIFICATIONS, 0, getString(R.string.departurelist_notifications) );
348 torben 1057 item.setIcon(android.R.drawable.ic_menu_info_details);
349 torben 982
350     boolean notifEnabled = hasNotifications();
351     item.setEnabled(notifEnabled);
352    
353 torben 1057 if (station.isMetro()) {
354     item = menu.add(0, MENU_METROMAP, 0, "Metro" ); //TODO:translate!?!
355     item.setIcon(android.R.drawable.ic_menu_mapmode);
356     }
357    
358 torben 982
359     return true;
360     }
361    
362     @Override
363     public boolean onOptionsItemSelected(MenuItem item) {
364     boolean res;
365     switch(item.getItemId()) {
366     case MENU_MAP:
367 torben 1152 Uri uri = Uri.parse("geo:" + station.getLatitude() + "," + station.getLongitude() + "?z=16");
368 torben 982 startActivity( new Intent(Intent.ACTION_VIEW, uri));
369     res = true;
370     break;
371     case MENU_NOTIFICATIONS:
372     Intent i = new Intent(this,dk.thoerup.traininfo.NotificationList.class);
373     i.putExtra(NotificationList.EXTRA_NOTIFICATIONS, departures.notifications);
374     startActivity(i);
375     res = true;
376     break;
377 torben 1057 case MENU_METROMAP:
378     Intent metroMap = new Intent(this,dk.thoerup.traininfo.MetroMap.class);
379     startActivity(metroMap);
380     res = true;
381     break;
382 torben 982 default:
383     res = super.onOptionsItemSelected(item);
384     }
385     return res;
386     }
387    
388 torben 336 void startDepartureFetcher() {
389     showDialog(DLG_PROGRESS);
390     fetcher = new DepartureFetcher();
391 torben 557 fetcher.execute(station.getId());
392 torben 336 }
393 torben 316
394 torben 1053 void startMetroFetcher() {
395     showDialog(DLG_PROGRESS);
396     metroFetcher = new MetroFetcher();
397     metroFetcher.execute(station.getId());
398     }
399    
400 torben 237 class DialogDismisser implements View.OnClickListener {
401    
402     Dialog dlg;
403     public DialogDismisser(Dialog d) {
404     dlg = d;
405     }
406    
407     @Override
408     public void onClick(View v) {
409     if (dlg.isShowing())
410     dlg.dismiss();
411 torben 365 }
412     }
413 torben 238
414 torben 982 /*View.OnClickListener mapLauncher = new View.OnClickListener() {
415 torben 239 @Override
416 torben 557 public void onClick(View v) {
417     Uri uri = Uri.parse("geo:" + station.getLatitude() + "," + station.getLongitude());
418 torben 239 startActivity( new Intent(Intent.ACTION_VIEW, uri));
419     }
420 torben 982 };*/
421 torben 336
422    
423 torben 238
424 torben 310 class DepartureFetcher extends AsyncTask<Integer, Void, Void> {
425 torben 238
426     @Override
427     protected void onPostExecute(Void result) {
428     super.onPostExecute(result);
429    
430 torben 336
431 torben 238 pgDialog.dismiss();
432 torben 1423
433 torben 1373 if (departures != null && departures.errorCode == null) {
434 torben 1017 commFailCounter = 0;
435 torben 917 DepartureList.this.getListView().setVisibility(View.GONE); //Experimental, inspired by http://osdir.com/ml/Android-Developers/2010-04/msg01198.html
436 torben 981 adapter.setDepartures(departures.entries);
437 torben 917 DepartureList.this.getListView().setVisibility(View.VISIBLE);
438    
439 torben 982
440 torben 1261 // handle notification icon.
441 torben 982 if ( hasNotifications() ) {
442 torben 1261 View notifIcon = findViewById(R.id.notifIcon);
443     notifIcon.setVisibility(View.VISIBLE);
444     notifIcon.setClickable(true);
445     notifIcon.setOnClickListener( new View.OnClickListener() {
446     @Override
447     public void onClick(View v) {
448     Intent i = new Intent(DepartureList.this, dk.thoerup.traininfo.NotificationList.class);
449     i.putExtra(NotificationList.EXTRA_NOTIFICATIONS, departures.notifications);
450     startActivity(i);
451     }
452     });
453     }
454 torben 982
455 torben 1264 if (departures.entries.size() == 0) {
456 torben 1262 int msgId = (arrival==false) ? R.string.departurelist_nodepartures : R.string.departurelist_noarrivals;
457     MessageBox.showMessage(DepartureList.this, getString(msgId), false);
458 torben 319 }
459     } else { // communication or parse error
460 torben 1017 commFailCounter++;
461 torben 1373 AlertDialog.Builder builder = new AlertDialog.Builder(DepartureList.this);
462    
463     if (departures != null && departures.errorCode != null ) { //got an error xml back
464     commFailCounter = 10;
465     builder.setMessage( getString(R.string.no_backend) );
466     } else {
467     builder.setMessage( getString(R.string.departurelist_fetcherror) );
468     }
469 torben 336 builder.setCancelable(true);
470 torben 1373
471 torben 1017 if (commFailCounter < 3) {
472     builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
473     public void onClick(DialogInterface dialog, int id) {
474     dialog.dismiss();
475     startDepartureFetcher();
476    
477     }
478     });
479     }
480 torben 561 builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
481 torben 336 public void onClick(DialogInterface dialog, int id) {
482     dialog.dismiss();
483 torben 843 DepartureList.this.finish();
484 torben 336 }
485 torben 630 });
486    
487 torben 1263 try { //TODO: is this still necessary after the 0.9.4.1 fix ?
488 torben 630 builder.show();
489     } catch (android.view.WindowManager.BadTokenException e) {
490     Log.i("DepartureList", "BadTokenException"); // this can happen if the user switched away from this activity, while doInBackground was running
491     }
492 torben 319 }
493 torben 238 }
494    
495     @Override
496 torben 310 protected Void doInBackground(Integer... params) {
497 torben 1250 departures = provider.lookupDepartures(params[0], DepartureList.this.arrival, trainType);
498 torben 238 return null;
499     }
500    
501     }
502 torben 1053
503     public void loadMetroData() {
504     ((TextView) findViewById(R.id.operations)).setText( metroBean.operationInfo );
505     ((TextView) findViewById(R.id.plan)).setText( metroBean.plan );
506    
507    
508     TableLayout table = (TableLayout) findViewById(R.id.metrotable);
509     table.removeAllViews();
510    
511     TableRow head = new TableRow(this);
512    
513     TextView h1 = new TextView(this);
514     h1.setText("Metro");
515 torben 1072 h1.setTextSize(16);
516 torben 1053 h1.setTypeface( Typeface.defaultFromStyle(Typeface.BOLD));
517    
518    
519     TableRow.LayoutParams params = new TableRow.LayoutParams();
520     params.span = 2;
521     head.addView(h1, params);
522    
523 torben 1055
524    
525 torben 1053 TextView h2 = new TextView(this);
526 torben 1072 h2.setTextSize(16);
527 torben 1053 h2.setTypeface( Typeface.defaultFromStyle(Typeface.BOLD));
528 torben 1055 h2.setText("Om minutter");
529    
530 torben 1072 params = new TableRow.LayoutParams();
531     params.weight = 2;
532 torben 1055 head.addView(h2,params);
533 torben 1053
534    
535    
536     table.addView(head);
537    
538     for (MetroEntry entry : metroBean.entries) {
539     TableRow row = new TableRow(this);
540    
541     Log.e("Test", "" + entry.destination);
542    
543     TextView v1 = new TextView(this);
544 torben 1072 v1.setTextSize(16);
545     v1.setText( entry.metro );
546 torben 1053 row.addView(v1);
547    
548     TextView v2 = new TextView(this);
549 torben 1072 v2.setTextSize(16);
550 torben 1053 v2.setText( entry.destination );
551     row.addView(v2);
552 torben 1055
553 torben 1053 TextView v3 = new TextView(this);
554 torben 1072 v3.setTextSize(16);
555 torben 1053 v3.setText( entry.minutes );
556     row.addView(v3);
557    
558     table.addView(row);
559    
560     }
561     findViewById(R.id.rootView).requestLayout();
562     }
563    
564     class MetroFetcher extends AsyncTask<Integer, Void, Void> {
565    
566     @Override
567     protected void onPostExecute(Void result) {
568     super.onPostExecute(result);
569    
570    
571    
572     pgDialog.dismiss();
573    
574     if (metroBean != null) {
575     loadMetroData();
576     } else { // communication or parse error
577     commFailCounter++;
578     AlertDialog.Builder builder = new AlertDialog.Builder(DepartureList.this);
579     builder.setMessage("Error finding metro data");
580     builder.setCancelable(true);
581     if (commFailCounter < 3) {
582     builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
583     public void onClick(DialogInterface dialog, int id) {
584     dialog.dismiss();
585     startMetroFetcher();
586    
587     }
588     });
589     }
590     builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
591     public void onClick(DialogInterface dialog, int id) {
592     dialog.dismiss();
593 torben 1263 DepartureList.this.finish(); //TODO: should we really close the activity ??
594 torben 1053 }
595     });
596    
597 torben 1263 try { //TODO: is this still necessary after the 0.9.4.1 fix ?
598 torben 1053 builder.show();
599     } catch (android.view.WindowManager.BadTokenException e) {
600     Log.i("DepartureList", "BadTokenException"); // this can happen if the user switched away from this activity, while doInBackground was running
601     }
602     }
603     }
604    
605     @Override
606     protected Void doInBackground(Integer... params) {
607     metroBean = metro.lookupMetroInfo(params[0]);
608     return null;
609     }
610    
611     }
612    
613 torben 237 }

  ViewVC Help
Powered by ViewVC 1.1.20