Android Open Source - egotrip Map View Activity






From Project

Back to project page egotrip.

License

The source code is released under:

Apache License

If you think the Android project egotrip 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 net.myegotrip.egotrip;
// w w  w  .  java2 s.  co m
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import net.myegotrip.egotrip.map.Placemark;
import net.myegotrip.egotrip.map.PlacemarkOverlay;
import net.myegotrip.egotrip.map.RouteOverlay;
import net.myegotrip.egotrip.map.RoutePoint;
import net.myegotrip.egotrip.map.Trip;
import net.myegotrip.egotrip.metadata.Icon;
import net.myegotrip.egotrip.metadata.Image;
import net.myegotrip.egotrip.metadata.MetadataManager;
import net.myegotrip.egotrip.metadata.Text;
import net.myegotrip.egotrip.net.Uploader;
import net.myegotrip.egotrip.profile.ProfileActivity;
import net.myegotrip.egotrip.utils.DebugActivity;
import net.myegotrip.egotrip.utils.GuiUtils;
import net.myegotrip.egotrip.utils.IconItem;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.LayoutInflater.Factory;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;

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.google.android.maps.Projection;

public class MapViewActivity extends MapActivity implements DbListener {
  private static final String TAG = "EGOTRIP-MapView";

  // debugging
  private String debug; // debug utility class;

  // pro...?
  private boolean proFeaturesEnabled = false;

  private static final int CAMERA_REQUEST = 1888;
  private static final int SELECT_IMAGE_REQUEST = 1889;

  private static final int STATUS_UNKNOWN = 1;
  private static final int STATUS_STOPPED = 3;
  private static final int STATUS_RUNNING = 4;

  /** MAP RELATED */
  private MapView mapView;
  private MapController mapController;
  private Trip trip;
  private Placemark currentPlacemark;
  private boolean edit;
  private boolean firstTimeDraw = true;

  // initially, a tap on the map not related to a marker doesn't do anything
  private boolean TAP_ADD = false;
  private boolean TAP_MOVE = false;

  private int TAP_SPLIT = 0;
  private boolean TAP_INSERT_BEFORE = false;
  private boolean TAP_INSERT_AFTER = false;

  /** GPS and DB related */
  private GPSService gpsService;
  private DbTools dbtools;
  private Uploader uploader;

  private MetadataManager metamanager;
  private int gps_current_state;
  private int upl_current_state;

  /** MESSAGES/HANDLER */
  private static final int MESSAGE_STATUS = 100;
  private static final int MESSAGE_ADDTOPATH = 101;

  private static final int MESSAGE_INSERT = 0;
  private static final int MESSAGE_ADD = 1;
  private static final int MESSAGE_MOVE = 2;
  private static final int MESSAGE_NOPLACEMARK = 3;

  private static final int MESSAGE_SPLIT = 5;

  private static final int ACTION_ADD = 10;
  private static final int ACTION_MOVE = 11;
  private static final int ACTION_INSERT = 12;

  // TODO: replace with @strings
  private static int[] messages = { R.string.tap_to_insert_a_route_point,
      R.string.tap_the_map_to_add_a_marker_there,
      R.string.tap_the_map_to_move_marker,
      R.string.no_placemark_is_selected, R.string.there_is_no_trip,
      R.string.pick_the_first_point_of_the_new_trip };

  private Timer serviceTimer = new Timer();

  private String tripname;
  private SharedPreferences prefs;

  private GestureDetector mGestureDetector;

  private GuiUtils guiutils;
  private TripManager tripmanager;
  private String apptitle;

  private ServiceConnection serviceConn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
      p("onServiceConnection: " + name);
      GPSService.LocalBinder binder = (GPSService.LocalBinder) service;
      gpsService = binder.getService();
      uploader = gpsService.getUploader();

