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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 481 - (hide annotations) (download)
Thu Oct 29 08:56:17 2009 UTC (14 years, 7 months ago) by torben
File size: 15868 byte(s)
New gui structure with a initial welcome screen
1 torben 237 package dk.thoerup.traininfo;
2    
3 torben 258 import java.util.ArrayList;
4     import java.util.List;
5 torben 294 import java.util.Locale;
6 torben 258
7 torben 336 import android.app.AlertDialog;
8 torben 237 import android.app.Dialog;
9     import android.app.ListActivity;
10     import android.app.ProgressDialog;
11 torben 336 import android.content.DialogInterface;
12 torben 237 import android.content.Intent;
13 torben 433 import android.content.SharedPreferences;
14 torben 435 import android.content.SharedPreferences.Editor;
15 torben 294 import android.location.Address;
16     import android.location.Geocoder;
17 torben 319 import android.location.Location;
18 torben 241 import android.os.AsyncTask;
19 torben 237 import android.os.Bundle;
20     import android.os.Handler;
21     import android.os.Message;
22 torben 294 import android.util.Log;
23 torben 433 import android.view.ContextMenu;
24 torben 381 import android.view.LayoutInflater;
25 torben 368 import android.view.Menu;
26     import android.view.MenuItem;
27 torben 237 import android.view.View;
28 torben 433 import android.view.ContextMenu.ContextMenuInfo;
29     import android.view.View.OnCreateContextMenuListener;
30     import android.widget.AdapterView;
31 torben 381 import android.widget.EditText;
32 torben 237 import android.widget.ListView;
33 torben 433 import android.widget.Toast;
34 torben 319 import dk.thoerup.traininfo.provider.ProviderFactory;
35     import dk.thoerup.traininfo.provider.StationProvider;
36 torben 368 import dk.thoerup.traininfo.stationmap.GeoPair;
37     import dk.thoerup.traininfo.stationmap.StationMapView;
38 torben 433 import dk.thoerup.traininfo.util.IntSet;
39 torben 245 import dk.thoerup.traininfo.util.MessageBox;
40 torben 237
41 torben 336 public class StationList extends ListActivity {
42     public static final int GOTLOCATION = 1001;
43     public static final int GOTSTATIONLIST = 1002;
44     public static final int NOPROVIDER = 1003;
45     public static final int LOCATIONFIXTIMEOUT = 1004;
46 torben 368
47 torben 381 public static final int OPTIONS_MAP = 2003;
48 torben 481 public static final int OPTIONS_GPSINFO = 2004;
49    
50 torben 433
51 torben 336
52 torben 237
53 torben 381 public static final int DLG_PROGRESS = 3001;
54     public static final int DLG_STATIONNAME = 3002;
55 torben 237
56 torben 440 static enum LookupMethod {
57     ByLocation,
58     ByName,
59     ByList,
60     MethodNone
61     }
62    
63    
64 torben 336 String dialogMessage = "";
65 torben 237 ProgressDialog dialog;
66 torben 319 LocationLookup locator = null;
67 torben 440 FindStationsTask findStationsTask;
68 torben 381 StationsFetchedHandler stationsFetched = new StationsFetchedHandler();
69 torben 237
70 torben 374 GeoPair location = new GeoPair();
71    
72 torben 258 boolean isRunning = false;
73     List<StationBean> stations = new ArrayList<StationBean>();
74    
75 torben 319 StationProvider stationProvider = ProviderFactory.getStationProvider();
76 torben 381
77     StationListAdapter adapter = null;
78 torben 258
79 torben 433 FavoritesMenu contextMenu = new FavoritesMenu();
80     IntSet favorites = new IntSet();
81 torben 481
82     WelcomeScreen.ListType listType;
83 torben 480 String dialogTitle;
84 torben 433 SharedPreferences prefs;
85    
86 torben 381 ///////////////////////////////////////////////////////////////////////////////////////////
87     //Activity call backs
88    
89 torben 258 @SuppressWarnings("unchecked")
90 torben 237 @Override
91     public void onCreate(Bundle savedInstanceState) {
92     super.onCreate(savedInstanceState);
93 torben 481 setContentView(R.layout.stationlist);
94 torben 237
95 torben 241
96 torben 237 adapter = new StationListAdapter(this);
97     setListAdapter(adapter);
98    
99 torben 433 ListView lv = getListView();
100     lv.setOnCreateContextMenuListener(contextMenu);
101    
102 torben 319 locator = new LocationLookup(this, stationsFetched);
103 torben 433
104    
105     prefs = getSharedPreferences("TrainStation", 0);
106     String favoriteString = prefs.getString("favorites", "");
107     if (! favoriteString.equals("") ) {
108     favorites.fromString(favoriteString);
109     }
110    
111 torben 258 if (savedInstanceState == null) {
112 torben 481 listType = (WelcomeScreen.ListType) getIntent().getSerializableExtra("type");
113     switch (listType) {
114     case ListNearest:
115     startLookup();
116     break;
117     case ListSearch:
118     this.showDialog(DLG_STATIONNAME);
119     break;
120     case ListFavorites:
121     startFavoriteLookup();
122     break;
123     default:
124     // Not possible !?!
125     }
126    
127 torben 258 } else {
128     stations = (ArrayList<StationBean>) savedInstanceState.getSerializable("stations");
129 torben 260 adapter.setStations(stations);
130 torben 374 location = (GeoPair) savedInstanceState.getSerializable("location");
131 torben 480 dialogTitle = savedInstanceState.getString("title");
132     setTitle(dialogTitle);
133 torben 258 }
134 torben 237 }
135 torben 371
136    
137 torben 243 @Override
138     public void onSaveInstanceState(Bundle outState)
139     {
140 torben 258 if (dialog != null && dialog.isShowing())
141 torben 243 dialog.dismiss();
142 torben 258 outState.putSerializable("stations", (ArrayList<StationBean>) stations);
143 torben 374 outState.putSerializable("location", location);
144 torben 480 outState.putString("title", dialogTitle);
145 torben 243 }
146 torben 237
147 torben 243
148 torben 237
149     @Override
150 torben 368 public boolean onCreateOptionsMenu(Menu menu) {
151 torben 419 MenuItem item;
152 torben 481
153 torben 439 item = menu.add(0, OPTIONS_MAP, 0, "Station map");
154 torben 419 item.setIcon(android.R.drawable.ic_menu_mapmode);
155    
156 torben 481 item = menu.add(0, OPTIONS_GPSINFO, 0, "GPS Info");
157     item.setIcon(android.R.drawable.ic_menu_mapmode);
158    
159 torben 368 return true;
160     }
161    
162     @Override
163     public boolean onOptionsItemSelected(MenuItem item) {
164 torben 381 boolean retval = true;
165    
166 torben 481 //TODO: Cleanup
167 torben 368 switch (item.getItemId()) {
168     case OPTIONS_MAP:
169    
170     Intent intent = new Intent(this,StationMapView.class);
171 torben 374 intent.putExtra("userlocation", location );
172 torben 368
173     ArrayList<GeoPair> stationPoints = new ArrayList<GeoPair>();
174     for (StationBean st : stations ) {
175 torben 369 stationPoints.add( new GeoPair(st.getLatitude(), st.getLongitude(), st.getName()) );
176 torben 368 }
177    
178     intent.putExtra("stations", stationPoints);
179    
180     startActivity(intent);
181     break;
182 torben 481 case OPTIONS_GPSINFO:
183 torben 401 Location loc = locator.getLocation();
184 torben 371 StringBuffer message = new StringBuffer();
185 torben 401 message.append("Location info:\n");
186     message.append("-Obtained by: ").append(loc != null ? loc.getProvider() : "-").append("\n");
187     message.append("-Accuracy: ").append(loc != null ? (int)loc.getAccuracy() : "-").append("m\n");
188 torben 371
189     MessageBox.showMessage(this, message.toString());
190     break;
191 torben 368 default:
192     retval = super.onOptionsItemSelected(item);
193     }
194    
195     return retval;
196     }
197 torben 433
198    
199 torben 368
200     @Override
201 torben 433 public boolean onContextItemSelected(MenuItem item) {
202     contextMenu.onContextItemSelected(item);
203     return true;
204    
205    
206     }
207    
208    
209    
210    
211     @Override
212 torben 237 protected Dialog onCreateDialog(int id) {
213     switch (id) {
214     case DLG_PROGRESS:
215     ProgressDialog dlg = new ProgressDialog(this);
216     dlg.setMessage("Wait for location fix");
217     dlg.setCancelable(false);
218 torben 336 return dlg;
219 torben 381 case DLG_STATIONNAME:
220     LayoutInflater factory = LayoutInflater.from(this);
221     final View rootView = factory.inflate(R.layout.textinput, null);
222    
223    
224     AlertDialog.Builder builder = new AlertDialog.Builder(this);
225    
226     builder.setTitle("Station search");
227     builder.setView(rootView);
228     builder.setCancelable(true);
229     builder.setPositiveButton("Search", new DialogInterface.OnClickListener() {
230     public void onClick(DialogInterface dialog, int which) {
231     EditText et = (EditText) rootView.findViewById(R.id.EditText);
232     dialog.dismiss();
233     if (et.getText().toString().length() >= 2) {
234     startNameSearch(et.getText().toString());
235     } else {
236 torben 382 MessageBox.showMessage(StationList.this, "Two characters minimum" );
237 torben 381 }
238     }
239     });
240     builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
241     public void onClick(DialogInterface dialog, int which) {
242     dialog.dismiss();
243     }
244     });
245     return builder.create();
246    
247 torben 237 default:
248     return super.onCreateDialog(id);
249     }
250    
251     }
252    
253    
254     @Override
255     protected void onPrepareDialog(int id, Dialog dialog) {
256     super.onPrepareDialog(id, dialog);
257     switch (id) {
258     case DLG_PROGRESS:
259     this.dialog = (ProgressDialog) dialog;
260 torben 336 if (!dialogMessage.equals("")) {
261     this.dialog.setMessage(dialogMessage);
262     dialogMessage = "";
263     }
264 torben 237 break;
265     }
266     }
267 torben 381
268     @Override
269     protected void onListItemClick(ListView l, View v, int position, long id) {
270     super.onListItemClick(l, v, position, id);
271    
272     StationBean station = stations.get(position);
273 torben 237
274 torben 381 double latitude = station.getLatitude();
275     double longitude = station.getLongitude();
276    
277    
278    
279     Intent intent = new Intent(this, DepartureList.class);
280     intent.putExtra("name", station.getName());
281     intent.putExtra("distance", station.getDistance());
282     intent.putExtra("latitude", latitude);
283     intent.putExtra("longitude", longitude);
284     intent.putExtra("stationid", station.getId());
285     intent.putExtra("address", station.getAddress());
286     startActivity(intent);
287     }
288    
289     /////////////////////////////////////////////////////////////
290     //
291    
292 torben 237 public void startLookup() {
293     isRunning = true;
294 torben 381 dialogMessage = "Wait for location fix";
295 torben 237 showDialog(DLG_PROGRESS);
296    
297     locator.locateStations();
298 torben 336 stationsFetched.sendEmptyMessageDelayed(LOCATIONFIXTIMEOUT, 20000);
299 torben 237 }
300 torben 381
301     void startNameSearch(String name) {
302     dialogMessage = "Finding stations by name";
303     showDialog(DLG_PROGRESS);
304 torben 237
305 torben 440 findStationsTask = new FindStationsTask();
306     findStationsTask.searchByName(name, locator.getLocation());
307     findStationsTask.execute();
308 torben 381
309     }
310 torben 433
311     public void startFavoriteLookup() {
312    
313 torben 440 if (favorites.size() > 0) {
314 torben 433 dialogMessage = "Loading favorites";
315     showDialog(DLG_PROGRESS);
316 torben 237
317 torben 440 findStationsTask = new FindStationsTask();
318     findStationsTask.searchByIds(favorites.toString(), locator.getLocation());
319     findStationsTask.execute();
320 torben 433 } else {
321     MessageBox.showMessage(this, "Favorite list is empty");
322     }
323     }
324 torben 381
325 torben 433
326 torben 381
327     void startLocatorTask()
328     {
329     dialogMessage = "Finding nearby stations";
330     showDialog(DLG_PROGRESS);
331    
332 torben 440 findStationsTask = new FindStationsTask();
333     findStationsTask.searchByLocation( locator.getLocation() );
334     findStationsTask.execute();
335 torben 381 }
336    
337    
338     String lookupAddress(double latitude, double longitude) {
339    
340     Geocoder coder = new Geocoder(this, new Locale("da"));
341     StringBuilder sb = new StringBuilder();
342     Log.i("lookupaddr", "" + latitude + "/" + longitude);
343     try {
344     List<Address> addressList = coder.getFromLocation(latitude, longitude, 1);
345     Address addr = addressList.get(0);
346    
347    
348     int max = addr.getMaxAddressLineIndex();
349     for (int i=0; i<max; i++) {
350     if (i>0)
351     sb.append(", ");
352    
353     sb.append(addr.getAddressLine(i));
354     }
355    
356    
357     } catch (Exception e) {
358     Log.e("DepartureList", "geocoder failed", e);
359     }
360    
361     return sb.toString();
362     }
363    
364    
365     ////////////////////////////////////////////////////////////////////////////
366     // Inner classes
367    
368     class StationsFetchedHandler extends Handler {
369 torben 237 @Override
370     public void handleMessage(Message msg) {
371 torben 336
372 torben 237 switch (msg.what) {
373     case GOTLOCATION:
374 torben 336 dismissDialog(DLG_PROGRESS);
375    
376     startLocatorTask();
377 torben 374 location = GeoPair.fromLocation( locator.getLocation() );
378 torben 336
379 torben 237 break;
380 torben 319
381 torben 237 case NOPROVIDER:
382 torben 336 dismissDialog(DLG_PROGRESS);
383     MessageBox.showMessage(StationList.this,"No location provider enabled. Plase enable gps.");
384 torben 237 break;
385 torben 336 case LOCATIONFIXTIMEOUT:
386 torben 237 if (isRunning) {
387 torben 336 locator.stopSearch();
388 torben 285 if (locator.hasLocation()) {
389 torben 336 stationsFetched.sendEmptyMessage( GOTLOCATION );
390     } else {
391     dismissDialog(DLG_PROGRESS);
392    
393     AlertDialog.Builder builder = new AlertDialog.Builder(StationList.this);
394 torben 420 builder.setMessage("Location fix timed out");
395 torben 336 builder.setCancelable(true);
396     builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
397     public void onClick(DialogInterface dialog, int id) {
398     dialog.dismiss();
399     startLookup();
400    
401     }
402     });
403     builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
404     public void onClick(DialogInterface dialog, int id) {
405     dialog.dismiss();
406     }
407     });
408     builder.show();
409    
410 torben 285 }
411 torben 237 }
412     break;
413     }
414     isRunning = false;
415     }
416     };
417 torben 381
418 torben 237
419 torben 440 class FindStationsTask extends AsyncTask<Void,Void,Void> {
420 torben 336
421 torben 381 LookupMethod method = LookupMethod.MethodNone;
422     boolean success;
423     String name;
424     Location loc;
425 torben 433 String ids;
426 torben 237
427 torben 381 public void searchByName(String n, Location l) {
428 torben 317
429 torben 381 method = LookupMethod.ByName;
430     loc = l;
431     name = n;
432 torben 317 }
433    
434 torben 381 public void searchByLocation(Location l) {
435     method = LookupMethod.ByLocation;
436     loc = l;
437     }
438    
439 torben 433 public void searchByIds(String id, Location l) {
440    
441     method = LookupMethod.ByList;
442     loc = l;
443     ids = id;
444     }
445    
446 torben 241 @Override
447     protected void onPreExecute() {
448 torben 258
449 torben 381 if (method.equals(LookupMethod.MethodNone))
450     throw new RuntimeException("Method not set");
451 torben 241 super.onPreExecute();
452     }
453    
454     @Override
455     protected Void doInBackground(Void... params) {
456 torben 473
457     switch (method) {
458     case ByLocation:
459 torben 381 success = stationProvider.lookupStations(loc);
460 torben 473 break;
461     case ByName:
462 torben 433 success = stationProvider.lookupStationsByName(name);
463 torben 473 break;
464     case ByList:
465 torben 433 success = stationProvider.lookupStationsByIds(ids);
466 torben 473 break;
467     default:
468     success = false; // not possible
469     }
470 torben 433
471 torben 473
472 torben 381 Location dummy = new Location("gps");
473 torben 319 List<StationBean> stations = stationProvider.getStations();
474 torben 381
475     for (StationBean station : stations) {
476 torben 317 String addr = lookupAddress(station.getLatitude(), station.getLongitude());
477     station.setAddress(addr);
478 torben 381
479 torben 478
480     if (method.equals(LookupMethod.ByName) || method.equals(LookupMethod.ByList)) {
481     if (loc != null) { //only do the distance calc if we have a location
482 torben 476 dummy.setLatitude(station.getLatitude());
483     dummy.setLongitude(station.getLongitude());
484     station.setDistance( (int)loc.distanceTo(dummy) );
485 torben 478 } else {
486     station.setDistance(0);
487 torben 476 }
488 torben 381 }
489 torben 478
490 torben 381 }
491 torben 317
492 torben 241 return null;
493     }
494    
495     @Override
496     protected void onPostExecute(Void result) {
497     super.onPostExecute(result);
498 torben 319 dialog.dismiss();
499    
500 torben 473 //set title
501     switch (method) {
502     case ByLocation:
503 torben 480 dialogTitle = "Traininfo DK - Nearby stations";
504 torben 473 break;
505     case ByName:
506 torben 480 dialogTitle = "Traininfo DK - Search";
507 torben 473 break;
508     case ByList:
509 torben 480 dialogTitle = "Traininfo DK - Favorites";
510 torben 473 break;
511     default:
512 torben 480 dialogTitle = "";//not possible
513 torben 473 }
514    
515 torben 480 StationList.this.setTitle(dialogTitle);
516 torben 473 //set title end
517    
518 torben 319 if (success) {
519     if (stationProvider.getStations().size() == 0)
520 torben 336 MessageBox.showMessage(StationList.this, "No stations found!"); // this should not be possible !?!
521 torben 319 stations = stationProvider.getStations();
522 torben 481 adapter.setStations( stations );
523 torben 319
524     } else { //communication or parse errors
525 torben 336 AlertDialog.Builder builder = new AlertDialog.Builder(StationList.this);
526     builder.setMessage("Error on finding nearby stations");
527     builder.setCancelable(true);
528     builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
529     public void onClick(DialogInterface dialog, int id) {
530     dialog.dismiss();
531    
532     stationsFetched.post( new Runnable() {
533     @Override
534     public void run() {
535     startLocatorTask();
536     }
537     });
538     }
539     });
540     builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
541     public void onClick(DialogInterface dialog, int id) {
542     dialog.dismiss();
543     }
544     });
545     builder.show();
546 torben 319 }
547 torben 241 }
548     }
549 torben 433
550    
551     class FavoritesMenu implements OnCreateContextMenuListener {
552     private final static int FAVORITES_ADD = 9001;
553     private final static int FAVORITES_REMOVE = 9002;
554    
555     private int selectedPosition;
556    
557    
558     @Override
559     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
560    
561     AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
562     selectedPosition = info.position;
563     int stationID = stations.get(selectedPosition).getId();
564    
565 torben 441 if (!favorites.contains(stationID)) {
566 torben 433 menu.add(0, FAVORITES_ADD, 0, "Add to favorites");
567     } else {
568     menu.add(0, FAVORITES_REMOVE, 0, "Remove from favorites");
569     }
570    
571     }
572    
573     public void onContextItemSelected(MenuItem item) {
574     StationBean sb = stations.get(selectedPosition);
575    
576     int stationID = sb.getId();
577     if (item.getItemId() == FAVORITES_ADD) {
578     favorites.add(stationID);
579     Toast.makeText(StationList.this, "Station added", Toast.LENGTH_SHORT).show();
580     } else {
581 torben 473
582 torben 433 favorites.remove(stationID);
583     Toast.makeText(StationList.this, "Station removed", Toast.LENGTH_SHORT).show();
584 torben 473
585 torben 481
586     if (listType.equals( WelcomeScreen.ListType.ListFavorites) ) {
587 torben 473 stations.remove(selectedPosition);
588     adapter.notifyDataSetChanged();
589     }
590 torben 433 }
591 torben 435 Editor ed = prefs.edit();
592     ed.putString("favorites", favorites.toString());
593     ed.commit();
594 torben 433 }
595     }
596 torben 237 }

  ViewVC Help
Powered by ViewVC 1.1.20