/[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 1577 - (show annotations) (download)
Sun Jul 10 07:45:38 2011 UTC (12 years, 10 months ago) by torben
File size: 15107 byte(s)
Also save the search string
1 package dk.thoerup.traininfo;
2
3 import static dk.thoerup.traininfo.R.string.app_name;
4 import static dk.thoerup.traininfo.R.string.generic_cancel;
5 import static dk.thoerup.traininfo.R.string.generic_retry;
6 import static dk.thoerup.traininfo.R.string.stationlist_accuracy;
7 import static dk.thoerup.traininfo.R.string.stationlist_addfavorite;
8 import static dk.thoerup.traininfo.R.string.stationlist_favorites;
9 import static dk.thoerup.traininfo.R.string.stationlist_gpsinfo;
10 import static dk.thoerup.traininfo.R.string.stationlist_gpstimeout;
11 import static dk.thoerup.traininfo.R.string.stationlist_latitude;
12 import static dk.thoerup.traininfo.R.string.stationlist_locationinfo;
13 import static dk.thoerup.traininfo.R.string.stationlist_longitude;
14 import static dk.thoerup.traininfo.R.string.stationlist_nearbystations;
15 import static dk.thoerup.traininfo.R.string.stationlist_nofavorites;
16 import static dk.thoerup.traininfo.R.string.stationlist_nolocationprovider;
17 import static dk.thoerup.traininfo.R.string.stationlist_obtainedby;
18 import static dk.thoerup.traininfo.R.string.stationlist_removefavorite;
19 import static dk.thoerup.traininfo.R.string.stationlist_satellitecount;
20 import static dk.thoerup.traininfo.R.string.stationlist_search;
21 import static dk.thoerup.traininfo.R.string.stationlist_stationadded;
22 import static dk.thoerup.traininfo.R.string.stationlist_stationmap;
23 import static dk.thoerup.traininfo.R.string.stationlist_stationremoved;
24 import static dk.thoerup.traininfo.R.string.stationlist_waitforlocation;
25
26 import java.util.ArrayList;
27
28 import android.app.Activity;
29 import android.app.AlertDialog;
30 import android.app.Dialog;
31 import android.app.ListActivity;
32 import android.app.ProgressDialog;
33 import android.content.DialogInterface;
34 import android.content.Intent;
35 import android.content.SharedPreferences;
36 import android.content.SharedPreferences.Editor;
37 import android.location.Location;
38 import android.os.Bundle;
39 import android.os.Handler;
40 import android.os.Message;
41 import android.text.Editable;
42 import android.text.TextWatcher;
43 import android.util.Log;
44 import android.view.ContextMenu;
45 import android.view.ContextMenu.ContextMenuInfo;
46 import android.view.Menu;
47 import android.view.MenuItem;
48 import android.view.View;
49 import android.view.View.OnCreateContextMenuListener;
50 import android.widget.AdapterView;
51 import android.widget.ListView;
52 import android.widget.TextView;
53 import android.widget.Toast;
54 import dk.thoerup.android.traininfo.common.StationBean;
55 import dk.thoerup.android.traininfo.common.StationEntry;
56 import dk.thoerup.traininfo.WelcomeScreen.ListType;
57 import dk.thoerup.traininfo.provider.ProviderFactory;
58 import dk.thoerup.traininfo.provider.StationProvider;
59 import dk.thoerup.traininfo.stationmap.GeoPair;
60 import dk.thoerup.traininfo.stationmap.StationMapView;
61 import dk.thoerup.traininfo.util.IntSet;
62 import dk.thoerup.traininfo.util.MessageBox;
63
64 public class StationList extends ListActivity {
65
66
67
68 public static final int OPTIONS_MAP = 103;
69 public static final int OPTIONS_GPSINFO = 104;
70
71 public static final int DLG_PROGRESS = 3001;
72
73
74 public static final int GPS_TIMEOUT_MS = 15000; //how long are we willing to wait for gps fix -in milliseconds
75
76
77 static enum LookupMethod {
78 ByLocation,
79 ByName,
80 ByList,
81 MethodNone
82 }
83
84
85 String dialogMessage = "";
86 ProgressDialog dialog;
87 LocationLookup locationLookup = null;
88 StationsFetchedHandler stationsFetched = new StationsFetchedHandler();
89
90 //GeoPair location = new GeoPair();
91
92 boolean isLaunchedforShortcut;
93
94 StationBean stations = new StationBean();
95
96 StationProvider stationProvider = ProviderFactory.getStationProvider();
97
98 StationListAdapter adapter = null;
99
100 FavoritesMenu contextMenu = new FavoritesMenu();
101 IntSet favorites = new IntSet();
102
103 WelcomeScreen.ListType listType;
104 SharedPreferences prefs;
105
106 ///////////////////////////////////////////////////////////////////////////////////////////
107 //Activity call backs
108
109
110 @Override
111 public void onCreate(Bundle savedInstanceState) {
112 super.onCreate(savedInstanceState);
113 setContentView(R.layout.stationlist);
114
115 listType = (WelcomeScreen.ListType) getIntent().getSerializableExtra("type");
116
117 adapter = new StationListAdapter(this, (listType == ListType.ListNearest) );
118 setListAdapter(adapter);
119
120 ListView lv = getListView();
121 lv.setOnCreateContextMenuListener(contextMenu);
122
123 locationLookup = new LocationLookup(this);
124
125
126 prefs = getSharedPreferences("TrainStation", 0);
127 String favoriteString = prefs.getString("favorites", "");
128 if (! favoriteString.equals("") ) {
129 favorites.fromString(favoriteString);
130 }
131
132 setTitle();
133
134 isLaunchedforShortcut = getIntent().getBooleanExtra("shortcut", false);
135
136 ProviderFactory.purgeOldEntries(); //cleanup before fetching more data
137
138 if (listType == ListType.ListSearch) {
139 enableNamesearchField();
140 }
141
142 if (savedInstanceState == null) {
143
144 switch (listType) {
145 case ListNearest:
146 startNearestLookup();
147 break;
148 case ListSearch:
149 // do nothing here
150 break;
151 case ListFavorites:
152 startFavoriteLookup();
153 break;
154 default:
155 // Not possible !?!
156 }
157
158 } else {
159 ((TextView)findViewById(R.id.stationsearch)).setText( savedInstanceState.getString( "search") );
160
161 stations = (StationBean) savedInstanceState.getSerializable("stations");
162 adapter.setStations(stations);
163 }
164
165 }
166
167
168
169
170
171
172 @Override
173 protected void onDestroy() {
174 super.onDestroy();
175
176 stationsFetched.removeMessages(0);
177
178
179 if (locationLookup != null) {
180 locationLookup.stopSearch();
181 }
182
183 }
184
185
186 protected void setTitle() {
187 String dialogTitle = getResources().getString(app_name);
188 switch (listType) {
189 case ListNearest:
190 dialogTitle += " - " + getString(stationlist_nearbystations);
191 break;
192 case ListSearch:
193 dialogTitle += " - " + getString(stationlist_search);
194 break;
195 case ListFavorites:
196 dialogTitle += " - " + getString(stationlist_favorites);
197 break;
198 default:
199 dialogTitle = "";//not possible
200 }
201
202 setTitle(dialogTitle);
203
204 }
205
206
207 public void enableNamesearchField() {
208 final TextView stationSearch = (TextView) findViewById(R.id.stationsearch);
209 stationSearch.setVisibility( View.VISIBLE );
210 stationSearch.addTextChangedListener( new TextWatcher() {
211
212 @Override
213 public void afterTextChanged(Editable s) {
214 if (s.length() > 0) {
215 startNameLookup( s.toString() );
216 } else {
217 stations = new StationBean();
218 getListView().invalidateViews();
219 adapter.setStations( stations );
220 }
221 }
222
223 @Override
224 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
225 }
226
227 @Override
228 public void onTextChanged(CharSequence s, int start, int before, int count) {
229 }
230
231 });
232
233
234 }
235
236
237 @Override
238 public void onSaveInstanceState(Bundle outState)
239 {
240 if (dialog != null && dialog.isShowing())
241 dialog.dismiss();
242 outState.putSerializable("stations", (StationBean) stations);
243 outState.putString("search", ((TextView)findViewById(R.id.stationsearch)).getText().toString() );
244
245 }
246
247
248
249 @Override
250 public boolean onCreateOptionsMenu(Menu menu) {
251 MenuItem item;
252
253 item = menu.add(0, OPTIONS_MAP, 0, getString(stationlist_stationmap));
254 item.setIcon(android.R.drawable.ic_menu_mapmode);
255
256 item = menu.add(0, OPTIONS_GPSINFO, 0, getString(stationlist_gpsinfo));
257 item.setIcon(android.R.drawable.ic_menu_info_details);
258 boolean hasLoc = (locationLookup.getLocation() != null);
259 item.setEnabled(hasLoc);
260
261 return true;
262 }
263
264
265
266
267 @Override
268 public boolean onOptionsItemSelected(MenuItem item) {
269 boolean retval = true;
270
271
272 switch (item.getItemId()) {
273 case OPTIONS_MAP:
274
275 if ( stations == null || stations.entries == null || stations.entries.size() == 0 ) {
276 Toast.makeText(this, "No stations to show on map", Toast.LENGTH_SHORT).show(); //TODO: Translate
277 return true;
278 }
279
280 Intent intent = new Intent(this,StationMapView.class);
281
282 ArrayList<GeoPair> stationPoints = new ArrayList<GeoPair>();
283 for (StationEntry st : stations.entries ) {
284 stationPoints.add( new GeoPair(st.getLatitude(), st.getLongitude(), st.getName()) );
285 }
286
287 intent.putExtra("stations", stationPoints);
288
289 startActivity(intent);
290 break;
291 case OPTIONS_GPSINFO:
292 Location loc = locationLookup.getLocation();
293 StringBuffer message = new StringBuffer();
294 message.append( getString(stationlist_locationinfo) ).append(":\n");
295
296 message.append( getString(stationlist_obtainedby) ).append( loc.getProvider() ).append("\n");
297 message.append( getString(stationlist_accuracy) ).append( (int)loc.getAccuracy()).append("m\n");
298 message.append( getString(stationlist_latitude) ).append( (float)loc.getLatitude()).append("\n");
299 message.append( getString(stationlist_longitude) ).append( (float)loc.getLongitude() ).append("\n");
300
301
302 MessageBox.showMessage(this, message.toString(), false);
303 break;
304 default:
305 retval = super.onOptionsItemSelected(item);
306 }
307
308 return retval;
309 }
310
311
312
313 @Override
314 public boolean onContextItemSelected(MenuItem item) {
315 contextMenu.onContextItemSelected(item);
316 return true;
317
318
319 }
320
321 public void showMessageAndClose(String message) {
322 AlertDialog.Builder builder = new AlertDialog.Builder(this);
323 builder.setMessage(message)
324 .setCancelable(false)
325 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
326 public void onClick(DialogInterface dialog, int id) {
327 dialog.dismiss();
328 StationList.this.finish();
329 }
330 })
331 .show();
332 }
333
334
335
336
337 @Override
338 protected Dialog onCreateDialog(int id) {
339 switch (id) {
340 case DLG_PROGRESS:
341 ProgressDialog dlg = new ProgressDialog(this);
342 dlg.setMessage( getString(stationlist_waitforlocation) );
343 dlg.setCancelable(false);
344 return dlg;
345
346 default:
347 return super.onCreateDialog(id);
348 }
349
350 }
351
352
353 @Override
354 protected void onPrepareDialog(int id, Dialog dialog) {
355 super.onPrepareDialog(id, dialog);
356 switch (id) {
357 case DLG_PROGRESS:
358 this.dialog = (ProgressDialog) dialog;
359 if (!dialogMessage.equals("")) {
360 this.dialog.setMessage(dialogMessage);
361 dialogMessage = "";
362 }
363 break;
364 }
365 }
366
367 @Override
368 protected void onListItemClick(ListView l, View v, int position, long id) {
369 super.onListItemClick(l, v, position, id);
370
371 StationEntry station = stations.entries.get(position);
372
373 if (isLaunchedforShortcut == true) {
374 Intent i = new Intent();
375 i.putExtra("station", station);
376 setResult(Activity.RESULT_OK, i);
377 finish();
378 } else {
379 Intent intent = new Intent(this, DepartureList.class);
380 intent.putExtra("stationbean", station);
381 startActivity(intent);
382 }
383 }
384
385 /////////////////////////////////////////////////////////////
386 //
387
388 public void startNearestLookup() {
389 dialogMessage = getString( stationlist_waitforlocation );
390 showDialog(DLG_PROGRESS);
391
392 locationLookup.locateStations();
393 stationsFetched.sendEmptyMessageDelayed(0, 500);
394 }
395
396 void startNameLookup(String name) {
397
398 stations = stationProvider.lookupStationsByName(name);
399 getListView().invalidateViews();
400 adapter.setStations( stations );
401 }
402
403 public void startFavoriteLookup() {
404
405 if (favorites.size() > 0) {
406
407 stations = stationProvider.lookupStationsByIds( favorites.toString() );
408 getListView().invalidateViews();
409 adapter.setStations( stations );
410
411
412 } else {
413 showMessageAndClose( getString( stationlist_nofavorites ) );
414 }
415 }
416
417
418
419 void startNearestLookupPhase2()
420 {
421 stations = stationProvider.lookupStationsByLocation( locationLookup.getLocation() );
422 getListView().invalidateViews();
423 adapter.setStations( stations );
424 }
425
426
427 ////////////////////////////////////////////////////////////////////////////
428 // Inner classes
429
430 class StationsFetchedHandler extends Handler {
431 @Override
432 public void handleMessage(Message msg) {
433
434 LocationLookup.LookupStates state = locationLookup.getState();
435
436
437 switch (state) {
438 case GOTLOCATION:
439 dismissDialog(DLG_PROGRESS);
440
441 startNearestLookupPhase2();
442
443 return;
444
445 case NOPROVIDER:
446 dismissDialog(DLG_PROGRESS);
447 MessageBox.showMessage(StationList.this, getString(stationlist_nolocationprovider), true );
448 //StationList.this.finish();
449 return;
450 case IDLE:
451 Log.e("TrainInfo", "How did this happen ???");
452 dismissDialog(DLG_PROGRESS); // how did we get here ??
453 return;
454
455 }
456
457
458
459 if (locationLookup.elapsedTime() >= GPS_TIMEOUT_MS) {
460 dismissDialog(DLG_PROGRESS);
461
462
463 locationLookup.stopSearch();
464
465 if (locationLookup.hasLocation()) {
466 startNearestLookupPhase2();
467 } else {
468 AlertDialog.Builder builder = new AlertDialog.Builder(StationList.this);
469 builder.setMessage( getString( stationlist_gpstimeout) );
470 builder.setCancelable(true);
471 builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
472 public void onClick(DialogInterface dialog, int id) {
473 dialog.dismiss();
474 startNearestLookup();
475
476 }
477 });
478 builder.setNegativeButton( getString(generic_cancel), new DialogInterface.OnClickListener() {
479 public void onClick(DialogInterface dialog, int id) {
480 dialog.dismiss();
481 StationList.this.finish(); // Close this Activity
482 }
483 });
484 builder.show();
485
486 }
487 } else {
488 if (locationLookup.hasGps()) {
489 int count = locationLookup.getSatCount();
490 String dialogMessage = getString( stationlist_waitforlocation ) + "\n" + getString( stationlist_satellitecount ) + ": " + count;
491 dialog.setMessage( dialogMessage );
492 }
493 this.sendEmptyMessageDelayed(0, 500);
494 }
495
496 }
497 }
498
499
500
501
502 class FavoritesMenu implements OnCreateContextMenuListener {
503 private final static int FAVORITES_ADD = 9001;
504 private final static int FAVORITES_REMOVE = 9002;
505
506 private int selectedPosition;
507
508
509 @Override
510 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
511
512 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
513 selectedPosition = info.position;
514 int stationID = stations.entries.get(selectedPosition).getId();
515
516 if (!favorites.contains(stationID)) {
517 menu.add(0, FAVORITES_ADD, 0, getString(stationlist_addfavorite) );
518 } else {
519 menu.add(0, FAVORITES_REMOVE, 0, getString(stationlist_removefavorite) );
520 }
521
522 }
523
524 public void onContextItemSelected(MenuItem item) {
525 StationEntry sb = stations.entries.get(selectedPosition);
526
527 int stationID = sb.getId();
528 if (item.getItemId() == FAVORITES_ADD) {
529 favorites.add(stationID);
530 Toast.makeText(StationList.this, getString(stationlist_stationadded), Toast.LENGTH_SHORT).show();
531 } else {
532
533 favorites.remove(stationID);
534 Toast.makeText(StationList.this, getString(stationlist_stationremoved), Toast.LENGTH_SHORT).show();
535
536
537 if (listType.equals( WelcomeScreen.ListType.ListFavorites) ) {
538 stations.entries.remove(selectedPosition);
539 adapter.notifyDataSetChanged();
540 }
541 }
542 Editor ed = prefs.edit();
543 ed.putString("favorites", favorites.toString());
544 ed.commit();
545 }
546 }
547 }

  ViewVC Help
Powered by ViewVC 1.1.20