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

  ViewVC Help
Powered by ViewVC 1.1.20