/[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 1576 - (show annotations) (download)
Sun Jul 10 07:18:54 2011 UTC (12 years, 10 months ago) by torben
File size: 14899 byte(s)
The showing of the name search text field is not dependent on savedInstanceState
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 stations = (StationBean) savedInstanceState.getSerializable("stations");
160 adapter.setStations(stations);
161 }
162
163 }
164
165
166
167
168
169
170 @Override
171 protected void onDestroy() {
172 super.onDestroy();
173
174 stationsFetched.removeMessages(0);
175
176
177 if (locationLookup != null) {
178 locationLookup.stopSearch();
179 }
180
181 }
182
183
184 protected void setTitle() {
185 String dialogTitle = getResources().getString(app_name);
186 switch (listType) {
187 case ListNearest:
188 dialogTitle += " - " + getString(stationlist_nearbystations);
189 break;
190 case ListSearch:
191 dialogTitle += " - " + getString(stationlist_search);
192 break;
193 case ListFavorites:
194 dialogTitle += " - " + getString(stationlist_favorites);
195 break;
196 default:
197 dialogTitle = "";//not possible
198 }
199
200 setTitle(dialogTitle);
201
202 }
203
204
205 public void enableNamesearchField() {
206 final TextView stationSearch = (TextView) findViewById(R.id.stationsearch);
207 stationSearch.setVisibility( View.VISIBLE );
208 stationSearch.addTextChangedListener( new TextWatcher() {
209
210 @Override
211 public void afterTextChanged(Editable s) {
212 if (s.length() > 0) {
213 startNameLookup( s.toString() );
214 } else {
215 stations = new StationBean();
216 getListView().invalidateViews();
217 adapter.setStations( stations );
218 }
219 }
220
221 @Override
222 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
223 }
224
225 @Override
226 public void onTextChanged(CharSequence s, int start, int before, int count) {
227 }
228
229 });
230
231
232 }
233
234
235 @Override
236 public void onSaveInstanceState(Bundle outState)
237 {
238 if (dialog != null && dialog.isShowing())
239 dialog.dismiss();
240 outState.putSerializable("stations", (StationBean) stations);
241
242 }
243
244
245
246 @Override
247 public boolean onCreateOptionsMenu(Menu menu) {
248 MenuItem item;
249
250 item = menu.add(0, OPTIONS_MAP, 0, getString(stationlist_stationmap));
251 item.setIcon(android.R.drawable.ic_menu_mapmode);
252
253 item = menu.add(0, OPTIONS_GPSINFO, 0, getString(stationlist_gpsinfo));
254 item.setIcon(android.R.drawable.ic_menu_info_details);
255 boolean hasLoc = (locationLookup.getLocation() != null);
256 item.setEnabled(hasLoc);
257
258 return true;
259 }
260
261
262
263
264 @Override
265 public boolean onOptionsItemSelected(MenuItem item) {
266 boolean retval = true;
267
268
269 switch (item.getItemId()) {
270 case OPTIONS_MAP:
271
272 if ( stations == null || stations.entries == null || stations.entries.size() == 0 ) {
273 Toast.makeText(this, "No stations to show on map", Toast.LENGTH_SHORT).show(); //TODO: Translate
274 return true;
275 }
276
277 Intent intent = new Intent(this,StationMapView.class);
278
279 ArrayList<GeoPair> stationPoints = new ArrayList<GeoPair>();
280 for (StationEntry st : stations.entries ) {
281 stationPoints.add( new GeoPair(st.getLatitude(), st.getLongitude(), st.getName()) );
282 }
283
284 intent.putExtra("stations", stationPoints);
285
286 startActivity(intent);
287 break;
288 case OPTIONS_GPSINFO:
289 Location loc = locationLookup.getLocation();
290 StringBuffer message = new StringBuffer();
291 message.append( getString(stationlist_locationinfo) ).append(":\n");
292
293 message.append( getString(stationlist_obtainedby) ).append( loc.getProvider() ).append("\n");
294 message.append( getString(stationlist_accuracy) ).append( (int)loc.getAccuracy()).append("m\n");
295 message.append( getString(stationlist_latitude) ).append( (float)loc.getLatitude()).append("\n");
296 message.append( getString(stationlist_longitude) ).append( (float)loc.getLongitude() ).append("\n");
297
298
299 MessageBox.showMessage(this, message.toString(), false);
300 break;
301 default:
302 retval = super.onOptionsItemSelected(item);
303 }
304
305 return retval;
306 }
307
308
309
310 @Override
311 public boolean onContextItemSelected(MenuItem item) {
312 contextMenu.onContextItemSelected(item);
313 return true;
314
315
316 }
317
318 public void showMessageAndClose(String message) {
319 AlertDialog.Builder builder = new AlertDialog.Builder(this);
320 builder.setMessage(message)
321 .setCancelable(false)
322 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
323 public void onClick(DialogInterface dialog, int id) {
324 dialog.dismiss();
325 StationList.this.finish();
326 }
327 })
328 .show();
329 }
330
331
332
333
334 @Override
335 protected Dialog onCreateDialog(int id) {
336 switch (id) {
337 case DLG_PROGRESS:
338 ProgressDialog dlg = new ProgressDialog(this);
339 dlg.setMessage( getString(stationlist_waitforlocation) );
340 dlg.setCancelable(false);
341 return dlg;
342
343 default:
344 return super.onCreateDialog(id);
345 }
346
347 }
348
349
350 @Override
351 protected void onPrepareDialog(int id, Dialog dialog) {
352 super.onPrepareDialog(id, dialog);
353 switch (id) {
354 case DLG_PROGRESS:
355 this.dialog = (ProgressDialog) dialog;
356 if (!dialogMessage.equals("")) {
357 this.dialog.setMessage(dialogMessage);
358 dialogMessage = "";
359 }
360 break;
361 }
362 }
363
364 @Override
365 protected void onListItemClick(ListView l, View v, int position, long id) {
366 super.onListItemClick(l, v, position, id);
367
368 StationEntry station = stations.entries.get(position);
369
370 if (isLaunchedforShortcut == true) {
371 Intent i = new Intent();
372 i.putExtra("station", station);
373 setResult(Activity.RESULT_OK, i);
374 finish();
375 } else {
376 Intent intent = new Intent(this, DepartureList.class);
377 intent.putExtra("stationbean", station);
378 startActivity(intent);
379 }
380 }
381
382 /////////////////////////////////////////////////////////////
383 //
384
385 public void startNearestLookup() {
386 dialogMessage = getString( stationlist_waitforlocation );
387 showDialog(DLG_PROGRESS);
388
389 locationLookup.locateStations();
390 stationsFetched.sendEmptyMessageDelayed(0, 500);
391 }
392
393 void startNameLookup(String name) {
394
395 stations = stationProvider.lookupStationsByName(name);
396 getListView().invalidateViews();
397 adapter.setStations( stations );
398 }
399
400 public void startFavoriteLookup() {
401
402 if (favorites.size() > 0) {
403
404 stations = stationProvider.lookupStationsByIds( favorites.toString() );
405 getListView().invalidateViews();
406 adapter.setStations( stations );
407
408
409 } else {
410 showMessageAndClose( getString( stationlist_nofavorites ) );
411 }
412 }
413
414
415
416 void startNearestLookupPhase2()
417 {
418 stations = stationProvider.lookupStationsByLocation( locationLookup.getLocation() );
419 getListView().invalidateViews();
420 adapter.setStations( stations );
421 }
422
423
424 ////////////////////////////////////////////////////////////////////////////
425 // Inner classes
426
427 class StationsFetchedHandler extends Handler {
428 @Override
429 public void handleMessage(Message msg) {
430
431 LocationLookup.LookupStates state = locationLookup.getState();
432
433
434 switch (state) {
435 case GOTLOCATION:
436 dismissDialog(DLG_PROGRESS);
437
438 startNearestLookupPhase2();
439
440 return;
441
442 case NOPROVIDER:
443 dismissDialog(DLG_PROGRESS);
444 MessageBox.showMessage(StationList.this, getString(stationlist_nolocationprovider), true );
445 //StationList.this.finish();
446 return;
447 case IDLE:
448 Log.e("TrainInfo", "How did this happen ???");
449 dismissDialog(DLG_PROGRESS); // how did we get here ??
450 return;
451
452 }
453
454
455
456 if (locationLookup.elapsedTime() >= GPS_TIMEOUT_MS) {
457 dismissDialog(DLG_PROGRESS);
458
459
460 locationLookup.stopSearch();
461
462 if (locationLookup.hasLocation()) {
463 startNearestLookupPhase2();
464 } else {
465 AlertDialog.Builder builder = new AlertDialog.Builder(StationList.this);
466 builder.setMessage( getString( stationlist_gpstimeout) );
467 builder.setCancelable(true);
468 builder.setPositiveButton(getString(generic_retry), new DialogInterface.OnClickListener() {
469 public void onClick(DialogInterface dialog, int id) {
470 dialog.dismiss();
471 startNearestLookup();
472
473 }
474 });
475 builder.setNegativeButton( getString(generic_cancel), new DialogInterface.OnClickListener() {
476 public void onClick(DialogInterface dialog, int id) {
477 dialog.dismiss();
478 StationList.this.finish(); // Close this Activity
479 }
480 });
481 builder.show();
482
483 }
484 } else {
485 if (locationLookup.hasGps()) {
486 int count = locationLookup.getSatCount();
487 String dialogMessage = getString( stationlist_waitforlocation ) + "\n" + getString( stationlist_satellitecount ) + ": " + count;
488 dialog.setMessage( dialogMessage );
489 }
490 this.sendEmptyMessageDelayed(0, 500);
491 }
492
493 }
494 }
495
496
497
498
499 class FavoritesMenu implements OnCreateContextMenuListener {
500 private final static int FAVORITES_ADD = 9001;
501 private final static int FAVORITES_REMOVE = 9002;
502
503 private int selectedPosition;
504
505
506 @Override
507 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
508
509 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
510 selectedPosition = info.position;
511 int stationID = stations.entries.get(selectedPosition).getId();
512
513 if (!favorites.contains(stationID)) {
514 menu.add(0, FAVORITES_ADD, 0, getString(stationlist_addfavorite) );
515 } else {
516 menu.add(0, FAVORITES_REMOVE, 0, getString(stationlist_removefavorite) );
517 }
518
519 }
520
521 public void onContextItemSelected(MenuItem item) {
522 StationEntry sb = stations.entries.get(selectedPosition);
523
524 int stationID = sb.getId();
525 if (item.getItemId() == FAVORITES_ADD) {
526 favorites.add(stationID);
527 Toast.makeText(StationList.this, getString(stationlist_stationadded), Toast.LENGTH_SHORT).show();
528 } else {
529
530 favorites.remove(stationID);
531 Toast.makeText(StationList.this, getString(stationlist_stationremoved), Toast.LENGTH_SHORT).show();
532
533
534 if (listType.equals( WelcomeScreen.ListType.ListFavorites) ) {
535 stations.entries.remove(selectedPosition);
536 adapter.notifyDataSetChanged();
537 }
538 }
539 Editor ed = prefs.edit();
540 ed.putString("favorites", favorites.toString());
541 ed.commit();
542 }
543 }
544 }

  ViewVC Help
Powered by ViewVC 1.1.20