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

  ViewVC Help
Powered by ViewVC 1.1.20