Android Open Source - mycitybikes-android My City Bikes Activity






From Project

Back to project page mycitybikes-android.

License

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.

Java Source Code

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) {
  }
}




Java Source Code List

com.mycitybikes.android.ClearChannel.java
com.mycitybikes.android.Constants.java
com.mycitybikes.android.JCDecaux.java
com.mycitybikes.android.MyCityBikesActivity.java
com.mycitybikes.android.model.City.java
com.mycitybikes.android.model.StationInfoBuilder.java
com.mycitybikes.android.model.StationLocation.java
com.mycitybikes.android.model.StationStatus.java
com.mycitybikes.android.util.AndroidUtils.java
com.mycitybikes.android.util.Utils.java
com.mycitybikes.android.view.MapLocationItemizedOverlay.java