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

  ViewVC Help
Powered by ViewVC 1.1.20