public void cancelRecording() {
    if (trip != null) {
      trip.dropTrip();
    }

    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    lm.removeUpdates(this);

    sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    sm.unregisterListener(this);

    clearNotifications();
    this.state = STATE_IDLE;
  }
  // LocationListener implementation:
  @Override
  public void onLocationChanged(Location loc) {
    if (loc != null) {
      // Only save one beep per second.
      double currentTime = System.currentTimeMillis();
      if (currentTime - latestUpdate > 999) {

        latestUpdate = currentTime;
        updateTripStats(loc);
        boolean rtn = trip.addPointNow(loc, currentTime, distanceTraveled);
        if (!rtn) {
          // Log.e("FAIL", "Couldn't write to DB");
        }

        // Update the status page every time, if we can.
        notifyListeners();
      }
    }
  }
  public void startRecording(TripData trip) {
    this.state = STATE_RECORDING;
    this.trip = trip;

    curSpeed = maxSpeed = distanceTraveled = 0.0f;
    lastLocation = null;
    numBumps = 0;

    // Add the notify bar and blinking light
    setNotification();

    // Start listening for GPS updates!
    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

    // TO BE REMOVED
    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    boolean rtn = trip.addPointNow(location, System.currentTimeMillis(), 1f);

    // Start listening for Magnet sensor
    sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    magSensor = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    sm.registerListener(this, magSensor, SensorManager.SENSOR_DELAY_FASTEST);

    // Set up timer for bike bell
    if (timer != null) {
      timer.cancel();
      timer.purge();
    }
    timer = new Timer();
    timer.schedule(
        new TimerTask() {
          @Override
          public void run() {
            mHandler.post(mRemindUser);
          }
        },
        BELL_FIRST_INTERVAL * 60000,
        BELL_NEXT_INTERVAL * 60000);
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.show_map);

    Bundle cmds = getIntent().getExtras();

    if (cmds == null) {
      // We have no trip to show, do nothing
      return;
    }

    trip = TripData.fetchTrip(this, cmds.getLong("showtrip"));

    gpspoints = trip.getPoints();

    // Upload the trip if it hasn't yet been sent
    if (trip.status < TripData.STATUS_SENT || cmds.getBoolean("uploadTrip", false)) {
      // And upload to the cloud database, too!  W00t W00t!
      TripUploader uploader = new TripUploader(ShowMap.this);
      uploader.execute(trip.tripid);
    }

    // Show trip details
    setTitle(trip.purp);
    // ((TextView) findViewById(R.id.text2)).setText(trip.info);
    // ((TextView) findViewById(R.id.text3)).setText(trip.fancystart);

    // Set up the map
    GoogleMap map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

    CyclePoint startPoint = null;
    CyclePoint endPoint = null;
    LatLngBounds.Builder tripBoundsBuilder = new LatLngBounds.Builder();

    PolylineOptions tripLine =
        new PolylineOptions().color(getResources().getColor(R.color.accent_color));

    for (CyclePoint cyclepoint : gpspoints) {
      Log.i(getClass().getName(), cyclepoint.latLng.latitude + ", " + cyclepoint.latLng.longitude);
      // Add point to boundary calculator
      tripBoundsBuilder.include(cyclepoint.latLng);

      // Add to the trip line
      tripLine.add(cyclepoint.latLng);

      if (startPoint == null) startPoint = cyclepoint;
      endPoint = cyclepoint;
    }

    LatLngBounds tripBounds = tripBoundsBuilder.build();
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);

    int minSize = Math.min(size.x, size.y);
    Log.i(getClass().getName(), String.valueOf(minSize));

    // Zoome the camera so it shows the entire trip on the map
    map.moveCamera(CameraUpdateFactory.newLatLngBounds(tripBounds, minSize, minSize, 0));

    // Draw the trip on the map
    map.addPolyline(tripLine);

    // Show the first and last markers
    map.addMarker(
        new MarkerOptions()
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.trip_start))
            .anchor(0.5f, 0.5f)
            .position(startPoint.latLng));
    map.addMarker(
        new MarkerOptions()
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.trip_end))
            .anchor(0.5f, 0.5f)
            .position(endPoint.latLng));

    int total_seconds = (int) Math.round((trip.endTime - trip.startTime) / 1000);
    int seconds = total_seconds;
    int minutes = (int) Math.floor(seconds / 60);
    seconds -= (minutes * 60);
    int hours = (int) Math.floor(minutes / 60);
    minutes -= (hours * 60);

    double total_miles = 0.0006212f * trip.distance;

    double speed = total_miles / total_seconds * (60 * 60);

    double calories = Common.distanceToCals(trip.distance);
    calories = Math.max(calories, 0);

    View infoView = getLayoutInflater().inflate(R.layout.show_info, null);

    TextView text1 = (TextView) infoView.findViewById(R.id.text1);
    infoView.findViewById(R.id.image_view).setVisibility(View.GONE);

    text1.setText(
        Html.fromHtml(
            TextUtils.join(
                "<br>",
                new String[] {
                  String.format(
                      "<b>" + getString(R.string.start_time) + "</b> %s", trip.fancystart),
                  String.format(
                      "<b>" + getString(R.string.time_elapsed) + "</b> %1$02d:%2$02d:%3$02d",
                      hours,
                      minutes,
                      seconds),
                  String.format(
                      "<b>" + getString(R.string.distance) + "</b> %1.1f miles", total_miles),
                  String.format("<b>" + getString(R.string.avg_speed) + "</b> %1.1f mph", speed),
                  String.format("<b>" + getString(R.string.est_cal) + "</b> %.1f kcal", calories),
                  String.format(
                      "<b>" + getString(R.string.c02_reduced) + "</b> %.1f lbs",
                      Common.distanceToCO2(trip.distance)),
                  String.format("<b>" + getString(R.string.notes) + "</b> %s", trip.note)
                })));

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setView(infoView);
    infoDialog = builder.create();
  }
  @Override
  public void onSensorChanged(SensorEvent event) {
    // TODO Auto-generated method stub
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];
    float value = Math.abs(x) + Math.abs(y) + Math.abs(z);
    double cal = Math.sqrt(x * x + y * y + z * z);
    double currentTime = System.currentTimeMillis();

    // first time
    if (lastCal == 0 && lastMag == 0) {
      magStartTime = currentTime;
      lastValue = value;
      lastMag = currentTime; // last calibration time
      lastBumpRecord = currentTime; // last bump recording time
      lastCal = cal; // calibration
    }

    // first 5 seconds calibrate
    if (currentTime - magStartTime < 5000) {
      lastCal = (lastCal + cal) / 2;
      lastMag = currentTime;
      lastValue = value;
      return;
    }

    // it's bump
    if (currentTime - lastBumpRecord > 999) {
      if (cal > 2 * lastCal) {
        if (!isBump) {
          isBump = true;
          // if(currentTime - lastBumpRecord > 2100){
          lastBumpRecord = currentTime;
          numBumps++;
          vibe.vibrate(500);
          mp.start();

          boolean rtn = true;
          if (lastLocation != null) {
            rtn = trip.addFlagNow(lastLocation, currentTime);
          } else {
            // TO BE REMOVED
            lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            rtn = trip.addFlagNow(location, currentTime);
            // System.out.println("#########"+location.getLatitude()+"
            // "+location.getLongitude());
          }
          if (!rtn) {
            System.out.println("could not save flag!!####!!!###");
          }

          // Update the status page every time, if we can.
          notifyListeners();
          // }
        }
      } else if (cal < 1.5 * lastCal) {
        isBump = false;
      }
    }

    // calibrate each second
    if (currentTime - lastMag > 999) {
      if (!isBump) {
        lastCal = (lastCal + cal) / 2;
        lastMag = currentTime;
      }
    }

    // Location lastLocation;
    // TripData trip;
    // double currentTime = System.currentTimeMillis();

  }