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

  ViewVC Help
Powered by ViewVC 1.1.20