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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1006 - (show annotations) (download)
Mon Aug 2 23:18:53 2010 UTC (13 years, 9 months ago) by torben
File size: 17777 byte(s)
Go away from 2-step station lookup (so now station-cache actually works)

No i just need to do the same operation for the 2 other xml providers
1 package dk.thoerup.traininfo;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.app.Dialog;
10 import android.app.ListActivity;
11 import android.app.ProgressDialog;
12 import android.content.DialogInterface;
13 import android.content.Intent;
14 import android.content.SharedPreferences;
15 import android.content.SharedPreferences.Editor;
16 import android.location.Location;
17 import android.os.AsyncTask;
18 import android.os.Bundle;
19 import android.os.Handler;
20 import android.os.Message;
21
22 import android.view.ContextMenu;
23 import android.view.LayoutInflater;
24 import android.view.Menu;
25 import android.view.MenuItem;
26 import android.view.View;
27 import android.view.ContextMenu.ContextMenuInfo;
28 import android.view.View.OnCreateContextMenuListener;
29 import android.widget.AdapterView;
30 import android.widget.EditText;
31 import android.widget.ListView;
32 import android.widget.Toast;
33 import dk.thoerup.traininfo.provider.ProviderFactory;
34 import dk.thoerup.traininfo.provider.StationProvider;
35 import dk.thoerup.traininfo.stationmap.GeoPair;
36 import dk.thoerup.traininfo.stationmap.StationMapView;
37 import dk.thoerup.traininfo.util.IntSet;
38 import dk.thoerup.traininfo.util.MessageBox;
39
40 import static dk.thoerup.traininfo.R.string.*;
41
42 public class StationList extends ListActivity {
43 public static final int GOTLOCATION = 1001;
44 public static final int GOTSTATIONLIST = 1002;
45 public static final int NOPROVIDER = 1003;
46 public static final int LOCATIONFIXTIMEOUT = 1004;
47
48 public static final int OPTIONS_MAP = 2003;
49 public static final int OPTIONS_GPSINFO = 2004;
50
51 public static final int DLG_PROGRESS = 3001;
52 public static final int DLG_STATIONNAME = 3002;
53
54
55 public static final int GPS_TIMEOUT_MS = 17500; //how long are we willing to wait for gps fix -in milliseconds
56
57
58 static enum LookupMethod {
59 ByLocation,
60 ByName,
61 ByList,
62 MethodNone
63 }
64
65
66 String dialogMessage = "";
67 ProgressDialog dialog;
68 LocationLookup locationLookup = null;
69 FindStationsTask findStationsTask;
70 StationsFetchedHandler stationsFetched = new StationsFetchedHandler();
71
72 GeoPair location = new GeoPair();
73
74 boolean isLaunchedforShortcut;
75 boolean isRunning = false;
76 List<StationBean> stations = new ArrayList<StationBean>();
77
78 StationProvider stationProvider = ProviderFactory.getStationProvider();
79
80 StationListAdapter adapter = null;
81
82 FavoritesMenu contextMenu = new FavoritesMenu();
83 IntSet favorites = new IntSet();
84
85 WelcomeScreen.ListType listType;
86 SharedPreferences prefs;
87
88 ///////////////////////////////////////////////////////////////////////////////////////////
89 //Activity call backs
90
91 @SuppressWarnings("unchecked")
92 @Override
93 public void onCreate(Bundle savedInstanceState) {
94 super.onCreate(savedInstanceState);
95 setContentView(R.layout.stationlist);
96
97
98 adapter = new StationListAdapter(this);
99 setListAdapter(adapter);
100
101 ListView lv = getListView();
102 lv.setOnCreateContextMenuListener(contextMenu);
103
104 locationLookup = new LocationLookup(this, stationsFetched);
105
106
107 prefs = getSharedPreferences("TrainStation", 0);
108 String favoriteString = prefs.getString("favorites", "");
109 if (! favoriteString.equals("") ) {
110 favorites.fromString(favoriteString);
111 }
112
113 listType = (WelcomeScreen.ListType) getIntent().getSerializableExtra("type");
114 setTitle();
115
116 isLaunchedforShortcut = getIntent().getBooleanExtra("shortcut", false);
117
118 if (savedInstanceState == null) {
119
120
121 switch (listType) {
122 case ListNearest:
123 startLookup();
124 break;
125 case ListSearch:
126 showDialog(DLG_STATIONNAME); //TODO: this.showDialogSafe(DLG_STATIONNAME);
127 break;
128 case ListFavorites:
129 startFavoriteLookup();
130 break;
131 default:
132 // Not possible !?!
133 }
134
135 } else {
136 stations = (ArrayList<StationBean>) savedInstanceState.getSerializable("stations");
137 adapter.setStations(stations);
138 location = (GeoPair) savedInstanceState.getSerializable("location");
139 }
140
141 }
142
143
144 @Override
145 protected void onDestroy() {
146 super.onDestroy();
147
148 if (findStationsTask != null) {
149 findStationsTask.cancel(true);
150 }
151 if (locationLookup != null) {
152 locationLookup.stopSearch();
153 }
154 isRunning = false;
155 }
156
157
158 protected void setTitle() {
159 String dialogTitle = getResources().getString(app_name);
160 switch (listType) {
161 case ListNearest:
162 dialogTitle += " - " + getString(stationlist_nearbystations);
163 break;
164 case ListSearch:
165 dialogTitle += " - " + getString(stationlist_search);
166 break;
167 case ListFavorites:
168 dialogTitle += " - " + getString(stationlist_favorites);
169 break;
170 default:
171 dialogTitle = "";//not possible
172 }
173
174 setTitle(dialogTitle);
175
176 }
177
178
179 /* these 3 dialogs helper functions are very rude and ugly hack
180 * to remove these auto-reported exceptions
181 * - android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@436aaef8 is not valid; is your activity running?
182 * - java.lang.IllegalArgumentException: View not attached to window manager
183 */
184
185 /*
186 public void showDialogSafe(int id) {
187 try {
188 showDialog(id);
189 } catch (Exception e) {
190 Log.e("StationList", "showDialog failed", e);
191 }
192 }
193
194 public void dismissDialogSafe(int id) {
195 try {
196 dismissDialog(id);
197 } catch (Exception e) {
198 Log.e("StationList", "dismissDialog failed", e);
199 }
200 }
201 public void dismissDialogSafe(Dialog dlg) {
202 try {
203 dlg.dismiss();
204 } catch (Exception e) {
205 Log.e("StationList", "dismissDialog failed", e);
206 }
207 }
208
209 public void builderShowSafe(AlertDialog.Builder builder) {
210 try {
211 builder.show();
212 } catch (Exception e) {
213 Log.e("StationList", "builder.show() failed", e);
214 }
215
216 }*/
217
218 /* EOF rude and ugly dialog hack */
219
220
221
222 @Override
223 public void onSaveInstanceState(Bundle outState)
224 {
225 if (dialog != null && dialog.isShowing())
226 dialog.dismiss();
227 outState.putSerializable("stations", (ArrayList<StationBean>) stations);
228 outState.putSerializable("location", location);
229
230 }
231
232
233
234 @Override
235 public boolean onCreateOptionsMenu(Menu menu) {
236 MenuItem item;
237
238 item = menu.add(0, OPTIONS_MAP, 0, getString(stationlist_stationmap));
239 item.setIcon(android.R.drawable.ic_menu_mapmode);
240
241 item = menu.add(0, OPTIONS_GPSINFO, 0, getString(stationlist_gpsinfo));
242 item.setIcon(android.R.drawable.ic_menu_mapmode);
243
244 return true;
245 }
246
247 @Override
248 public boolean onOptionsItemSelected(MenuItem item) {
249 boolean retval = true;
250
251 //TODO: Cleanup
252 switch (item.getItemId()) {
253 case OPTIONS_MAP:
254
255 Intent intent = new Intent(this,StationMapView.class);
256
257 ArrayList<GeoPair> stationPoints = new ArrayList<GeoPair>();
258 for (StationBean st : stations ) {
259 stationPoints.add( new GeoPair(st.getLatitude(), st.getLongitude(), st.getName()) );
260 }
261
262 intent.putExtra("stations", stationPoints);
263
264 startActivity(intent);
265 break;
266 case OPTIONS_GPSINFO:
267 Location loc = locationLookup.getLocation();
268 StringBuffer message = new StringBuffer();
269 message.append( getString(stationlist_locationinfo) ).append(":\n");
270 if (loc != null) {
271 message.append( getString(stationlist_obtainedby) ).append( loc.getProvider() ).append("\n");
272 message.append( getString(stationlist_accuracy) ).append( (int)loc.getAccuracy()).append("m\n");
273 message.append( getString(stationlist_latitude) ).append( (float)loc.getLatitude()).append("\n");
274 message.append( getString(stationlist_longitude) ).append( (float)loc.getLongitude() ).append("\n");
275 } else {
276 message.append( getString(stationlist_nolocation) );
277 }
278
279 MessageBox.showMessage(this, message.toString(), false);
280 break;
281 default:
282 retval = super.onOptionsItemSelected(item);
283 }
284
285 return retval;
286 }
287
288
289
290 @Override
291 public boolean onContextItemSelected(MenuItem item) {
292 contextMenu.onContextItemSelected(item);
293 return true;
294
295
296 }
297
298 public void showMessageAndClose(String message) {
299 AlertDialog.Builder builder = new AlertDialog.Builder(this);
300 builder.setMessage(message)
301 .setCancelable(false)
302 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
303 public void onClick(DialogInterface dialog, int id) {
304 dialog.dismiss();
305 StationList.this.finish();
306 }
307 })
308 .show();
309 }
310
311
312
313
314 @Override
315 protected Dialog onCreateDialog(int id) {
316 switch (id) {
317 case DLG_PROGRESS:
318 ProgressDialog dlg = new ProgressDialog(this);
319 dlg.setMessage( getString(stationlist_waitforlocation) );
320 dlg.setCancelable(false);
321 return dlg;
322 case DLG_STATIONNAME:
323 LayoutInflater factory = LayoutInflater.from(this);
324 final View rootView = factory.inflate(R.layout.textinput, null);
325
326
327 AlertDialog.Builder builder = new AlertDialog.Builder(this);
328
329 builder.setTitle( getString(stationlist_stationsearch) );
330 builder.setView(rootView);
331 builder.setCancelable(true);
332 builder.setPositiveButton( getString(generic_search), new DialogInterface.OnClickListener() {
333 public void onClick(DialogInterface dialog, int which) {
334 EditText et = (EditText) rootView.findViewById(R.id.EditText);
335 dialog.dismiss();
336 String search = et.getText().toString().trim();
337 if (search.length() >= 2) {
338 startNameSearch(search);
339 } else {
340 showMessageAndClose( getString(stationlist_twocharmin) );
341 }
342 }
343 });
344 builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
345 public void onClick(DialogInterface dialog, int which) {
346 dialog.dismiss();
347 StationList.this.finish(); // Close this Activity
348 }
349 });
350 return builder.create();
351
352 default:
353 return super.onCreateDialog(id);
354 }
355
356 }
357
358
359 @Override
360 protected void onPrepareDialog(int id, Dialog dialog) {
361 super.onPrepareDialog(id, dialog);
362 switch (id) {
363 case DLG_PROGRESS:
364 this.dialog = (ProgressDialog) dialog;
365 if (!dialogMessage.equals("")) {
366 this.dialog.setMessage(dialogMessage);
367 dialogMessage = "";
368 }
369 break;
370 }
371 }
372
373 @Override
374 protected void onListItemClick(ListView l, View v, int position, long id) {
375 super.onListItemClick(l, v, position, id);
376
377 StationBean station = stations.get(position);
378
379 if (isLaunchedforShortcut == true) {
380 Intent i = new Intent();
381 i.putExtra("station", station);
382 setResult(Activity.RESULT_OK, i);
383 finish();
384 } else {
385 Intent intent = new Intent(this, DepartureList.class);
386 intent.putExtra("stationbean", station);
387 startActivity(intent);
388 }
389 }
390
391 /////////////////////////////////////////////////////////////
392 //
393
394 public void startLookup() {
395 isRunning = true;
396 dialogMessage = getString( stationlist_waitforlocation );
397 showDialog(DLG_PROGRESS);//TODO:showDialogSafe(DLG_PROGRESS);
398
399 locationLookup.locateStations();
400 stationsFetched.sendEmptyMessageDelayed(LOCATIONFIXTIMEOUT, GPS_TIMEOUT_MS);
401 }
402
403 void startNameSearch(String name) {
404 dialogMessage = getString( stationlist_findbyname );
405 showDialog(DLG_PROGRESS);//TODO:showDialogSafe(DLG_PROGRESS);
406
407 findStationsTask = new FindStationsTask();
408 findStationsTask.searchByName(name);
409 findStationsTask.execute();
410
411 }
412
413 public void startFavoriteLookup() {
414
415 if (favorites.size() > 0) {
416 dialogMessage = getString( stationlist_loadfavorites );
417 showDialog(DLG_PROGRESS);//TODO:showDialogSafe(DLG_PROGRESS);
418
419 findStationsTask = new FindStationsTask();
420 findStationsTask.searchByIds( favorites.toString() );
421 findStationsTask.execute();
422 } else {
423 showMessageAndClose( getString( stationlist_nofavorites ) );
424 }
425 }
426
427
428
429 void startLocatorTask()
430 {
431 dialogMessage = getString( stationlist_findingnearby );
432 showDialog(DLG_PROGRESS);//TODO:showDialogSafe(DLG_PROGRESS);
433
434 findStationsTask = new FindStationsTask();
435 findStationsTask.searchByLocation( locationLookup.getLocation() );
436 findStationsTask.execute();
437 }
438
439
440 ////////////////////////////////////////////////////////////////////////////
441 // Inner classes
442
443 class StationsFetchedHandler extends Handler {
444 @Override
445 public void handleMessage(Message msg) {
446
447 switch (msg.what) {
448 case GOTLOCATION:
449 dismissDialog(DLG_PROGRESS);//TODO:dismissDialogSafe(DLG_PROGRESS);
450
451 startLocatorTask();
452 location = GeoPair.fromLocation( locationLookup.getLocation() );
453
454 break;
455
456 case NOPROVIDER:
457 dismissDialog(DLG_PROGRESS);//TODO:dismissDialogSafe(DLG_PROGRESS);
458 MessageBox.showMessage(StationList.this, getString(stationlist_nolocationprovider), true );
459 //StationList.this.finish();
460 break;
461 case LOCATIONFIXTIMEOUT:
462 if (isRunning) {
463 locationLookup.stopSearch();
464 if (locationLookup.hasLocation()) {
465 stationsFetched.sendEmptyMessage( GOTLOCATION );
466 } else {
467 dismissDialog(DLG_PROGRESS);//TODO:dismissDialogSafe(DLG_PROGRESS);
468
469 AlertDialog.Builder builder = new AlertDialog.Builder(StationList.this);
470 builder.setMessage( getString( stationlist_gpstimeout) );
471 builder.setCancelable(true);
472 builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
473 public void onClick(DialogInterface dialog, int id) {
474 dialog.dismiss();
475 startLookup();
476
477 }
478 });
479 builder.setNegativeButton( getString(generic_cancel), new DialogInterface.OnClickListener() {
480 public void onClick(DialogInterface dialog, int id) {
481 dialog.dismiss();
482 }
483 });
484 builder.show();//TODO:builderShowSafe(builder);
485
486 }
487 }
488 break;
489 }
490 isRunning = false;
491 }
492 };
493
494
495 class FindStationsTask extends AsyncTask<Void,Void,Void> {
496
497 LookupMethod method = LookupMethod.MethodNone;
498 String name;
499 Location loc;
500 String ids;
501
502 public void searchByName(String n) {
503
504 method = LookupMethod.ByName;
505 name = n;
506 }
507
508 public void searchByLocation(Location l) {
509 method = LookupMethod.ByLocation;
510 loc = l;
511 }
512
513 public void searchByIds(String id) {
514
515 method = LookupMethod.ByList;
516 ids = id;
517 }
518
519 @Override
520 protected void onPreExecute() {
521
522 if (method.equals(LookupMethod.MethodNone))
523 throw new RuntimeException("Method not set");
524 super.onPreExecute();
525 }
526
527 @Override
528 protected Void doInBackground(Void... params) {
529
530 switch (method) {
531 case ByLocation:
532 stations = stationProvider.lookupStations(loc);
533 break;
534 case ByName:
535 stations = stationProvider.lookupStationsByName(name);
536 break;
537 case ByList:
538 stations = stationProvider.lookupStationsByIds(ids);
539 break;
540 default:
541 stations = null; // not possible
542 }
543
544
545 return null;
546 }
547
548 @Override
549 protected void onPostExecute(Void result) {
550 super.onPostExecute(result);
551 dialog.dismiss();//TODO:dismissDialogSafe(dialog);
552
553
554 if (stations != null) {
555 if (stations.size() == 0) {
556 showMessageAndClose(getString(stationlist_nostations));
557 }
558
559 StationList.this.getListView().invalidateViews();
560 adapter.setStations( stations );
561
562
563 } else { //communication or parse errors
564 AlertDialog.Builder builder = new AlertDialog.Builder(StationList.this);
565 builder.setMessage(getString(stationlist_fetcherror));
566 builder.setCancelable(true);
567 builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
568 public void onClick(DialogInterface dialog, int id) {
569 dialog.dismiss();
570
571 Runnable runner = null;
572 switch (method) {
573 case ByLocation:
574 runner = new Runnable() {
575 @Override
576 public void run() {
577 startLocatorTask();
578 }
579 };
580 break;
581 case ByName:
582 runner = new Runnable() {
583 @Override
584 public void run() {
585 startNameSearch( FindStationsTask.this.name );
586 }
587 };
588 break;
589 case ByList:
590 runner = new Runnable() {
591 @Override
592 public void run() {
593 startFavoriteLookup();
594 }
595 };
596 break;
597 }
598
599 stationsFetched.post( runner );
600 }
601 });
602 builder.setNegativeButton(getString(generic_cancel), new DialogInterface.OnClickListener() {
603 public void onClick(DialogInterface dialog, int id) {
604 dialog.dismiss();
605 StationList.this.finish();
606 }
607 });
608
609 builder.show();//TODO:builderShowSafe(builder);
610 }
611 }
612 }
613
614
615 class FavoritesMenu implements OnCreateContextMenuListener {
616 private final static int FAVORITES_ADD = 9001;
617 private final static int FAVORITES_REMOVE = 9002;
618
619 private int selectedPosition;
620
621
622 @Override
623 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
624
625 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
626 selectedPosition = info.position;
627 int stationID = stations.get(selectedPosition).getId();
628
629 if (!favorites.contains(stationID)) {
630 menu.add(0, FAVORITES_ADD, 0, getString(stationlist_addfavorite) );
631 } else {
632 menu.add(0, FAVORITES_REMOVE, 0, getString(stationlist_removefavorite) );
633 }
634
635 }
636
637 public void onContextItemSelected(MenuItem item) {
638 StationBean sb = stations.get(selectedPosition);
639
640 int stationID = sb.getId();
641 if (item.getItemId() == FAVORITES_ADD) {
642 favorites.add(stationID);
643 Toast.makeText(StationList.this, getString(stationlist_stationadded), Toast.LENGTH_SHORT).show();
644 } else {
645
646 favorites.remove(stationID);
647 Toast.makeText(StationList.this, getString(stationlist_stationremoved), Toast.LENGTH_SHORT).show();
648
649
650 if (listType.equals( WelcomeScreen.ListType.ListFavorites) ) {
651 stations.remove(selectedPosition);
652 adapter.notifyDataSetChanged();
653 }
654 }
655 Editor ed = prefs.edit();
656 ed.putString("favorites", favorites.toString());
657 ed.commit();
658 }
659 }
660 }

  ViewVC Help
Powered by ViewVC 1.1.20