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

  ViewVC Help
Powered by ViewVC 1.1.20