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

  ViewVC Help
Powered by ViewVC 1.1.20