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

  ViewVC Help
Powered by ViewVC 1.1.20