/[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 1432 - (hide annotations) (download)
Tue May 3 12:35:34 2011 UTC (13 years ago) by torben
File size: 18266 byte(s)
don't crash if we couln't launch google maps (or other geo: uri handler)
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 1432 try {
368     Uri uri = Uri.parse("geo:" + station.getLatitude() + "," + station.getLongitude() + "?z=16");
369     startActivity( new Intent(Intent.ACTION_VIEW, uri));
370     } catch (ActivityNotFoundException anfe) {
371     Toast.makeText(this, "Could not launch google maps", Toast.LENGTH_LONG).show();
372     }
373 torben 982 res = true;
374     break;
375     case MENU_NOTIFICATIONS:
376     Intent i = new Intent(this,dk.thoerup.traininfo.NotificationList.class);
377     i.putExtra(NotificationList.EXTRA_NOTIFICATIONS, departures.notifications);
378     startActivity(i);
379     res = true;
380     break;
381 torben 1057 case MENU_METROMAP:
382     Intent metroMap = new Intent(this,dk.thoerup.traininfo.MetroMap.class);
383     startActivity(metroMap);
384     res = true;
385     break;
386 torben 982 default:
387     res = super.onOptionsItemSelected(item);
388     }
389     return res;
390     }
391    
392 torben 336 void startDepartureFetcher() {
393     showDialog(DLG_PROGRESS);
394     fetcher = new DepartureFetcher();
395 torben 557 fetcher.execute(station.getId());
396 torben 336 }
397 torben 316
398 torben 1053 void startMetroFetcher() {
399     showDialog(DLG_PROGRESS);
400     metroFetcher = new MetroFetcher();
401     metroFetcher.execute(station.getId());
402     }
403    
404 torben 237 class DialogDismisser implements View.OnClickListener {
405    
406     Dialog dlg;
407     public DialogDismisser(Dialog d) {
408     dlg = d;
409     }
410    
411     @Override
412     public void onClick(View v) {
413     if (dlg.isShowing())
414     dlg.dismiss();
415 torben 365 }
416     }
417 torben 238
418 torben 982 /*View.OnClickListener mapLauncher = new View.OnClickListener() {
419 torben 239 @Override
420 torben 557 public void onClick(View v) {
421     Uri uri = Uri.parse("geo:" + station.getLatitude() + "," + station.getLongitude());
422 torben 239 startActivity( new Intent(Intent.ACTION_VIEW, uri));
423     }
424 torben 982 };*/
425 torben 336
426    
427 torben 238
428 torben 310 class DepartureFetcher extends AsyncTask<Integer, Void, Void> {
429 torben 238
430     @Override
431     protected void onPostExecute(Void result) {
432     super.onPostExecute(result);
433    
434 torben 336
435 torben 238 pgDialog.dismiss();
436 torben 1423
437 torben 1373 if (departures != null && departures.errorCode == null) {
438 torben 1017 commFailCounter = 0;
439 torben 917 DepartureList.this.getListView().setVisibility(View.GONE); //Experimental, inspired by http://osdir.com/ml/Android-Developers/2010-04/msg01198.html
440 torben 981 adapter.setDepartures(departures.entries);
441 torben 917 DepartureList.this.getListView().setVisibility(View.VISIBLE);
442    
443 torben 982
444 torben 1261 // handle notification icon.
445 torben 982 if ( hasNotifications() ) {
446 torben 1261 View notifIcon = findViewById(R.id.notifIcon);
447     notifIcon.setVisibility(View.VISIBLE);
448     notifIcon.setClickable(true);
449     notifIcon.setOnClickListener( new View.OnClickListener() {
450     @Override
451     public void onClick(View v) {
452     Intent i = new Intent(DepartureList.this, dk.thoerup.traininfo.NotificationList.class);
453     i.putExtra(NotificationList.EXTRA_NOTIFICATIONS, departures.notifications);
454     startActivity(i);
455     }
456     });
457     }
458 torben 982
459 torben 1264 if (departures.entries.size() == 0) {
460 torben 1262 int msgId = (arrival==false) ? R.string.departurelist_nodepartures : R.string.departurelist_noarrivals;
461     MessageBox.showMessage(DepartureList.this, getString(msgId), false);
462 torben 319 }
463     } else { // communication or parse error
464 torben 1017 commFailCounter++;
465 torben 1373 AlertDialog.Builder builder = new AlertDialog.Builder(DepartureList.this);
466    
467     if (departures != null && departures.errorCode != null ) { //got an error xml back
468     commFailCounter = 10;
469     builder.setMessage( getString(R.string.no_backend) );
470     } else {
471     builder.setMessage( getString(R.string.departurelist_fetcherror) );
472     }
473 torben 336 builder.setCancelable(true);
474 torben 1373
475 torben 1017 if (commFailCounter < 3) {
476     builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
477     public void onClick(DialogInterface dialog, int id) {
478     dialog.dismiss();
479     startDepartureFetcher();
480    
481     }
482     });
483     }
484 torben 561 builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
485 torben 336 public void onClick(DialogInterface dialog, int id) {
486     dialog.dismiss();
487 torben 843 DepartureList.this.finish();
488 torben 336 }
489 torben 630 });
490    
491 torben 1263 try { //TODO: is this still necessary after the 0.9.4.1 fix ?
492 torben 630 builder.show();
493     } catch (android.view.WindowManager.BadTokenException e) {
494     Log.i("DepartureList", "BadTokenException"); // this can happen if the user switched away from this activity, while doInBackground was running
495     }
496 torben 319 }
497 torben 238 }
498    
499     @Override
500 torben 310 protected Void doInBackground(Integer... params) {
501 torben 1250 departures = provider.lookupDepartures(params[0], DepartureList.this.arrival, trainType);
502 torben 238 return null;
503     }
504    
505     }
506 torben 1053
507     public void loadMetroData() {
508     ((TextView) findViewById(R.id.operations)).setText( metroBean.operationInfo );
509     ((TextView) findViewById(R.id.plan)).setText( metroBean.plan );
510    
511    
512     TableLayout table = (TableLayout) findViewById(R.id.metrotable);
513     table.removeAllViews();
514    
515     TableRow head = new TableRow(this);
516    
517     TextView h1 = new TextView(this);
518     h1.setText("Metro");
519 torben 1072 h1.setTextSize(16);
520 torben 1053 h1.setTypeface( Typeface.defaultFromStyle(Typeface.BOLD));
521    
522    
523     TableRow.LayoutParams params = new TableRow.LayoutParams();
524     params.span = 2;
525     head.addView(h1, params);
526    
527 torben 1055
528    
529 torben 1053 TextView h2 = new TextView(this);
530 torben 1072 h2.setTextSize(16);
531 torben 1053 h2.setTypeface( Typeface.defaultFromStyle(Typeface.BOLD));
532 torben 1055 h2.setText("Om minutter");
533    
534 torben 1072 params = new TableRow.LayoutParams();
535     params.weight = 2;
536 torben 1055 head.addView(h2,params);
537 torben 1053
538    
539    
540     table.addView(head);
541    
542     for (MetroEntry entry : metroBean.entries) {
543     TableRow row = new TableRow(this);
544    
545     Log.e("Test", "" + entry.destination);
546    
547     TextView v1 = new TextView(this);
548 torben 1072 v1.setTextSize(16);
549     v1.setText( entry.metro );
550 torben 1053 row.addView(v1);
551    
552     TextView v2 = new TextView(this);
553 torben 1072 v2.setTextSize(16);
554 torben 1053 v2.setText( entry.destination );
555     row.addView(v2);
556 torben 1055
557 torben 1053 TextView v3 = new TextView(this);
558 torben 1072 v3.setTextSize(16);
559 torben 1053 v3.setText( entry.minutes );
560     row.addView(v3);
561    
562     table.addView(row);
563    
564     }
565     findViewById(R.id.rootView).requestLayout();
566     }
567    
568     class MetroFetcher extends AsyncTask<Integer, Void, Void> {
569    
570     @Override
571     protected void onPostExecute(Void result) {
572     super.onPostExecute(result);
573    
574    
575    
576     pgDialog.dismiss();
577    
578     if (metroBean != null) {
579     loadMetroData();
580     } else { // communication or parse error
581     commFailCounter++;
582     AlertDialog.Builder builder = new AlertDialog.Builder(DepartureList.this);
583     builder.setMessage("Error finding metro data");
584     builder.setCancelable(true);
585     if (commFailCounter < 3) {
586     builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
587     public void onClick(DialogInterface dialog, int id) {
588     dialog.dismiss();
589     startMetroFetcher();
590    
591     }
592     });
593     }
594     builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
595     public void onClick(DialogInterface dialog, int id) {
596     dialog.dismiss();
597 torben 1263 DepartureList.this.finish(); //TODO: should we really close the activity ??
598 torben 1053 }
599     });
600    
601 torben 1263 try { //TODO: is this still necessary after the 0.9.4.1 fix ?
602 torben 1053 builder.show();
603     } catch (android.view.WindowManager.BadTokenException e) {
604     Log.i("DepartureList", "BadTokenException"); // this can happen if the user switched away from this activity, while doInBackground was running
605     }
606     }
607     }
608    
609     @Override
610     protected Void doInBackground(Integer... params) {
611     metroBean = metro.lookupMetroInfo(params[0]);
612     return null;
613     }
614    
615     }
616    
617 torben 237 }

  ViewVC Help
Powered by ViewVC 1.1.20