      t_checkStatusOfGps();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
  };

  /**
   * create the options menu (display refresh button)
   */
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.mapmenu, menu);

    MenuItem checkBox = (MenuItem) findViewById(R.id.menu_satellite);

    if (checkBox != null)
      checkBox.setChecked(mapView.isSatellite());
    checkBox = (MenuItem) findViewById(R.id.menu_traffic);
    if (checkBox != null)
      checkBox.setChecked(mapView.isTraffic());
    return true;
  }

  /**
   * tell the gps service to record the current location
   */
  public void forcelocationupdate(View v) {
    CommonGPSServiceFunctions.forcelocationupdate(gpsService, this);
  }

  /**
   * load trip with the most recent insert ... actually we want the CURRENT
   * trip name! Because this is called on each oncreate call!
   */
  private void loadNewestTrip() {
    String tname = tripmanager.getCurrenTripName();
    if (tname == null) {
      tname = FallbackDefaults.DEFAULT_TRIP_NAME;
    }
    tripname = tname;
    doOpenTrip(tripname);

    String startupview = prefs.getString("startup_view", "Startup");
    if (startupview != null && startupview.equalsIgnoreCase("profile")) {
      profileView(null);
    }
  }

  /** we need this because of a google bug.. . */
  public MapView getMapView() {
    return this.mapView;
  }

  /** TODO hide inaccurate ponits */
  private void doAutoHide() {
    Toast.makeText(this, "Auto hide inaccurate points not implemented...",
        Toast.LENGTH_SHORT).show();
  }

  private void doMoveTo(boolean first) {
    if (trip == null || !trip.hasRoutePoints())
      return;
    RoutePoint p = null;
    if (first)
      p = trip.getFirstPoint();
    else
      p = trip.getLastPoint();
    mapController.animateTo(p.getGeoPoint());
  }

  /**
   * handle refresh user request
   */
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.menu_closecont:
      this.finish();
      break;
    case R.id.menu_move_first:
      doMoveTo(true);
      break;
    case R.id.menu_move_last:
      doMoveTo(false);
      break;
    // case R.id.menu_edit_hide:
    // doAutoHide();
    // break;
    case R.id.menu_closestop:
      stopRecording();
      stopGpsService();
      this.finish();
      break;
    case R.id.menu_email_screenshot:
      if (checkPro())
        guiutils.doEmailScreenshot(this.mapView.getRootView());
      break;
    case R.id.menu_edit_map:
      this.editPath(mapView);
      break;
    case R.id.menu_new_trip:
      doNewTrip();
      break;
    case R.id.menu_open_trip:
      doOpenTrip();
      break;
    case R.id.menu_rename_trip:
      tripmanager
          .doRenameTrip(trip, getString(R.string.new_name_of_trip));
      updateTitle();
      break;
    case R.id.menu_split_trip:
      doSplitTrip();
      break;
    case R.id.menu_delete_trip:
      doDeleteTrip();
      break;
    case R.id.menu_settings:
      openPrefs();
      break;
    // case R.id.menu_debug:
    // openDebug();
    // break;
    case R.id.menu_satellite:
      item.setChecked(!item.isChecked());
      this.mapView.setSatellite(item.isChecked());
      break;
    case R.id.menu_traffic:
      item.setChecked(!item.isChecked());
      this.mapView.setTraffic(item.isChecked());
      break;
    // case R.id.menu_gps_settings:
    // if (gpsService!= null) guiutils.launchGPSOptions();
    // break;
    // case R.id.menu_control:
    // openControl();
    // break;

    case R.id.menu_viewtrail:
      tripmanager.openBrowser();
      break;

    case R.id.menu_add_placemark:
      if (checkPro())
        doAddPlacemark();

      break;
    default:
      break;
    }

    return true;
  }

  private boolean checkPro() {
    if (proFeaturesEnabled)
      return true;
    Toast.makeText(
        this,
        getApplicationContext()
            .getString(
                R.string.you_can_turn_on_this_feature_right_away_if_you_upgrade_to_the_full_version),
        Toast.LENGTH_LONG).show();
    guiutils.openMarket(ReleaseConfig.LICENSE_APP_PACKAGE_NAME);

    return false;
  }

  public void doAddPlacemark() {
    // get location on map?
    // maybe create marker overlay with custom ontap implemntaion?
    TAP_ADD = true;
    handler.sendEmptyMessage(MESSAGE_ADD);

    // check onTap
  }

  public void doSplitTrip() {
    TAP_SPLIT = 2;

    handler.sendEmptyMessage(MESSAGE_SPLIT);

    // check onTap
  }

  public void doMovePlacemark() {
    TAP_MOVE = true;
    handler.sendEmptyMessage(MESSAGE_MOVE);
    // check onTap
  }

  public void onTap(GeoPoint p) {
    p("Got on tap");
    if (TAP_ADD) {
      TAP_ADD = false; // only one marker at a time!
      // HANDLER MUST DO THIS!
      Message msg = new Message();
      msg.what = ACTION_ADD;
      msg.obj = p;
      handler.sendMessage(msg);

    } else if (TAP_MOVE) {
      TAP_MOVE = false; // only one move at a time
      Message msg = new Message();
      msg.what = ACTION_MOVE;
      msg.obj = p;
      handler.sendMessage(msg);

    } else if (TAP_INSERT_BEFORE || TAP_INSERT_AFTER) {
      TAP_INSERT_BEFORE = false;
      TAP_INSERT_AFTER = false;
      Message msg = new Message();
      msg.what = ACTION_INSERT;
      msg.obj = p;
      handler.sendMessage(msg);
    } else if (TAP_SPLIT > 0) {
      TAP_SPLIT--; // only one marker at a time!
      p("onTap:"
          + TAP_SPLIT
          + " user should click on rp and not on empty map - we give the user another change :-)");

    } else {
      // PROBLEM: when something is selected in the context menu
      // opens the context menu again... is there a way to check if the
      // menu is already open?
      // if (super.h.i
      // p("Just open map related menu.. maybe only on double tap? Or use a flag to check if the menu is already open? Will use mgesturedector");
      // this.openContextMenu(mapView);
    }
  }

  public void doNewTrip() {
    p("doNewTrip called");
    // clear any current data from gps
    if (gpsService != null)
      this.gpsService.clearData();
    trip = tripmanager.createNewTrip(R.string.name_of_new_trip);
    updateTitle();
    edit = false;
    firstTimeDraw = true;
    p("Name of new trip is:" + trip.getName());
    this.drawAll(trip, edit);

  }

  public void doDeleteTrip() {
    // show list of trips
    // if this trip is deleted, create new trip?
    final String[] items = getTripNames();
    if (items == null) {
      Toast.makeText(this, "There are no trips yet", Toast.LENGTH_LONG)
          .show();
      return;
    }
    ListAdapter adapter = createListAdapter(items);
    new AlertDialog.Builder(this).setTitle(getString(R.string.pick_a_trip))
        .setAdapter(adapter, new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, final int item) {
            if (item > -1) {
              // ask to make sure
              AlertDialog.Builder builder = new AlertDialog.Builder(
                  MapViewActivity.this);
              builder.setMessage(
                  "Are you sure you want to delete trip "
                      + items[item] + "?")
                  .setPositiveButton(
                      getString(R.string.yes),
                      new DialogInterface.OnClickListener() {
                        public void onClick(
                            DialogInterface dialog,
                            int notused) {

                          if (item < 0
                              || item >= items.length) {
                            p("Item id out of bounds: "
                                + item
                                + ", got only "
                                + items.length
                                + " trip names: "
                                + Arrays.toString(items));
                          } else {
                            String name = items[item];
                            p("Got item name: "
                                + name);
                            dbtools.markTripDeleted(name);
                            if (trip != null
                                && trip.getName()
                                    .equalsIgnoreCase(
                                        name)) {
                              // / THIS trip was
                              // deleted...
                              p("This trip was just deleted, doing new trip");
                              doNewTrip();

                            }
                          }
                        }
                      })
                  .setNegativeButton(getString(R.string.no),
                      null).show();
            }
          }
        }).show();
  }

  private ListAdapter createListAdapter(final String[] items) {
    ListAdapter adapter = new ArrayAdapter<String>(this,
        android.R.layout.select_dialog_item, android.R.id.text1, items) {
      public View getView(int position, View convertView, ViewGroup parent) {
        // User super class to create the View
        View v = super.getView(position, convertView, parent);
        TextView tv = (TextView) v.findViewById(android.R.id.text1);
        int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
        tv.setCompoundDrawablePadding(dp5);
        return v;
      }
    };
    return adapter;
  }

  private String[] getTripNames() {
    ArrayList<String> names = dbtools.getTripNames();
    if (names == null)
      return null;

    final String items[] = new String[names.size()];
    for (int i = 0; i < items.length; i++) {
      items[i] = names.get(i);
    }
    return items;
  }

  public void doOpenTrip() {
    final String[] items = getTripNames();

    if (items == null) {
      Toast.makeText(this, "There are no trips yet", Toast.LENGTH_LONG)
          .show();
      // this.doNewTrip();
      return;
    }
    Arrays.sort(items);
    ListAdapter adapter = new ArrayAdapter<String>(this,
        android.R.layout.select_dialog_item, android.R.id.text1, items) {
      public View getView(int position, View convertView, ViewGroup parent) {
        // User super class to create the View
        View v = super.getView(position, convertView, parent);
        TextView tv = (TextView) v.findViewById(android.R.id.text1);
        int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
        tv.setCompoundDrawablePadding(dp5);
        return v;
      }
    };
    new AlertDialog.Builder(this).setTitle(getString(R.string.pick_a_trip))
        .setAdapter(adapter, new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int item) {
            if (item > -1) {
              p("Got trip: " + items[item]);
              doOpenTrip(items[item]);
            }
          }
        }).show();
  }

  public void doOpenTrip(String tripname) {
    this.tripname = tripname;
    p("Loading trip " + tripname);
    trip = tripmanager.doOpenTrip(tripname);
    updateTitle();
    firstTimeDraw = true;
    edit = false;
    this.drawAll(trip, edit);
  }

  public void openPrefs() {
    Intent myIntent = new Intent(this, PrefActivity.class);
    this.startActivity(myIntent);
  }

  public void openDebug() {
    Intent myIntent = new Intent(this, DebugActivity.class);
    myIntent.putExtra("text", debug);
    this.startActivity(myIntent);
  }

  public void openControl() {
    Intent myIntent = new Intent(this, ControlWindow.class);
    this.startActivity(myIntent);
  }

  public void pickIcon() {

    ListAdapter adapter = new ArrayAdapter<IconItem>(this,
        android.R.layout.select_dialog_item, android.R.id.text1,
        TripManager.ICONITEMS) {
      public View getView(int position, View convertView, ViewGroup parent) {
        // User super class to create the View
        View v = super.getView(position, convertView, parent);
        TextView tv = (TextView) v.findViewById(android.R.id.text1);

        // Put the image on the TextView
        tv.setCompoundDrawablesWithIntrinsicBounds(
            TripManager.ICONITEMS[position].icon, 0, 0, 0);

        // Add margin between image and text (support various screen
        // densities)
        int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
        tv.setCompoundDrawablePadding(dp5);

        return v;
      }
    };
    new AlertDialog.Builder(this).setTitle(R.string.pick_an_icon)
        .setAdapter(adapter, new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int item) {
            if (item > -1) {
              currentPlacemark
                  .setCustomDrawable(TripManager.ICONITEMS[item].icon);
              p("Attaching icon "
                  + TripManager.ICONITEMS[item].text
                  + " to placemark");
              metamanager.attachMetadata(currentPlacemark
                  .getLocation(), new Icon(
                  TripManager.ICONITEMS[item].text));

              drawAll(trip, edit);
            }
          }
        }).show();
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    debug = ""; // debug text
    p("onCreate");

    prefs = PreferenceManager.getDefaultSharedPreferences(this);
    setContentView(R.layout.map);
    guiutils = new GuiUtils(this);
    dbtools = DbTools.getDbTools(this.getApplicationContext());
    dbtools.setDbListener((DbListener) MapViewActivity.this);
    // maybe we could use loadNewestTrip here?

    tripmanager = new TripManager(this);
    apptitle = (String) this.getTitle();
    updateTitle();
    PreferenceManager.setDefaultValues(this, R.xml.preferences, true);

    proFeaturesEnabled = ReleaseConfig
        .isPROLicenseInstalled(getApplicationContext());

    metamanager = MetadataManager.getMetadataManager(this
        .getApplicationContext());

    mapView = (MapView) findViewById(R.id.map_view);
    mapView.setBuiltInZoomControls(true);
    mapController = mapView.getController();
    // maybe save zoom level as pref, or remember last zoom level

    int zoom = Integer.parseInt(prefs.getString("zoom_level", "" + 13));
    mapController.setZoom(zoom);

    registerForContextMenu(mapView);

    Intent serviceIntent = new Intent(this, GPSService.class);
    bindService(serviceIntent, serviceConn, BIND_AUTO_CREATE);
    serviceTimer.scheduleAtFixedRate(new TimerTask() {
      @Override
      public void run() {
        t_checkStatusOfGps();
      }
    }, 0, 5 * 1000);

    startGpsService();

    mGestureDetector = new GestureDetector(
        new GestureDetector.SimpleOnGestureListener() {
          @Override
          public void onLongPress(MotionEvent e) {
            p("Long Press event, might open context menu if no placemark:"
                + currentPlacemark);
            // if (currentPlacemark == null)
            // MapViewActivity.this.openContextMenu(mapView);
          }

          public boolean onSingleTapConfirmed(MotionEvent e) {
            p("GestureDetector: Single Tap event, might open context menu if no placemark:"
                + currentPlacemark);
            Projection proj = mapView.getProjection();
            GeoPoint loc = proj.fromPixels((int) e.getX(),
                (int) e.getY());
            // p("GestureDetector: got geo point: " + loc);
            MapViewActivity.this.onTap(loc);
            return false;
          }

          @Override
          public boolean onDoubleTap(MotionEvent e) {

            p("Double Tap event, might open context menu if no placemark:"
                + currentPlacemark);
            if (currentPlacemark == null) {
              MapViewActivity.this.openContextMenu(mapView);
              return true;
            }
            return true;
          }

          @Override
          public boolean onDown(MotionEvent e) {
            return false;
          }
        });
    // mGestureDetector.s
    addEmptyOverlay();
    trip = (Trip) getLastNonConfigurationInstance();
    if (trip == null) {
      loadNewestTrip();
    } else {
      this.drawAll(trip, edit);
    }
  }

  /**
   * The implementation of onRetainNonConfigurationInstance will return an
   * instance of someExpensiveObject which we created earlier. This instance
   * will be available to the future instance of SomeActivity.
   */
  @Override
  public Object onRetainNonConfigurationInstance() {
    return trip;
  }

  private void updateTitle() {

    this.setTitle(apptitle + ": " + tripmanager.getCurrenTripName());
    p("Update title called: " + tripmanager.getCurrenTripName());
  }

  @Override
  public void onResume() {
    super.onResume();
    p("onResume called");
    if (tripname != null
        && !tripname.equalsIgnoreCase(tripmanager.getCurrenTripName())) {
      p("onResume called - calling loadNewestTrip because name has changed");
      loadNewestTrip();
    } else
      drawAll(trip, edit);

  }

  @Override
  public void onRestart() {
    super.onRestart();
    p("onRestart called - calling drawAll");
    drawAll(trip, edit);
  }

  private void addEmptyOverlay() {
    p("Adding emtpy overlay for getting on tap events");
    mapView.getOverlays().add(new Overlay() {
      @Override
      public boolean onTouchEvent(MotionEvent e, MapView mapView) {
        // p("GestureDetector: Got ontouch on empty overlay");
        if (mGestureDetector != null) {
          return mGestureDetector.onTouchEvent(e);
        }
        return super.onTouchEvent(e, mapView);

      }

      @Override
      public boolean onTap(GeoPoint p, MapView mapView) {
        // Handle tapping on the overlay here
        // p("Got ontap on empty overlay, sending to mapviewactivity ");
        MapViewActivity.this.onTap(p);
        return false;
      }

    });
  }

  public void profileView(View v) {
    Intent myIntent = new Intent(this, ProfileActivity.class);
    synchronized (trip) {
      myIntent.putExtra("trip", trip);
    }

    this.startActivity(myIntent);
  }

  public void openMyContextMenu() {
    openMyContextMenu(null);
  }

  public void openMyContextMenu(Placemark mark) {
    if (TAP_MOVE || TAP_INSERT_BEFORE || TAP_INSERT_AFTER || TAP_ADD)
      return;
    if (TAP_SPLIT > 0) {
      p("openContextMenu: We are in the process of splitting a trip");
      TAP_SPLIT = 0;
      if (mark instanceof RoutePoint) {
        final RoutePoint rp = (RoutePoint) mark;
        // ask for confirmation
        String msg = "Do you want to split the trip at this point?";
        msg += "\n" + guiutils.getMessage(rp.getLocation());
        // info about the location
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(msg)
            .setPositiveButton(getString(R.string.yes),
                new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog,
                      int item) {
                    splitTripAfterRPPicked(rp);
                  }
                })
            .setNegativeButton(getString(R.string.no), null).show();

      } else {
        p("No split event, because got no route point");
        Toast.makeText(this,
            R.string.i_found_no_route_point_to_split_the_trip,
            Toast.LENGTH_LONG).show();
      }
    } else {
      currentPlacemark = mark;
      if (mark != null) {
        p("Open context menu on item " + mark.getTitle());
      } else
        p("Open context menu, no marker");
      this.openContextMenu(mapView);
    }
  }

  private void splitTripAfterRPPicked(RoutePoint rp) {
    ArrayList<RoutePoint> after = trip.getLocationsAfter(rp);
    p("Got locs after: " + after);

    trip.deleteLocationsAfter(rp);
    // also delete from db
    // now create new trip with routeoints
    trip = tripmanager.createNewTrip(R.string.name_of_second_part_of_trip);
    edit = false;
    firstTimeDraw = true;
    for (RoutePoint p : after) {
      LocationUpdate up = p.getLocation();
      // move location update to new trip
      up.setTripname(trip.getName());
      trip.addRoutePoint(p);
      dbtools.updateLocation(up);
    }

    this.drawAll(trip, edit);
    Toast.makeText(this, "Trip was split", Toast.LENGTH_SHORT).show();
  }

  private void p(String msg) {
    Log.d(TAG, msg);
    if (debug == null)
      debug = "";
    if (debug.length() > 1000) {
      // delete start
      debug = debug.substring(1000);
    }
    debug += TAG + ":" + msg + "\n";
  }

  private void err(String msg) {
    Log.e(TAG, msg);
    if (debug.length() > 1000) {
      // delete start
      debug = debug.substring(1000);
    }
    debug += TAG + ": ERROR: " + msg + "\n";
  };

  /**
   * start the gps recorder thread
   */
  private void startRecording() {
    // start the gps receiver thread
    CommonGPSServiceFunctions.startRecording(gpsService, this);
    ((ImageButton) findViewById(R.id.btnRecord))
        .setImageResource(R.drawable.tracker_run);
  }

  /**
   * switch recorder state
   * 
   * @param v
   */
  public void btnRecorderClicked(View v) {
    if (gpsService != null) {
      if (gpsService.isRecording()) {
        stopRecording();
      } else {
        startRecording();
      }
    }
  }

  private void t_checkStatusOfGps() {

    if (gpsService == null) {
      startGpsService();
    }
    int old_gps_state = gps_current_state;
    int old_upload_state = upl_current_state;
    if (gpsService != null) {
      if (gpsService.isRecording()) {
        gps_current_state = STATUS_RUNNING;
      } else {
        gps_current_state = STATUS_STOPPED;
      }
      // uploader
      if (uploader.isUploading()) {
        upl_current_state = STATUS_RUNNING;
      } else {
        upl_current_state = STATUS_STOPPED;
      }

    } else {
      p("No gps service");
      gps_current_state = STATUS_UNKNOWN;
    }

    if (old_gps_state != gps_current_state
        || old_upload_state != upl_current_state) {
      handler.sendEmptyMessage(MESSAGE_STATUS);
    }

  }

  public void editPath(View v) {
    edit = !edit;
    drawAll(trip, edit);
  }

  public void addToPath(RoutePoint point) {

    if (trip == null) {
      p("No trip yet, not adding point");
      return;
    }
    if (mapView == null) {
      p("No map view yet - should not really happen...");
      return;
    }
    if (point == null) {
      p("No point - this should not happen :-)");
      return;
    }
    if (!trip.hasRoutePoints()) {
      trip.addRoutePoint(point);
      p("addToPath: no last point, drawing entire trip");
      drawAll(trip, edit);
      return;
    }

    mapView.getOverlays()
        .add(new RouteOverlay(trip.getLastPoint(), point,
            getMapColorMode()));
    trip.addRoutePoint(point);
    p("drawing route to :" + point.getGeoPoint());
    List<Overlay> mapOverlays = mapView.getOverlays();

    mapOverlays.add(new PlacemarkOverlay(point, MapViewActivity.this));

    if (prefs.getBoolean("move_to_latest_point", true))
      mapController.animateTo(point.getGeoPoint());
  }

  public int getMapColorMode() {
    String mode = prefs.getString("map_color_mode", "SAME");
    p("Got coloring mode: " + mode);
    if (mode.equalsIgnoreCase("SAME"))
      return RouteOverlay.COLOR_SAME;
    else if (mode.equalsIgnoreCase("SPEED"))
      return RouteOverlay.COLOR_SPEED;
    return RouteOverlay.COLOR_HEIGHT;
  }

  public void drawAll(Trip trip, boolean withRouteMarkers) {
    List<Overlay> mapOverlays = mapView.getOverlays();
    mapOverlays.clear();

    if (trip == null) {
      p("DrawAll: got no trip");
      return;
    }
    if (trip.getRoutePoints() == null) {
      p("DrawAll: got no route points");

    } else {
      p("Drawing entire route");

      RoutePoint prev = null;
      boolean moved = false;

      // add ONE route overlay

      if (trip.getRoutePoints() != null) {
        int nr = trip.getRoutePoints().size();
        for (int i = 0; i < nr; i++) {
          RoutePoint point = trip.getRoutePoints().get(i);
          mapOverlays.add(new RouteOverlay(prev, point,
              getMapColorMode()));
          prev = point;
          if (withRouteMarkers || point.hasBitmap()
              || point.hasCustomDrawable() || (i + 1) == nr) {
            mapOverlays.add(new PlacemarkOverlay(point,
                MapViewActivity.this));
          }
        }
      }
      if (prev != null) {
        if (prefs.getBoolean("move_to_latest_point", true)
            || firstTimeDraw) {
          mapController.animateTo(prev.getGeoPoint());
        }
      }

      if (trip.getPlacemarks() != null) {
        for (Placemark mark : trip.getPlacemarks()) {
          mapOverlays.add(new PlacemarkOverlay(mark,
              MapViewActivity.this));
          if (!moved) {
            if (prefs.getBoolean("move_to_latest_point", true)
                || firstTimeDraw) {
              mapController.animateTo(mark.getGeoPoint());
            }
            moved = true;
          }
        }
      }
      firstTimeDraw = false;
    }
    this.addEmptyOverlay();

  }

  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenu.ContextMenuInfo menuInfo) {
    // Show different menu items, depending on what is
    // selected.
    // p("Context menu created, view=" + v + ",  curitem=" +
    // currentPlacemark);
    if (v.getId() == R.id.map_view) {
      if (currentPlacemark != null) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.map_context_menu_route, menu);
      } else {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.map_context_menu_nothing, menu);
      }
    }
  }

  public boolean onContextItemSelected(MenuItem item) {

    // p("Last item " + item.getTitle());
    switch (item.getItemId()) {
    case R.id.menu_add_image:
      if (checkPro())
        this.addImageToLocation();
      break;
    case R.id.menu_show_marker_info:
      guiutils.showInfo(currentPlacemark);
      break;
    case R.id.menu_show_image:
      if (checkPro())
        guiutils.showFoto(currentPlacemark, false);
      break;
    case R.id.menu_note:
      if (checkPro())
        this.addNoteToLocation();
      break;
    case R.id.menu_rename_marker:
      if (checkPro())
        this.renameMarker();
      break;
    case R.id.menu_icon:
      if (checkPro())
        this.pickIcon();
      break;
    case R.id.menu_insert_before:
      if (checkPro())
        this.insertMarker(true);
      break;
    case R.id.menu_move:
      if (checkPro())
        this.doMovePlacemark();
      break;

    case R.id.menu_delete:
      this.deleteLocation();
      break;

    default:
      this.onMenuItemSelected(0, item);
      break;
    }
    return true;
  }

  private void insertMarker(boolean before) {
    if (currentPlacemark == null) {
      Toast.makeText(
          this,
          getApplicationContext().getString(
              messages[MESSAGE_NOPLACEMARK]), Toast.LENGTH_SHORT)
          .show();
      return;
    }
    if (before)
      TAP_INSERT_BEFORE = true;
    else
      TAP_INSERT_AFTER = true;
    handler.sendEmptyMessage(MESSAGE_INSERT);

  }

  private void deleteLocation() {
    if (currentPlacemark == null) {
      Toast.makeText(
          this,
          getApplicationContext().getString(
              messages[MESSAGE_NOPLACEMARK]), Toast.LENGTH_SHORT)
          .show();
      return;
    }
    if (trip == null) {
      Toast.makeText(this, "There seems to be no trip - bug? :-)",
          Toast.LENGTH_SHORT).show();
      return;
    }
    if (currentPlacemark instanceof RoutePoint) {
      trip.getRoutePoints().remove(currentPlacemark);
    } else {
      if (trip.getPlacemarks() == null) {
        Toast.makeText(this, "Ther are no place marks - bug? :-)",
            Toast.LENGTH_SHORT).show();
        return;
      }
      trip.getPlacemarks().remove(currentPlacemark);
    }
    dbtools.markDeleted(currentPlacemark.getLocation());

    drawAll(trip, edit);
  }

  private void addImageToLocation() {
    if (currentPlacemark == null) {
      Toast.makeText(
          this,
          getApplicationContext().getString(
              messages[MESSAGE_NOPLACEMARK]), Toast.LENGTH_SHORT)
          .show();
      return;
    }
    addImageToLocation(currentPlacemark);

  }

  DialogInterface.OnClickListener cameraOrStoredListener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
      switch (which) {
      case DialogInterface.BUTTON_POSITIVE:

        Intent cameraIntent = new Intent(
            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        File photo = new File(
            Environment.getExternalStorageDirectory(),
            "egotrip.jpg");
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.fromFile(photo));

        startActivityForResult(cameraIntent, CAMERA_REQUEST);
        break;

      case DialogInterface.BUTTON_NEGATIVE:
        startActivityForResult(
            new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI),
            SELECT_IMAGE_REQUEST);
        break;
      }
    }
  };

  public void addImageToLocation(Placemark place) {
    // ask for image or camera
    if (place == null) {
      Toast.makeText(
          this,
          getApplicationContext().getString(
              messages[MESSAGE_NOPLACEMARK]), Toast.LENGTH_SHORT)
          .show();
      return;
    }
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(
        R.string.would_you_like_to_attach_an_image_from_the_camera_or_a_stored_image_)
        .setPositiveButton(R.string.camera, cameraOrStoredListener)
        .setNegativeButton(R.string.pick_image, cameraOrStoredListener)
        .show();

  }

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Bitmap bitmap = null;
    Uri imageUri = null;
    String realpath=null;
    p("Activity " + requestCode + " completed, result code is: "
        + resultCode);
    // Cam uri (hardcoded above)
    if (requestCode == CAMERA_REQUEST) {
      File f = new File(Environment.getExternalStorageDirectory(),
          "egotrip.jpg");
      realpath=f.getAbsolutePath();
      imageUri = Uri.fromFile(f);
      
      /*
      // we must add the image to a gallery first
      Intent mediaScanIntent = new Intent(
          Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
      Uri contentUri = Uri.fromFile(f);
      mediaScanIntent.setData(contentUri);
      this.sendBroadcast(mediaScanIntent);*/
    } else if (requestCode == SELECT_IMAGE_REQUEST) {
      imageUri = data.getData();
      realpath=getRealPathFromURI(imageUri);
    }
    p("IMAGEURI: " + imageUri);

    try {
      bitmap = android.provider.MediaStore.Images.Media.getBitmap(
          getContentResolver(), imageUri);
      Toast.makeText(this, "GOT IMAGE:" + imageUri, Toast.LENGTH_SHORT)
          .show();
    } catch (FileNotFoundException e) {
      Toast.makeText(this,
          R.string.could_not_load_image_ + "" + imageUri,
          Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
      Toast.makeText(this,
          R.string.problem_reading_image_ + "" + imageUri,
          Toast.LENGTH_SHORT).show();
    }

    if (bitmap != null) {
      if (currentPlacemark == null) {
        p("No current placemark");
      } else {
        //make a compressed copy
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, baos);
        bitmap = null;
        System.gc();
        Bitmap smaller = BitmapFactory.decodeStream(new ByteArrayInputStream(baos.toByteArray()));
        this.currentPlacemark.setBitMap(smaller);
        
        
        if (imageUri != null) {
          metamanager.attachMetadata(currentPlacemark.getLocation(),
              new Image(realpath));
          p("Attached image " + imageUri);
          Toast.makeText(
              this,
              R.string.attached_image_to_
                  + currentPlacemark.getTitle(),
              Toast.LENGTH_SHORT).show();
          drawAll(trip, edit);
        } else {
          p(getString(R.string.could_not_get_uri_for_image));
          Toast.makeText(this, R.string.could_not_get_uri_for_image,
              Toast.LENGTH_LONG);
        }
      }
    } else
      Toast.makeText(this, R.string.got_no_image_for_some_reason,
          Toast.LENGTH_SHORT).show();
  }

  public String getRealPathFromURI(Uri contentUri) {
    String[] proj = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(contentUri, proj, null, null, null);
    int column_index = cursor
        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
  }

  private void addNoteToLocation() {
    if (currentPlacemark == null) {
      Toast.makeText(
          this,
          getApplicationContext().getString(
              messages[MESSAGE_NOPLACEMARK]), Toast.LENGTH_SHORT)
          .show();
      return;
    }
    AlertDialog.Builder alert = new AlertDialog.Builder(this);
    alert.setTitle(getApplicationContext().getString(R.string.note));
    alert.setMessage(getApplicationContext().getString(
        R.string.add_a_note_to_location_)
        + currentPlacemark.getTitle());

    // Set an EditText view to get user input
    final EditText input = new EditText(this);
    alert.setView(input);

    alert.setPositiveButton(R.string.ok,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
            String value = input.getText().toString();
            currentPlacemark.setDescription(value);
            metamanager.attachMetadata(
                currentPlacemark.getLocation(), new Text(value));
            // maybe change icon to show it has a note?
          }
        });
    alert.setNegativeButton(R.string.cancel, null);
    alert.show();

  }

  private void renameMarker() {
    if (currentPlacemark == null) {
      Toast.makeText(
          this,
          getApplicationContext().getString(
              messages[MESSAGE_NOPLACEMARK]), Toast.LENGTH_SHORT)
          .show();
      return;
    }
    AlertDialog.Builder alert = new AlertDialog.Builder(this);
    alert.setTitle(R.string.name);
    alert.setMessage("Name the marker " + currentPlacemark.getTitle());

    // Set an EditText view to get user input
    final EditText input = new EditText(this);
    alert.setView(input);

    alert.setPositiveButton(R.string.ok,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
            String value = input.getText().toString();
            currentPlacemark.setTitle(value);
            // maybe change icon to show it has a note?
          }
        });
    alert.setNegativeButton(R.string.cancel, null);
    alert.show();

  }

  private void addLocation(LocationUpdate loc) {
    p("addLocation: " + loc);
    if (loc == null)
      return;

    if (!loc.isStandalone()) {
      int min = Integer.parseInt(prefs.getString("minimum_accuracy",
          "" + 500));
      if (loc.getAccuracy() > min) {
        loc.setHidden(true);
        dbtools.updateLocation(loc);
        p("Hiding loc with acc " + loc.getAccuracy());
      } else {
        RoutePoint point = new RoutePoint(loc, R.drawable.mm_20_red);
        // addToPath(point);
        Message msg = new Message();
        msg.what = MESSAGE_ADDTOPATH;
        msg.obj = point;
        // IMPORTANT: need to use handler or else we will get a
        // concurrent
        // modification error!
        handler.sendMessage(msg);
      }
    }
  }

  @Override
  protected boolean isRouteDisplayed() {
    return true;
  }

  private void startGpsService() {
    Intent serviceIntent = new Intent(this, GPSService.class);
    ComponentName name = startService(serviceIntent);
    p("startGpsService: " + name);
  }

  public void refreshGPSInfos() {
    ImageButton btnGPSPowerButton = (ImageButton) findViewById(R.id.btnRecord);

    p("Gps status: " + gps_current_state);
    switch (gps_current_state) {
    case STATUS_UNKNOWN:
      p("GPS unknown");
      btnGPSPowerButton.setImageResource(R.drawable.tracker_q);
      break;

    case STATUS_RUNNING:
      p("GPS is running");
      btnGPSPowerButton.setImageResource(R.drawable.tracker_run);
      break;

    case STATUS_STOPPED:
      p("GPS is stopped");
      btnGPSPowerButton.setImageResource(R.drawable.tracker_stop);
      break;

    default:
      btnGPSPowerButton.setImageResource(R.drawable.tracker_q);
      break;
    }
  }

  private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
      if (msg.what == MESSAGE_ADDTOPATH) {
        RoutePoint point = (RoutePoint) msg.obj;
        addToPath(point);
      } else if (msg.what == MESSAGE_STATUS) {
        refreshDisplay();
      } else if (msg.what == ACTION_ADD) {
        p("Adding standalone placemark to db and map");
        GeoPoint p = (GeoPoint) msg.obj;
        Placemark mark = new Placemark(p.getLatitudeE6(),
            p.getLongitudeE6(), "Placemark", null,
            R.drawable.orange_dot);
        trip.addPlacemark(mark);
        LocationUpdate up = mark.getLocation();
        up.setStandalone(true);
        up.setTripname(trip.getName());
        // mark.getLocation().
        dbtools.insertLocation(up);
        List<Overlay> mapOverlays = mapView.getOverlays();
        mapOverlays
            .add(new PlacemarkOverlay(mark, MapViewActivity.this));
        Toast.makeText(MapViewActivity.this,
            R.string.added_new_placemark, Toast.LENGTH_SHORT)
            .show();

        p("Added placemark: " + up.toString());
        // p("Added placemark: standalone? "+up.isStandalone()+
        // " deleted? "+up.isDeleted());
        // drawAll(trip, edit);
      } else if (msg.what == ACTION_MOVE) {
        GeoPoint p = (GeoPoint) msg.obj;
        if (currentPlacemark == null) {
          Toast.makeText(MapViewActivity.this,
              R.string.i_see_no_current_placemark_won_t_move_it,
              Toast.LENGTH_SHORT).show();
          return;
        } else {
          LocationUpdate loc = currentPlacemark.getLocation();
          loc.setLat((double) p.getLatitudeE6() / (double) 1E6);
          loc.setLng((double) p.getLongitudeE6() / (double) 1E6);
          dbtools.updateLocation(loc);
          Toast.makeText(
              MapViewActivity.this,
              R.string.location_of_ + currentPlacemark.getTitle()
                  + R.string._changed, Toast.LENGTH_SHORT)
              .show();
          p("Moving item");
          drawAll(trip, edit);
        }
      } else if (msg.what == ACTION_INSERT) {
        GeoPoint p = (GeoPoint) msg.obj;
        LocationUpdate loc = currentPlacemark.getLocation();

        LocationUpdate newloc = new LocationUpdate(loc);

        // if (TAP_INSERT_BEFORE) {
        //
        // if (newloc.getTsorder()>0) {
        // // first get all trips with same timestamp and lower tsorder
        // }
        // newloc.setTimestamp(loc.getTimestamp() - 1);
        // }
        // else {
        // newloc.setTimestamp(loc.getTimestamp() ;
        // // use tsorder? but we need to first find all trips with this
        // timestamp
        //
        // }

        p("TODO: check order, and also sort by timestamp tsorder");
        loc.setLat((double) p.getLatitudeE6() / (double) 1E6);
        loc.setLng((double) p.getLongitudeE6() / (double) 1E6);
        dbtools.insertLocation(newloc);
        RoutePoint add = new RoutePoint(newloc, R.drawable.mm_20_blue);
        trip.addRoutePoint(add);
        drawAll(trip, edit);
      } else {
        if (msg.what == MESSAGE_SPLIT) {
          if (!edit)
            editPath(null);
        }
        String text = getApplicationContext().getString(
            messages[msg.what]);
        Toast.makeText(MapViewActivity.this, text, Toast.LENGTH_SHORT)
            .show();
      }
    };
  };

  public void refreshDisplay() {
    refreshGPSInfos();
    refreshUploaderInfos();

  }

  public void refreshUploaderInfos() {
    ImageButton btnUploaderPowerButton = (ImageButton) findViewById(R.id.btnUpload);

    switch (upl_current_state) {
    case STATUS_UNKNOWN:
      btnUploaderPowerButton.setImageResource(R.drawable.signal_q);
      break;

    case STATUS_RUNNING:
      btnUploaderPowerButton.setImageResource(R.drawable.signal_run);
      break;

    case STATUS_STOPPED:
      btnUploaderPowerButton.setImageResource(R.drawable.signal_stop);
      break;

    default:
      btnUploaderPowerButton.setImageResource(R.drawable.signal_q);
      break;
    }

  }

  public void btnControlView(View v) {
    this.openControl();
  }

  public void btnUploaderClicked(View v) {
    if (gpsService != null) {
      if (uploader.isUploading()) {
        stopUploading();
      } else {
        startUploading();
      }
    }
  }

  /**
   * start the uploader
   */
  private void startUploading() {
    // start the gps receiver thread
    gpsService.startUploading();
    ((ImageButton) findViewById(R.id.btnUpload))
        .setImageResource(R.drawable.signal_q);
  }

  /** stop the uploader */
  private void stopUploading() {
    gpsService.stopUploading();
    ((ImageButton) findViewById(R.id.btnUpload))
        .setImageResource(R.drawable.signal_q);

  }

  /** stop the gps recorderthread */
  private void stopRecording() {
    CommonGPSServiceFunctions.stopRecording(gpsService);
    p("Stop recording");
    ((ImageButton) findViewById(R.id.btnRecord))
        .setImageResource(R.drawable.tracker_stop);
    // TextView tvRunning = (TextView) findViewById(R.id.txt_gpsrunning);
    // tvRunning.setText("stopping");
  }

  private void stopGpsService() {
    Intent serviceIntent = new Intent(this, GPSService.class);
    stopService(serviceIntent);
    // p("stopGpsService ");
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    unbindService(serviceConn);
    serviceTimer.cancel();
  }

  public void addDebug(String msg) {
    debug += msg + "\n";

  }

  @Override
  /** from interface DbListener */
  public void locationAdded(LocationUpdate loc) {
    if (loc != null) {
      p("Got location from db: " + loc);
      this.addLocation(loc);
    }

  }

}




