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

  ViewVC Help
Powered by ViewVC 1.1.20