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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20