Java Source Code List

net.myegotrip.egotrip.CommonGPSServiceFunctions.java
net.myegotrip.egotrip.ControlHandler.java
net.myegotrip.egotrip.ControlWindow.java
net.myegotrip.egotrip.DbListener.java
net.myegotrip.egotrip.DbTools.java
net.myegotrip.egotrip.DownloadProgressHandler.java
net.myegotrip.egotrip.FallbackDefaults.java
net.myegotrip.egotrip.GPSService.java
net.myegotrip.egotrip.Installation.java
net.myegotrip.egotrip.LocationUpdate.java
net.myegotrip.egotrip.MapViewActivity.java
net.myegotrip.egotrip.PrefActivity.java
net.myegotrip.egotrip.ReleaseConfig.java
net.myegotrip.egotrip.StartupActivity.java
net.myegotrip.egotrip.TaskDoneListener.java
net.myegotrip.egotrip.Tools.java
net.myegotrip.egotrip.TripManager.java
net.myegotrip.egotrip.help.HelpActivity.java
net.myegotrip.egotrip.help.TopicActivity.java
net.myegotrip.egotrip.image.ImageHandler.java
net.myegotrip.egotrip.map.MockLocationProvider.java
net.myegotrip.egotrip.map.PlacemarkOverlay.java
net.myegotrip.egotrip.map.Placemark.java
net.myegotrip.egotrip.map.RouteOverlay.java
net.myegotrip.egotrip.map.RoutePoint.java
net.myegotrip.egotrip.map.Trip.java
net.myegotrip.egotrip.metadata.EgotripMetadata.java
net.myegotrip.egotrip.metadata.GenericMetadata.java
net.myegotrip.egotrip.metadata.Icon.java
net.myegotrip.egotrip.metadata.Image.java
net.myegotrip.egotrip.metadata.MetadataManager.java
net.myegotrip.egotrip.metadata.Text.java
net.myegotrip.egotrip.net.BetaUpdateManager.java
net.myegotrip.egotrip.net.ProtocolConstants.java
net.myegotrip.egotrip.net.ServerReply.java
net.myegotrip.egotrip.net.Uploader.java
net.myegotrip.egotrip.profile.ProfileActivity.java
net.myegotrip.egotrip.profile.ProfilePrefActivity.java
net.myegotrip.egotrip.profile.ProfileView.java
net.myegotrip.egotrip.utils.DebugActivity.java
net.myegotrip.egotrip.utils.Debug.java
net.myegotrip.egotrip.utils.GuiUtils.java
net.myegotrip.egotrip.utils.IconItem.java
net.myegotrip.egotrip.utils.TwoDScrollView.java
net.myegotrip.egotrip.utils.XYScaleGestureDetector.java