Back to project page mycitybikes-android.
The source code is released under:
GNU General Public License
If you think the Android project mycitybikes-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.mycitybikes.android; /* ww w.java 2s . c om*/ import java.util.ArrayList; import java.util.Collections; import java.util.List; import android.content.Context; import android.graphics.drawable.Drawable; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.mycitybikes.android.model.StationLocation; import com.mycitybikes.android.model.StationStatus; import com.mycitybikes.android.util.AndroidUtils; import com.mycitybikes.android.view.MapLocationItemizedOverlay; /* * TODO * * menu button * ** settings * * selection of network provider (GPS vs ) ? */ public class MyCityBikesActivity extends MapActivity implements LocationListener { private MapView mapView; private Location myLocation; private MapController mc; private LocationManager locationManager; private List<StationLocation> stationLocations = new ArrayList<StationLocation>(); private Drawable meMarker; private Drawable stationsMarker; private Drawable highlightMarker; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mapView = (MapView) findViewById(R.id.mapView); mapView.setBuiltInZoomControls(true); meMarker = mapView.getResources().getDrawable(R.drawable.marker_orange); stationsMarker = mapView.getResources().getDrawable( R.drawable.marker_blue); highlightMarker = mapView.getResources().getDrawable( R.drawable.marker_green); // refresh current location locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); // LocationProvider locationProvider = // locationManager.getProvider(LocationManager.NETWORK_PROVIDER); // Location lastLocation = // locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); mc = mapView.getController(); String providerName = LocationManager.GPS_PROVIDER; try { locationManager.setTestProviderStatus(providerName, LocationProvider.AVAILABLE, null, System .currentTimeMillis()); locationManager.setTestProviderEnabled(providerName, true); } catch (Exception e) { Log.e(Constants.TAG, "Failed to enable TestProvider " + e.getMessage(), e); } try { Log.v(Constants.TAG, "requestLocationUpdates() "); locationManager.requestLocationUpdates(providerName, 60000, 20, this); } catch (Exception e) { Log.e(Constants.TAG, "Failed to requestLocationUpdates() from " + providerName + ": " + e.getMessage(), e); } providerName = LocationManager.NETWORK_PROVIDER; try { Log.v(Constants.TAG, "requestLocationUpdates() "); locationManager.requestLocationUpdates(providerName, 60000, 20, this); } catch (Exception e) { Log.e(Constants.TAG, "Failed to requestLocationUpdates() from " + providerName + ": " + e.getMessage(), e); } //Debug.startMethodTracing("myCityBikes", 32*1024*1024); ClearChannel.loadOsloBikeLocations(getApplicationContext(), stationLocations); ClearChannel.loadWashingtonBikeLocations(getApplicationContext(), stationLocations); ClearChannel.loadStockholmBikeLocations(getApplicationContext(), stationLocations); // Disabled until we find a way to speed up things. 1000+ overlay items don't cut it... /* ClearChannel.loadBarcelonaBikeLocations(getApplicationContext(), stationLocations); JCDecaux.loadParisBikeLocations(getApplicationContext(), stationLocations); */ //Debug.stopMethodTracing(); } private void zoomToEarthLevel() { mc.setZoom(1); // mapView.invalidate(); } private void animateMapToMyLocation() { GeoPoint point = animateToLocation(myLocation); mc.setZoom(15); // FIXME consider auto-adapting zoom level based on // distance // to closest bike station. Or using user prefs // ---Add a location marker--- MapLocationItemizedOverlay mapOverlay = new MapLocationItemizedOverlay( mapView, meMarker, stationsMarker, highlightMarker, point, stationLocations); List<Overlay> listOfOverlays = mapView.getOverlays(); listOfOverlays.clear(); listOfOverlays.add(mapOverlay); mapView.invalidate(); } private GeoPoint animateToLocation(Location location) { Log.v(Constants.TAG, "animate to " + location); GeoPoint point = AndroidUtils.buildGeoPoint(location.getLatitude(), location.getLongitude()); mc.animateTo(point); return point; } private static final int MENU_GO_TO_MY_LOCATION = 1; private static final int MENU_GO_TO_CITY = 2; private static final int MENU_GO_TO_DIRECTION = 3; private static final int MENU_GO_TO_EARTH = 4; private static final int MENU_CLOSEST_STATION_WITH_BIKE = 3; private static final int MENU_CLOSEST_STATION_WITH_SLOT = 4; private static final int GO_TO_MENU_GROUP = 1; private static final int MAP_MODE_MENU_GROUP = 2; private static final int MENU_MAP_MODE_MAP = 1; private static final int MENU_MAP_MODE_SATELLITE = 2; private static final int MENU_MAP_MODE_TRAFFIC = 3; private static final int MENU_MAP_MODE_STREET = 4; @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem item; SubMenu subMenu; subMenu = menu.addSubMenu("Go to"); item = subMenu.add(GO_TO_MENU_GROUP, MENU_GO_TO_MY_LOCATION, Menu.NONE, "My Location"); item.setIcon(meMarker); // FIXME implement // item = subMenu.add(GO_TO_MENU_GROUP, MENU_GO_TO_CITY, Menu.NONE, "City"); //item = subMenu.add(GO_TO_MENU_GROUP, MENU_GO_TO_DIRECTION, Menu.NONE, "Direction"); item = subMenu.add(GO_TO_MENU_GROUP, MENU_GO_TO_EARTH, Menu.NONE, "Earth View"); subMenu = menu.addSubMenu("Map Mode"); item = subMenu.add(MAP_MODE_MENU_GROUP, MENU_MAP_MODE_MAP, Menu.NONE, "Map"); item.setChecked(!mapView.isSatellite() && !mapView.isTraffic() && !mapView.isStreetView()); item = subMenu.add(MAP_MODE_MENU_GROUP, MENU_MAP_MODE_SATELLITE, Menu.NONE, "Satellite"); item.setChecked(mapView.isSatellite()); item = subMenu.add(MAP_MODE_MENU_GROUP, MENU_MAP_MODE_TRAFFIC, Menu.NONE, "Traffic"); item.setChecked(mapView.isTraffic()); item = subMenu.add(MAP_MODE_MENU_GROUP, MENU_MAP_MODE_STREET, Menu.NONE, "Street View"); item.setChecked(mapView.isStreetView()); subMenu.setGroupCheckable(MAP_MODE_MENU_GROUP, true, true); menu.add(Menu.NONE, MENU_CLOSEST_STATION_WITH_BIKE, Menu.NONE, "Closest Bike"); menu.add(Menu.NONE, MENU_CLOSEST_STATION_WITH_SLOT, Menu.NONE, "Closest Slot"); // menu.add(Menu.NONE, MENU_SATELLITE_SWITCH, Menu.NONE, "Settings"); // menu.add(Menu.NONE, MENU_SATELLITE_SWITCH, Menu.NONE, "Quit"); return true; } static enum FindStationCriteria { ReadyBike, FreeSlot } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getGroupId()) { case 0: switch (item.getItemId()) { case MENU_CLOSEST_STATION_WITH_BIKE: findClosestStation(FindStationCriteria.ReadyBike); return true; case MENU_CLOSEST_STATION_WITH_SLOT: findClosestStation(FindStationCriteria.FreeSlot); return true; } break; case GO_TO_MENU_GROUP: switch (item.getItemId()) { case MENU_GO_TO_MY_LOCATION: if (myLocation == null) { // FIXME myLocation not yet populated. We should consider // ask the user to retry re-populating return true; } mc.setZoom(15); animateToLocation(myLocation); return true; case MENU_GO_TO_CITY: return true; case MENU_GO_TO_DIRECTION: return true; case MENU_GO_TO_EARTH: zoomToEarthLevel(); return true; } case MAP_MODE_MENU_GROUP: item.setChecked(true); switch (item.getItemId()) { case MENU_MAP_MODE_MAP: mapView.setSatellite(false); mapView.setStreetView(false); mapView.setTraffic(false); return true; case MENU_MAP_MODE_SATELLITE: mapView.setSatellite(true); // mapView.setTraffic(false); return true; case MENU_MAP_MODE_TRAFFIC: mapView.setSatellite(false); mapView.setTraffic(true); return true; case MENU_MAP_MODE_STREET: mapView.setSatellite(false); mapView.setStreetView(true); return true; } } return false; } private static class LocationAndDistance implements Comparable<LocationAndDistance> { private StationLocation stationLocation; // private Location location; private float distanceInMeters; public LocationAndDistance(StationLocation stationLocation/* * , Location * location */, float distanceInMeters) { this.stationLocation = stationLocation; // this.location = location; this.distanceInMeters = distanceInMeters; } public int compareTo(LocationAndDistance another) { return (int) (this.distanceInMeters - another.distanceInMeters); } public int getStationIndex() { return stationLocation.getId(); } } public void findClosestStation(FindStationCriteria criteria) { // FIXME do we want to provide closest station from currently centered // point // ? /* * GeoPoint point = mapView.getMapCenter(); Location center = new * Location(Constants.TAG); center.setLatitude(point.getLatitudeE6() / * 1E6); center.setLongitude(point.getLongitudeE6() / 1E6); */ Location center = this.myLocation; List<LocationAndDistance> sortedStationLocations = new ArrayList<LocationAndDistance>(); for (StationLocation l : stationLocations) { Location loc = new Location(Constants.TAG); loc.setLatitude(l.getLocation().getLatitudeE6() / 1E6); loc.setLongitude(l.getLocation().getLongitudeE6() / 1E6); sortedStationLocations.add(new LocationAndDistance(l, center.distanceTo(loc))); } Collections.sort(sortedStationLocations); // find first matching station // FIXME olso specific StationLocation foundStation = null; for (LocationAndDistance lad : sortedStationLocations) { try { StationStatus status = ClearChannel .readBikeStationStatus(lad.getStationIndex()); if ((criteria == FindStationCriteria.ReadyBike && status .getReadyBikes() > 0) || (criteria == FindStationCriteria.FreeSlot && status .getEmptyLocks() > 0)) { foundStation = lad.stationLocation; Log.v(Constants.TAG, "Found station:" + foundStation); break; } } catch (Exception e) { // FIXME find a way to display the fact that some nearer // stations don't // have status information available continue; } } if (foundStation != null) { MapLocationItemizedOverlay overlay = ((MapLocationItemizedOverlay) mapView .getOverlays().get(0)); String prefix = criteria == FindStationCriteria.ReadyBike ? "station with closest bike:\n" : "station with closest free slot:\n"; overlay.actUponTapLocation(overlay.findOverlayIndex(foundStation .getId()), prefix); } } @Override protected boolean isRouteDisplayed() { return false; } public void onLocationChanged(Location location) { this.myLocation = location; animateMapToMyLocation(); locationManager.removeUpdates(this); } public void onProviderDisabled(String provider) { } public void onProviderEnabled(String provider) { } public void onStatusChanged(String provider, int status, Bundle extras) { } }