Commits

littledot5566 committed 883a38a

Implemented Expedition class.

  • Participants
  • Parent commits 057735c

Comments (0)

Files changed (29)

+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Eclipse project files
+.classpath
+.project

AndroidManifest.xml

         </activity>
         <!--  -->
         <activity
-            android:name=".HuntingMapActivity"
+            android:name=".ExpeditionCompleteActivity"
             android:configChanges="keyboardHidden|orientation"
             android:screenOrientation="portrait" >
         </activity>
         <activity android:name=".MainActivity" >
         </activity>
         <!--  -->
-        <activity android:name=".SelectDistanceActivity" >
+        <activity android:name=".components.SelectDistanceActivity" >
+        </activity>
+        <!--  -->
+        <activity android:name=".components.ProfileActivity" >
+        </activity>
+        <!--  -->
+        <activity android:name=".components.TestBundleActivity" >
         </activity>
     </application>
 
+> sqlite select query where values must follow "=" with no spaces.
+X: select * from profile where pID = 1;
+O: select * from profile where pID=1;
+
+> Android SQLiteDatabase.rawQuery() cannot substitue table names and column names with "?".
+X: db.rawQuery("select * from ? where ?=?", new String[]{"profile", "pID", "1"});
+O: db.rawQuery(String.format("select * from %s where %s=%d", "profile", "pID", 1));

res/layout/bundletest_act_layout.xml

+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/bundle_tv_debug"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" />
+
+</LinearLayout>

res/layout/main_act_layout.xml

         android:layout_height="wrap_content" />
 
     <Button
-        android:id="@+id/main_but_startHunt"
+        android:id="@+id/main_but_startExpedition"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:onClick="onStartNewHunt"
+        android:onClick="onClick"
         android:text="@string/main_but_startHunt" />
 
+    <Button
+        android:id="@+id/main_but_profile"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:onClick="onClick"
+        android:text="View my profile" />
+
 </LinearLayout>

res/layout/map_act_layout.xml

         android:layout_width="fill_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
-        android:apiKey="0-0tVBYzo78GcruEETjNXCnXjt4rzTKIkzU5HAQ"
+        android:apiKey="0-0tVBYzo78FEXFOBhiBi06dI13u00gCOfQnEUA"
         android:clickable="true" />
+    <!-- Ubuntu:		0-0tVBYzo78GcruEETjNXCnXjt4rzTKIkzU5HAQ -->
+    <!-- Win7:			0-0-0tVBYzo78FEXFOBhiBi06dI13u00gCOfQnEUA -->
+    <!-- android-dev:	0-0tVBYzo78F-qe7esdacwXkvQC1qjv3vYvBkbA -->
 
     <LinearLayout
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal" >
 
+        <TextView
+            android:id="@+id/map_tv_info"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:visibility="gone" />
+
         <Button
-            android:id="@+id/map_but_dig"
+            android:id="@+id/map_but_debug"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:onClick="onClick"
-            android:text="Start Digging!" />
+            android:text="debug bundle" />
     </LinearLayout>
 
 </LinearLayout>

res/layout/profile_activity.xml

+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/profile_tv_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/profile_tv_totalExpedition"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/profile_tv_totalDistance"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/profile_tv_totalTime"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <GridView
+        android:id="@+id/profile_gv_treasure"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>

src/nctuw/littledot/localtreasure/DataManager.java

-package nctuw.littledot.localtreasure;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-
-public class DataManager {
-	public static final String				DBTABLE_STATS				= "statistics";
-	public static final String				KEY_STATS_ID				= "sID";
-	public static final String				KEY_STATS_DIST_TRAV	= "sDistanceTraveled";
-	public static final String				KEY_STATS_EXP_TOTAL	= "sTotalExpeditionsLaunched";
-	public static final String				KEY_STATS_EXP_SUCC	= "sSuccessfulExpeditions";
-	public static final String				KEY_STATS_EXP_FAIL	= "sFailedExpeditions";
-
-	private Context										mCtx;
-	private SharedPreferences					mPrefs;
-	private SharedPreferences.Editor	mEditor;
-
-	public DataManager(Context ctx) {
-		mCtx = ctx;
-
-		mPrefs = mCtx.getSharedPreferences("nctuw.littledot.localtreasure",
-				Context.MODE_PRIVATE);
-
-		SharedPreferences.Editor editor = mPrefs.edit();
-		// editor.putLong(Constants.PREF_LAST_AD_CLICK, cal.getTimeInMillis());
-		// editor.commit();
-
-	}
-
-	public float getDistanceTraveled() {
-		return mPrefs.getFloat(KEY_STATS_DIST_TRAV, 0);
-	}
-
-	public void incDistanceTraveled(float inc) {
-		float value = getDistanceTraveled() + inc;
-		mEditor.putFloat(KEY_STATS_DIST_TRAV, value);
-		mEditor.commit();
-	}
-
-	public int getTotalExpeditions() {
-		return mPrefs.getInt(KEY_STATS_EXP_TOTAL, 0);
-	}
-
-	public void incTotalExpeditions(int inc) {
-		int value = getTotalExpeditions() + inc;
-		mEditor.putInt(KEY_STATS_EXP_TOTAL, value);
-		mEditor.commit();
-	}
-
-	public int getSuccessExpeditions() {
-		return mPrefs.getInt(KEY_STATS_EXP_SUCC, 0);
-	}
-
-	public void incSuccessExpeditions(int inc) {
-		int value = getSuccessExpeditions() + inc;
-		mEditor.putInt(KEY_STATS_EXP_SUCC, value);
-		mEditor.commit();
-	}
-
-	public int getFailedExpeditions() {
-		return mPrefs.getInt(KEY_STATS_EXP_FAIL, 0);
-	}
-
-	public void incFailedExpeditions(int inc) {
-		int value = getFailedExpeditions();
-		mEditor.putInt(KEY_STATS_EXP_FAIL, value);
-		mEditor.commit();
-	}
-}

src/nctuw/littledot/localtreasure/Database.java

-package nctuw.littledot.localtreasure;
-
-import nctuw.littledot.util.Leg;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-public class Database {
-	private static final int		DB_VERSION										= 1;
-	public static final String	DBNAME												= "nctuw.littledot.localtreasure";
-
-	public static final String	DBTABLE_TREASURE							= "treasure";
-	public static final String	KEY_TREASURE_ID								= "tID";
-	public static final String	KEY_TREASURE_NAME							= "tName";
-	public static final String	KEY_TREASURE_NUM							= "tDays";
-
-	public static final String	DBTABLE_PROFILE								= "profile";
-	public static final String	KEY_PROFILE_ID								= "pID";
-	public static final String	KEY_PROFILE_EXPEDITIONS				= "pExpeditions";
-	public static final String	KEY_PROFILE_DISTANCE_TRAVELED	= "pDistanceTraveled";
-
-	private static final String	SQL_CREATE_TREASURE						= "create table if not exists "
-																																+ DBTABLE_TREASURE
-																																+ "("
-																																+ KEY_TREASURE_ID
-																																+ " integer not null primary key,"
-																																+ KEY_TREASURE_NAME
-																																+ " text default '',"
-																																+ KEY_TREASURE_NUM
-																																+ " integer not null default 0"
-																																+ ");";
-
-	private static final String	SQL_CREATE_PROFILE						= "create table if not exists "
-																																+ DBTABLE_PROFILE
-																																+ "("
-																																+ KEY_PROFILE_ID
-																																+ " integer not null primary key autoincrement,"
-																																+ KEY_PROFILE_EXPEDITIONS
-																																+ " integer not null default 0,"
-																																+ KEY_PROFILE_DISTANCE_TRAVELED
-																																+ " real not null default 0"
-																																+ ");";
-
-	private final Context				mContext;
-
-	private DatabaseHelper			DBHelper;
-	private SQLiteDatabase			db;
-
-	public Database(Context ctx) {
-		this.mContext = ctx;
-		DBHelper = new DatabaseHelper(mContext);
-
-	}
-
-	private class DatabaseHelper extends SQLiteOpenHelper {
-		DatabaseHelper(Context context) {
-			super(context, DBNAME, null, DB_VERSION);
-		}
-
-		@Override
-		public void onCreate(SQLiteDatabase db) {
-			db.execSQL(SQL_CREATE_TREASURE);
-			db.execSQL(SQL_CREATE_PROFILE);
-		}
-
-		@Override
-		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-			db.execSQL("drop table if exists " + DBTABLE_TREASURE + ";");
-			db.execSQL("drop table if exists " + DBTABLE_PROFILE + ";");
-			onCreate(db);
-		}
-	}
-
-	public void open() {
-		db = DBHelper.getWritableDatabase();
-	}
-
-	public void close() {
-		if (db.isOpen())
-			db.close();
-	}
-
-	public int getVersion() {
-		return db.getVersion();
-	}
-
-	public void showAllData(String table) {
-		Cursor cur = db.query(table, null, null, null, null, null, null);
-		if (cur != null)
-			cur.moveToFirst();
-
-		while (!cur.isAfterLast()) {
-			String log = "";
-			for (int i = 4; i < 9; i++) {
-				log += "[" + i + "]=";
-				log += cur.getInt(i);
-			}
-			Leg.i(log);
-			cur.moveToNext();
-		}
-	}
-
-	/*************/
-	/** Queries **/
-	/*************/
-
-	public Cursor rawQuery(String sql) {
-		return rawQuery(sql, null);
-	}
-
-	public Cursor rawQuery(String sql, String[] args) {
-		Cursor cur = db.rawQuery(sql, args);
-
-		cur.moveToFirst();
-		return cur;
-	}
-
-	public int queryTreasureNum(Treasure treasure) {
-		Cursor cur = rawQuery(
-				"select * from ? where ? = ? ",
-				new String[] { DBTABLE_TREASURE, KEY_TREASURE_ID,
-						Integer.toString(treasure.getDrawableId()) });
-
-		if (cur.moveToFirst())
-			return cur.getInt(cur.getColumnIndexOrThrow(KEY_TREASURE_NUM));
-		else
-			return -1;
-	}
-
-	public int queryExpeditionNum(int profileID) {
-		Cursor cur = rawQuery("select * from ? where ? = ? ", new String[] {
-				DBTABLE_PROFILE, KEY_PROFILE_ID, Integer.toString(profileID) });
-
-		if (cur.moveToFirst())
-			return cur.getInt(cur.getColumnIndexOrThrow(KEY_PROFILE_EXPEDITIONS));
-		else
-			return -1;
-	}
-
-	public double queryDistanceTraveled(int profileID) {
-		Cursor cur = rawQuery("select * from ? where ? = ? ", new String[] {
-				DBTABLE_PROFILE, KEY_PROFILE_ID, Integer.toString(profileID) });
-
-		if (cur.moveToFirst())
-			return cur.getDouble(cur
-					.getColumnIndexOrThrow(KEY_PROFILE_DISTANCE_TRAVELED));
-		else
-			return -1;
-	}
-
-	/*************/
-	/** Inserts **/
-	/*************/
-
-	public long insert(String table, String[] keys, Object[] values) {
-		if (keys.length != values.length)
-			throw new IllegalArgumentException(
-					"keys-values must be of the same length");
-
-		ContentValues kvPair = new ContentValues();
-
-		for (int i = 0; i < keys.length; i++) {
-			if (values[i] instanceof String)
-				kvPair.put(keys[i], (String) values[i]);
-			else if (values[i] instanceof Integer)
-				kvPair.put(keys[i], (Integer) values[i]);
-			else if (values[i] instanceof Double)
-				kvPair.put(keys[i], (Double) values[i]);
-			else if (values[i] instanceof Float)
-				kvPair.put(keys[i], (Float) values[i]);
-			else if (values[i] instanceof Long)
-				kvPair.put(keys[i], (Long) values[i]);
-			else if (values[i] instanceof Short)
-				kvPair.put(keys[i], (Short) values[i]);
-			else if (values[i] instanceof Boolean)
-				kvPair.put(keys[i], (Boolean) values[i]);
-			else if (values[i] instanceof Byte)
-				kvPair.put(keys[i], (Byte) values[i]);
-			else if (values[i] instanceof byte[])
-				kvPair.put(keys[i], (byte[]) values[i]);
-			else
-				throw new IllegalArgumentException("Type "
-						+ values[i].getClass().getName() + " is not supported.");
-		}
-
-		long result = db.insert(table, null, kvPair);
-
-		return result;
-	}
-
-	// public long insertEvent(Event event) {
-	// ContentValues kvPair = new ContentValues();
-	//
-	// db = DBHelper.getWritableDatabase();
-	// long result = db.insert(DBTABLE_EVENT, null, kvPair);
-	// db.close();
-	// Leg.i("insertEvent=" + result);
-	//
-	// // set the alarm TODO:move this elsewhere
-	// if (event.getRingTime() > 0) {
-	// event.setEvtId((int) result);
-	// AlarmHandler ah = new AlarmHandler(mContext);
-	// ah.setWeeklyAlarm(event);
-	// }
-	//
-	// return result;
-	// }
-
-	/*************/
-	/** Updates **/
-	/*************/
-
-	public boolean update(String table, String[] keys, Object[] values,
-			String whereClause) {
-		if (keys.length != values.length)
-			throw new IllegalArgumentException(
-					"keys-values must be of the same length");
-
-		ContentValues kvPair = new ContentValues();
-		for (int i = 0; i < keys.length; i++) {
-			if (values[i] instanceof String)
-				kvPair.put(keys[i], (String) values[i]);
-			else if (values[i] instanceof Integer)
-				kvPair.put(keys[i], (Integer) values[i]);
-			else if (values[i] instanceof Double)
-				kvPair.put(keys[i], (Double) values[i]);
-			else if (values[i] instanceof Float)
-				kvPair.put(keys[i], (Float) values[i]);
-			else if (values[i] instanceof Long)
-				kvPair.put(keys[i], (Long) values[i]);
-			else if (values[i] instanceof Short)
-				kvPair.put(keys[i], (Short) values[i]);
-			else if (values[i] instanceof Boolean)
-				kvPair.put(keys[i], (Boolean) values[i]);
-			else if (values[i] instanceof Byte)
-				kvPair.put(keys[i], (Byte) values[i]);
-			else if (values[i] instanceof byte[])
-				kvPair.put(keys[i], (byte[]) values[i]);
-			else
-				throw new IllegalArgumentException("Type "
-						+ values[i].getClass().getName() + " is not supported.");
-		}
-
-		boolean result = db.update(table, kvPair, whereClause, null) > 0;
-
-		return result;
-	}
-
-	public boolean update(String table, String key, Object value,
-			String whereClause) {
-		return update(table, new String[] { key }, new Object[] { value },
-				whereClause);
-	}
-
-	/**
-	 * Increment the number of accumulated treasure by the specified amount.
-	 * 
-	 * @param treasure
-	 * @param increment
-	 * @return
-	 */
-	public void incrementTreasure(Treasure treasure, int increment) {
-		int ret = queryTreasureNum(treasure);
-
-		if (ret == -1) {
-			// do an insert if key does not exist yet
-			insert(DBTABLE_TREASURE, new String[] { KEY_TREASURE_NAME,
-					KEY_TREASURE_NUM }, new Object[] { treasure, increment });
-		} else {
-			// do an update if key exists
-			int newNum = ret + increment;
-
-			update(DBTABLE_TREASURE, KEY_TREASURE_NUM, newNum, KEY_TREASURE_NAME
-					+ " = " + treasure);
-		}
-	}
-
-	public void incrementExpeditions(int profileID, int increment) {
-		int ret = queryExpeditionNum(profileID);
-
-		if (ret == -1) {
-			insert(DBTABLE_PROFILE, new String[] { KEY_PROFILE_EXPEDITIONS,
-					KEY_PROFILE_DISTANCE_TRAVELED }, new Object[] { 0, 0 });
-		} else {
-			int newNum = ret + increment;
-
-			update(DBTABLE_PROFILE, KEY_PROFILE_EXPEDITIONS, newNum, KEY_PROFILE_ID
-					+ "=" + profileID);
-		}
-	}
-
-	public void incrementDistance(int profileID, double amount) {
-		double ret = queryDistanceTraveled(profileID);
-
-		if (ret == -1) {
-			insert(DBTABLE_PROFILE, new String[] { KEY_PROFILE_EXPEDITIONS,
-					KEY_PROFILE_DISTANCE_TRAVELED }, new Object[] { 0, 0 });
-		} else {
-			double newNum = ret + amount;
-
-			update(DBTABLE_PROFILE, KEY_PROFILE_DISTANCE_TRAVELED, newNum,
-					KEY_PROFILE_ID + "=" + profileID);
-		}
-	}
-
-	/*************/
-	/** Deletes **/
-	/*************/
-
-	public boolean delete(String table, String whereClaus, String[] whereArgs) {
-		boolean result = db.delete(table, whereClaus, whereArgs) > 0;
-
-		return result;
-	}
-
-	public boolean delete(String table, String whereClaus) {
-		return delete(table, whereClaus, null);
-	}
-
-	/*
-	 * public Cursor getEvent(long id) throws SQLException { Cursor cur =
-	 * db.query(true, DBTABLE_EVENT, null, KEY_EVENT_EID + "=" + id, null, null,
-	 * null, null, null); if (cur != null) cur.moveToFirst();
-	 * 
-	 * cursorReader(cur); return cur; }
-	 * 
-	 * public Cursor getEventsForTable(int tid, String[] neededColumns) { Cursor
-	 * mCursor = db.query(true, DBTABLE_EVENT, neededColumns, KEY_TABLE_TID + "="
-	 * + tid, null, null, null, null, null); if (mCursor != null)
-	 * mCursor.moveToFirst(); return mCursor; }
-	 * 
-	 * public Cursor query(String[] columns, String selection, String[]
-	 * selectionArgs) { Cursor mCursor = db.query(true, DBTABLE_EVENT, columns,
-	 * selection, selectionArgs, null, null, null, null); if (mCursor != null)
-	 * mCursor.moveToFirst(); return mCursor; }
-	 * 
-	 * private void cursorReader(Cursor cur) { while (!cur.isAfterLast()) { String
-	 * log = ""; for (int i = 0; i < cur.getColumnCount(); i++) log += "[" +
-	 * cur.getColumnName(i) + "]=" + cur.getString(i); //Leg.i( log);
-	 * cur.moveToNext(); } cur.moveToFirst(); }
-	 */
-
-	/***************/
-	/** Utilities **/
-	/***************/
-
-	public static String intArrToString(int[] intArray) {
-		StringBuilder retStr = new StringBuilder();
-		for (int i : intArray)
-			retStr.append(i);
-		return retStr.toString();
-	}
-
-	public static int[] stringToIntArr(String str) {
-		int len = str.length();
-		int[] retArr = new int[len];
-
-		for (int i = 0; i < len; i++)
-			retArr[i] = Integer.parseInt("" + str.charAt(i));
-		return retArr;
-	}
-}

src/nctuw/littledot/localtreasure/ExpeditionActivity.java

 package nctuw.littledot.localtreasure;
 
+import java.util.Currency;
+import java.util.Date;
+
+import nctuw.littledot.localtreasure.components.SelectDistanceActivity;
+import nctuw.littledot.localtreasure.components.TestBundleActivity;
+import nctuw.littledot.localtreasure.database.Database;
+import nctuw.littledot.localtreasure.database.Expedition;
+import nctuw.littledot.localtreasure.database.Treasure;
+import nctuw.littledot.localtreasure.expedition.DialogManager;
 import nctuw.littledot.util.Echo;
 import nctuw.littledot.util.Leg;
 import android.app.Dialog;
 import android.location.LocationListener;
 import android.location.LocationManager;
 import android.os.Bundle;
-import android.text.format.Time;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.View;
 import android.widget.TextView;
 
+import com.google.android.maps.GeoPoint;
 import com.google.android.maps.MapActivity;
+import com.google.android.maps.MapController;
 import com.google.android.maps.MapView;
 
 public class ExpeditionActivity extends MapActivity implements
 		LocationListener, SensorEventListener {
-	public static final long		LOCATION_TIME_THRESH	= 5 * 60 * 1000;
-	public static final float		LOCATION_ACC_THRESH		= 100.0f;
-	public static final int			LOCATION_LOCK_DIALOG	= 1;
+	public static final long		LOCATION_TIME_THRESH				= 5 * 60 * 1000;
+	public static final float		LOCATION_ACC_THRESH					= 100.0f;
+	public static final int			LOCATION_LOCK_DIALOG				= 1;
+	public static final int			EXPEDITION_COMPLETE_DIALOG	= 0;
 
-	public static final String	BUND_DIST							= "dist";
-	public static final String	BUND_BEAR							= "bear";
-	public static final String	BUND_STARTLOC					= "curr";
-	public static final String	BUND_DESTLOC					= "dest";
-	public static final String	BUND_DIST_TRAV				= "dist_trav";
+	public static final String	BUND_EXPEDITION							= "expedition";
 
-	private LayoutInflater			mLI;
 	private LocationManager			mLM;
 	private SensorManager				mSM;
 	private Database						mDB;
-	private DataManager					mDM;
+	// private DataManager mDM;
 
-	private TextView						tvCurLoc;
-	private TextView						tvDestLoc;
-	private TextView						tvDistance;
-	private TextView						tvBearing;
+	private TextView						tvInfo;
 	private MapView							map;
 
 	private ProgressDialog			pdLock;
 
 	// game states
-	private boolean							isCalibrated					= false;
-	private boolean							atDest								= false;
+	private boolean							isCalibrated								= false;
 
-	private int									mDistance;
-	private double							mDistanceTraveled;
-	private double							mBearing;
-	private Location						mStartLocation;
-	private Location						mCurLocation;
-	private Location						mLKLocation;
-	private Location						mDestLocation;
-
-	private Location						lkGPS;
-	private Location						lkNetwork;
-	private Location						lkPassive;
+	// private Location lkGPS;
+	// private Location lkNetwork;
+	// private Location lkPassive;
 
 	private float								mAcceler[];
 	private float								mMagnetic[];
-	private MapOverlay					destMarker;														// destination
-	private MapOverlay					playerMarker;													// player
-	private MapOverlay					startMarker;														// start
+	private MapOverlay					destMarker;																	// destination
+	private MapOverlay					playerMarker;																// player
+	private MapOverlay					startMarker;																	// start
+	private MapController				mController;
+
+	private Expedition					mExpedition;
 
-	private ExpeditionManager		ell;
+	// private ExpeditionManager ell;
 
 	/*
 	 * Base class Activity
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
+
 		setContentView(R.layout.map_act_layout);
+		tvInfo = (TextView) findViewById(R.id.map_tv_info);
 
-		mLI = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+		// mLI = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 		mLM = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
 		mSM = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
 		mDB = new Database(this);
-		mDM = new DataManager(this);
+		// mDM = new DataManager(this);
 
 		// tvCurLoc = (TextView) findViewById(R.id.hunt_tv_cur_location);
 		// tvDestLoc = (TextView) findViewById(R.id.hunt_tv_dest_location);
 		// tvDistance = (TextView) findViewById(R.id.hunt_tv_distance);
 		// tvBearing = (TextView) findViewById(R.id.hunt_tv_bearing);
 		map = (MapView) findViewById(R.id.mapview);
+		mController = map.getController();
+
 		pdLock = new ProgressDialog(this);
 
 		map.setBuiltInZoomControls(true);
 		mMagnetic = new float[3];
 
 		if (savedInstanceState != null) {
-			Echo.d(this, "restore bundle=" + savedInstanceState.size());
-			mDistance = savedInstanceState.getInt(BUND_DIST);
-			mDistanceTraveled = savedInstanceState.getDouble(BUND_DIST_TRAV);
-			mBearing = savedInstanceState.getDouble(BUND_BEAR);
-			mStartLocation = savedInstanceState.getParcelable(BUND_STARTLOC);
-			mDestLocation = savedInstanceState.getParcelable(BUND_DESTLOC);
+			mExpedition = savedInstanceState.getParcelable(BUND_EXPEDITION);
+			// mDistance = savedInstanceState.getFloat(BUND_DIST);
+			// mDistanceTraveled = savedInstanceState.getFloat(BUND_DIST_TRAV);
+			// mBearing = savedInstanceState.getDouble(BUND_BEAR);
+			// mStartLocation = savedInstanceState.getParcelable(BUND_STARTLOC);
+			// mDestLocation = savedInstanceState.getParcelable(BUND_DESTLOC);
 			isCalibrated = true;
+			Echo.a(this, String.format("bundle=%s", mExpedition.toString()));
 
 		} else {
+			mExpedition = new Expedition().setStartTS(System.currentTimeMillis());
+
 			Bundle extras = getIntent().getExtras();
-			mDistance = extras.getInt(SelectDistanceActivity.BUNDLE_DISTANCE, 0);
+			// mDistance = extras.getInt(SelectDistanceActivity.BUNDLE_DISTANCE, 0);
+			mExpedition.setDistance(extras.getFloat(
+					SelectDistanceActivity.BUNDLE_DISTANCE, 0));
 
+			// randomize direction, calculate destination if current location is set
+			// mBearing = Math.random() * 360;
+
+			showDialog(LOCATION_LOCK_DIALOG);
+
+			/*
 			// get a fresh start, only concerns are time & accuracy
 			Time time = new Time();
 			time.setToNow();
 				playerMarker.addLocation(mCurLocation, "CurLoc",
 						mCurLocation.toString());
 
-				Echo.d(this, "gps=\n" + lkGPS);
+				Echo.a(this, "gps=\n" + lkGPS);
 			}
 
 			lkNetwork = mLM.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
 				playerMarker.addLocation(mCurLocation, "CurLoc",
 						mCurLocation.toString());
 
-				Echo.d(this, "network=\n" + lkNetwork);
+				Echo.a(this, "network=\n" + lkNetwork);
 			}
 
 			lkPassive = mLM.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
 				playerMarker.addLocation(mCurLocation, "CurLoc",
 						mCurLocation.toString());
 
-				Echo.d(this, "passive=\n" + lkPassive);
+				Echo.a(this, "passive=\n" + lkPassive);
 			}
+			*/
 
-			// randomize direction, calculate destination if current location is set
-			mBearing = Math.random() * 360;
-			if (mStartLocation != null) {
-				mDestLocation = Geodesy.calculateVincentyDestination(mStartLocation,
-						mBearing, mDistance);
-
-				destMarker.addLocation(mDestLocation, "Dest", mDestLocation.toString());
-
-				// tvCurLoc.setText("===curLoc===\n" + mCurLocation.toString());
-				// tvDestLoc.setText("===destLoc===\n" + mDestLocation.toString());
-				// tvDistance.setText("===dist==="
-				// + mCurLocation.distanceTo(mDestLocation));
-			} else {
-				// else calibrate device
-				// showDialog(LOCATION_LOCK_DIALOG);
-			}
+			// if (mStartLocation != null) {
+			// mDestLocation = Geodesy.calculateVincentyDestination(mStartLocation,
+			// mBearing, mDistance);
+			//
+			// destMarker.addLocation(mDestLocation, "Dest",
+			// mDestLocation.toString());
+
+			// tvCurLoc.setText("===curLoc===\n" + mCurLocation.toString());
+			// tvDestLoc.setText("===destLoc===\n" + mDestLocation.toString());
+			// tvDistance.setText("===dist==="
+			// + mCurLocation.distanceTo(mDestLocation));
+			// } else {
+			// else calibrate device
+			// showDialog(LOCATION_LOCK_DIALOG);
+			// }
 
 		}
 	}
 		if (id == R.id.hunt_but_showmap) {
 			Intent showmap = new Intent(this, HuntingMapActivity.class);
 			startActivity(showmap);
-
-		} else if (id == R.id.map_but_dig) {
-			if (atDest) {
-				// give user reward
-				Treasure reward = Treasure.generateReward();
-				mDB.incrementTreasure(reward, 1);
-
-				mDM.incSuccessExpeditions(1);
-
-			} else {
-				mDM.incFailedExpeditions(1);
-			}
+		} else if (id == R.id.map_but_debug) {
+			Intent test = new Intent(this, TestBundleActivity.class);
+			mExpedition.setEndTS(System.currentTimeMillis());
+			test.putExtra(BUND_EXPEDITION, mExpedition);
+			Leg.a(mExpedition.toString());
+			startActivity(test);
 		}
 	}
 
 	protected void onResume() {
 		super.onResume();
 		// open database
-		mDB.open();
+		mDB.open(Database.MODE_WRITE);
 
 		// register location updates
 		for (String provider : mLM.getAllProviders()) {
-			Leg.d("provider=" + provider);
+			Leg.a("provider=" + provider);
 
-			mLM.requestLocationUpdates(provider, 0, mDistance * 0.05 < 10 ? 10
-					: (int) (mDistance * 0.05), this);
+			mLM.requestLocationUpdates(provider, 0, (float) (mExpedition
+					.getDistance() * 0.05 < 10 ? 10 : mExpedition.getDistance() * 0.05),
+					this);
 		}
 
 		// register sensor updates
 	@Override
 	protected void onPause() {
 		super.onPause();
-		Leg.d("");
+		Leg.a("");
+
+		mExpedition.setEndTS(System.currentTimeMillis());
+
 		mDB.close();
 		mLM.removeUpdates(this);
 		mSM.unregisterListener(this);
 	@Override
 	protected void onSaveInstanceState(Bundle outState) {
 		super.onSaveInstanceState(outState);
-
 		if (isCalibrated) {
-			outState.putInt(BUND_DIST, mDistance);
-			outState.putDouble(BUND_DIST_TRAV, mDistanceTraveled);
-			outState.putDouble(BUND_BEAR, mBearing);
-			outState.putParcelable(BUND_STARTLOC, mStartLocation);
-			outState.putParcelable(BUND_DESTLOC, mDestLocation);
+			mExpedition.setEndTS(System.currentTimeMillis());
+			outState.putParcelable(BUND_EXPEDITION, mExpedition);
+
+			// outState.putDouble(BUND_DIST, mDistance);
+			// outState.putDouble(BUND_DIST_TRAV, mDistanceTraveled);
+			// outState.putParcelable(BUND_STARTLOC, mStartLocation);
+			// outState.putParcelable(BUND_DESTLOC, mDestLocation);
 		}
 
-		Leg.d("saved bundle=" + outState.size());
+		Leg.a(String.format("expedition=%s", mExpedition.toString()));
 	}
 
 	@Override
 			pdLock.setMessage("Please walk around so that the GPS can get a fix");
 			pdLock.setCanceledOnTouchOutside(false);
 			pdLock.setOnCancelListener(new OnCancelListener() {
-				@Override
 				public void onCancel(DialogInterface dialog) {
-					finish();
+					// finish();
+					dialog.dismiss();
 				}
 			});
 			return pdLock;
 
+		} else if (id == EXPEDITION_COMPLETE_DIALOG) {
+			return DialogManager.onCreateDialog(this, mExpedition);
 		}
 
 		return super.onCreateDialog(id, args);
 	/** Interface LocationListener **/
 	/********************************/
 
-	@Override
 	public void onLocationChanged(Location location) {
-		Leg.d("location=" + location.toString());
+		Leg.a("location=" + location.toString());
 		if (location.getAccuracy() > LOCATION_ACC_THRESH) {
-			Leg.d("Discarded inaccurate location=" + location.getAccuracy());
+			Leg.a("Discarded inaccurate location=" + location.getAccuracy());
 			return;
 		}
 
-		mCurLocation = location;
+		// mCurLocation = location;
 
-		// tvCurLoc.setText("===curLoc===\n" + location.toString());
+		mController.setCenter(new GeoPoint((int) (location.getLatitude() * 1E6),
+				(int) (location.getLongitude() * 1E6)));
+		playerMarker.clearOverlay();
+		playerMarker.addLocation(location, "CurLoc", location.toString());
 
 		// always recalibrate on first location lock
-		if (mDestLocation == null || !isCalibrated) {
-			mStartLocation = location;
+		if (!isCalibrated) {
 
-			startMarker.clearOverlay();
-			startMarker.addLocation(mStartLocation, "Cali-Start",
-					mStartLocation.toString());
-
-			mDestLocation = Geodesy.calculateVincentyDestination(location, mBearing,
-					mDistance);
+			double bearing = Math.random() * 360;
+			mExpedition.setStartLoc(location);
+			mExpedition.setDestLoc(Geodesy.calculateVincentyDestination(location,
+					bearing, mExpedition.getDistance()));
 
+			startMarker.clearOverlay();
+			startMarker.addLocation(location, "Cali-Start", location.toString());
 			destMarker.clearOverlay();
-			destMarker.addLocation(mDestLocation, "Cali-Dest",
-					mDestLocation.toString());
-			// tvDestLoc.setText("===destLoc===\n" + mDestLocation.toString());
+			destMarker.addLocation(mExpedition.getDestLoc(), "Cali-Dest", mExpedition
+					.getDestLoc().toString());
 
 			isCalibrated = true;
-			mDM.incTotalExpeditions(1);
 
 			if (pdLock.isShowing()) {
 				pdLock.dismiss();
 		}
 
 		// log traveled distance
-		if (mLKLocation != null) {
-			float traveled = mLKLocation.distanceTo(mCurLocation);
-			mDistanceTraveled += traveled;
-			mDM.incDistanceTraveled(traveled);
+		if (mExpedition.getLKLocation() != null) {
+			float travelled = mExpedition.getLKLocation().distanceTo(location);
+			mExpedition.incTravelled(travelled);
 		}
-		mLKLocation = mCurLocation;
+
+		mExpedition.setLKLocation(location);
 
 		// determine if player is close enough to win
-		if (mCurLocation.distanceTo(mDestLocation) < (float) (mDistance * 0.05)) {
-			atDest = true;
-			Treasure treasure = Treasure.generateReward();
+		if (location.distanceTo(mExpedition.getDestLoc()) < mExpedition
+				.getDistance() * 0.05) {
+			mExpedition.setEndTS(System.currentTimeMillis());
+			mExpedition.setPrize(Treasure.generateReward());
 
-			mDB.incrementTreasure(treasure, 1);
-			mDB.incrementExpeditions(1, 1);
-			mDB.incrementDistance(1, mDistanceTraveled);
+			showDialog(EXPEDITION_COMPLETE_DIALOG);
 		}
 
-		playerMarker.clearOverlay();
-		playerMarker.addLocation(mCurLocation, "CurLoc", mCurLocation.toString());
-
-		// tvDistance.setText("===dist===" +
-		// mCurLocation.distanceTo(mDestLocation));
+		// debug info
+		tvInfo.setText(String.format("Travelled=%f", mExpedition.getTravelled()));
 	}
 
-	@Override
 	public void onProviderDisabled(String provider) {
 	}
 
-	@Override
 	public void onProviderEnabled(String provider) {
 
 	}
 
-	@Override
 	public void onStatusChanged(String provider, int status, Bundle extras) {
-		Echo.d(this, "provider=" + provider + " status=" + status + " extras="
+		Echo.a(this, "provider=" + provider + " status=" + status + " extras="
 				+ extras.toString());
 	}
 
 	/** Interface SensorEventListener **/
 	/***********************************/
 
-	@Override
 	public void onAccuracyChanged(Sensor sensor, int accuracy) {
 	}
 
-	@Override
 	public void onSensorChanged(SensorEvent event) {
 		int type = event.sensor.getType();
 		if (type == Sensor.TYPE_ACCELEROMETER) {

src/nctuw/littledot/localtreasure/ExpeditionManager.java

 	/** Interface LocationListener **/
 	/********************************/
 
-	@Override
 	public void onLocationChanged(Location location) {
 		Leg.d("location=" + location.toString());
 		if (location.getAccuracy() > LOCATION_ACC_THRESH) {
 		// mCurLocation.distanceTo(mDestLocation));
 	}
 
-	@Override
 	public void onProviderDisabled(String provider) {
 
 	}
 
-	@Override
 	public void onProviderEnabled(String provider) {
 
 	}
 
-	@Override
 	public void onStatusChanged(String provider, int status, Bundle extras) {
 	}
 
 	/** Interface SensorEventListener **/
 	/***********************************/
 
-	@Override
 	public void onAccuracyChanged(Sensor sensor, int accuracy) {
 	}
 
-	@Override
 	public void onSensorChanged(SensorEvent event) {
 		int type = event.sensor.getType();
 		if (type == Sensor.TYPE_ACCELEROMETER) {

src/nctuw/littledot/localtreasure/GPSLocationListener.java

 		mHandle = handle;
 	}
 
-	@Override
 	public void onLocationChanged(Location location) {
 		// TODO Auto-generated method stub
 		Message msg = mHandle.obtainMessage(MSG_LOCATION_CHANGED, location);
 		mHandle.sendMessage(msg);
 	}
 
-	@Override
 	public void onProviderDisabled(String provider) {
 		// TODO Auto-generated method stub
 
 	}
 
-	@Override
 	public void onProviderEnabled(String provider) {
 		// TODO Auto-generated method stub
 
 	}
 
-	@Override
 	public void onStatusChanged(String provider, int status, Bundle extras) {
 		// TODO Auto-generated method stub
 

src/nctuw/littledot/localtreasure/Geodesy.java

 	}
 
 	public static Location calculateVincentyDestination(Location curLoc,
-			double bearing, double distance) {// meter
+			double bearing, float distance) {// meter
 		// instantiate the calculator
 		GeodeticCalculator geoCalc = new GeodeticCalculator();
 

src/nctuw/littledot/localtreasure/HuntingActivity.java

 
 import java.util.List;
 
+import nctuw.littledot.localtreasure.components.SelectDistanceActivity;
 import nctuw.littledot.util.Echo;
 import nctuw.littledot.util.Leg;
 import android.app.Dialog;
 			pdLock.setMessage("Please walk around so that the GPS can get a fix");
 			pdLock.setCanceledOnTouchOutside(false);
 			pdLock.setOnCancelListener(new OnCancelListener() {
-				@Override
 				public void onCancel(DialogInterface dialog) {
 					finish();
 				}
 	 * Interface LocationListener
 	 */
 
-	@Override
 	public void onLocationChanged(Location location) {
 		Leg.d("location=" + location.toString());
 		if (location.getAccuracy() > LOCATION_ACC_THRESH) {
 		tvDistance.setText("===dist===" + mCurLocation.distanceTo(mDestLocation));
 	}
 
-	@Override
 	public void onProviderDisabled(String provider) {
 	}
 
-	@Override
 	public void onProviderEnabled(String provider) {
 
 	}
 
-	@Override
 	public void onStatusChanged(String provider, int status, Bundle extras) {
 		Echo.d(this, "provider=" + provider + " status=" + status + " extras="
 				+ extras.toString());
 	 * Interface SensorEventListener
 	 */
 
-	@Override
 	public void onAccuracyChanged(Sensor sensor, int accuracy) {
 		// TODO Auto-generated method stub
 
 	}
 
-	@Override
 	public void onSensorChanged(SensorEvent event) {
 		int type = event.sensor.getType();
 		if (type == Sensor.TYPE_ACCELEROMETER) {

src/nctuw/littledot/localtreasure/MainActivity.java

 package nctuw.littledot.localtreasure;
 
+import nctuw.littledot.localtreasure.components.ProfileActivity;
+import nctuw.littledot.localtreasure.components.SelectDistanceActivity;
+import nctuw.littledot.localtreasure.database.Database;
+import nctuw.littledot.localtreasure.database.Profile;
+import nctuw.littledot.localtreasure.database.SPManager;
+import nctuw.littledot.localtreasure.database.Treasure;
 import nctuw.littledot.util.Leg;
 import android.app.Activity;
 import android.app.Dialog;
 import android.widget.TextView;
 
 public class MainActivity extends Activity {
-	private DataManager	mDataManager;
+	public static final String	BUN_PROFILE	= "bunProfile";
+	private TextView						tvInfo;
 
-	private TextView		tvInfo;
+	private Database						mDB;
+	private SPManager						mSPManager;
+	private Profile							mProfile;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		setContentView(R.layout.main_act_layout);
-
-		mDataManager = new DataManager(this);
 
+		setContentView(R.layout.main_act_layout);
 		tvInfo = (TextView) findViewById(R.id.main_tv_info);
 
+		mSPManager = new SPManager(this);
+		mDB = new Database(this);
+		mDB.open(Database.MODE_WRITE);
+		mProfile = mDB.queryProfile(mSPManager.getActiveProfileID());
+		Leg.a(mProfile.toString());
+
+		tvInfo.setText(mProfile.toString());
 	}
 
 	@Override
 	@Override
 	protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
 		super.onPrepareDialog(id, dialog, args);
-		Leg.d("");
+		Leg.a("");
 	}
 
-	public void onStartNewHunt(View v) {
-		Intent intent = new Intent(this, SelectDistanceActivity.class);
-		startActivity(intent);
-	}
+	public void onClick(View v) {
+
+		int id = v.getId();
 
+		if (id == R.id.main_but_startExpedition) {
+			Intent intent = new Intent(this, SelectDistanceActivity.class);
+			startActivity(intent);
+		} else if (id == R.id.main_but_profile) {
+			Intent intent = new Intent(this, ProfileActivity.class);
+			intent.putExtra(BUN_PROFILE, mProfile);
+			startActivity(intent);
+		}
+	}
 }

src/nctuw/littledot/localtreasure/SelectDistanceActivity.java

-package nctuw.littledot.localtreasure;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-
-public class SelectDistanceActivity extends Activity {
-	public static String	BUNDLE_DISTANCE	= "bundle_distance";
-
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.selectdistance_act_layout);
-
-	}
-
-	public void onChooseDistance(View v) {
-		Intent intent = new Intent(this, ExpeditionActivity.class);
-
-		switch (v.getId()) {
-			case R.id.distance_but_500m:
-				intent.putExtra(BUNDLE_DISTANCE, 500);
-				break;
-		}
-
-		startActivity(intent);
-	}
-
-	public void onChooseCustomDistance(View v) {
-		EditText et = (EditText) findViewById(R.id.distance_et_custom);
-		Button but = (Button) findViewById(R.id.distance_but_custom);
-
-		if (et.getVisibility() == View.GONE) {
-			et.setVisibility(View.VISIBLE);
-			but.setText("OK!");
-		} else {
-			Intent intent = new Intent(this, ExpeditionActivity.class);
-			intent.putExtra(BUNDLE_DISTANCE,
-					Integer.parseInt(et.getText().toString()));
-			startActivity(intent);
-		}
-	}
-}

src/nctuw/littledot/localtreasure/SplashActivity.java

 		TextView logo = (TextView) findViewById(R.id.splash_tv_appName);
 		logo.postDelayed(new Runnable() {
 
-			@Override
 			public void run() {
 
 				Intent mainActivity = new Intent(SplashActivity.this,

src/nctuw/littledot/localtreasure/Treasure.java

-package nctuw.littledot.localtreasure;
-
-import java.util.Random;
-
-public enum Treasure {
-	APPLE(R.drawable.treasure_apple_256, "Apple"),
-	ORANGE(R.drawable.treasure_orange_256, "Orange"),
-	BANANA(R.drawable.treasure_banana_256, "Banana");
-
-	private final int			drawableID;
-	private final String	name;
-
-	Treasure(int drawID, String n) {
-		drawableID = drawID;
-		name = n;
-	}
-
-	public int getDrawableId() {
-		return drawableID;
-	}
-
-	/**
-	 * Generates a random reward.
-	 * 
-	 * @return
-	 */
-	public static Treasure generateReward() {
-		Random rand = new Random();
-		int index = rand.nextInt(values().length);
-
-		return values()[index];
-	}
-}

src/nctuw/littledot/localtreasure/components/ProfileActivity.java

+package nctuw.littledot.localtreasure.components;
+
+import nctuw.littledot.localtreasure.MainActivity;
+import nctuw.littledot.localtreasure.R;
+import nctuw.littledot.localtreasure.database.Database;
+import nctuw.littledot.localtreasure.database.Profile;
+import nctuw.littledot.localtreasure.database.Treasure;
+import nctuw.littledot.util.Leg;
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.GridView;
+import android.widget.TextView;
+
+public class ProfileActivity extends Activity {
+	// widgets
+	private TextView	tvName;
+	private TextView	tvExpeditionTotal;
+	private TextView	tvTotalDistance;
+	private TextView	tvTimeTotal;
+	private GridView	gvTreasure;
+
+	private Database	mDB	= new Database(this);
+	private Profile		mProfile;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		setContentView(R.layout.profile_activity);
+		tvName = (TextView) findViewById(R.id.profile_tv_name);
+		tvExpeditionTotal = (TextView) findViewById(R.id.profile_tv_totalExpedition);
+		tvTotalDistance = (TextView) findViewById(R.id.profile_tv_totalDistance);
+		tvTimeTotal = (TextView) findViewById(R.id.profile_tv_totalTime);
+		gvTreasure = (GridView) findViewById(R.id.profile_gv_treasure);
+
+		Bundle bundle = getIntent().getExtras();
+		mProfile = bundle.getParcelable(MainActivity.BUN_PROFILE);
+		Leg.a(mProfile.toString());
+
+		tvName.setText(mProfile.getName());
+		tvExpeditionTotal.setText("Total expeditions="
+				+ mProfile.getTotalExpeditions());
+		tvTotalDistance.setText("Total distance travelled="
+				+ mProfile.getTotalDistance());
+	}
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+		mDB.open(Database.MODE_WRITE);
+	}
+
+	@Override
+	protected void onPause() {
+		super.onPause();
+		mDB.close();
+	}
+}

src/nctuw/littledot/localtreasure/components/SelectDistanceActivity.java

+package nctuw.littledot.localtreasure.components;
+
+import nctuw.littledot.localtreasure.ExpeditionActivity;
+import nctuw.littledot.localtreasure.R;
+import nctuw.littledot.localtreasure.R.id;
+import nctuw.littledot.localtreasure.R.layout;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+public class SelectDistanceActivity extends Activity {
+	public static String	BUNDLE_DISTANCE	= "bundle_distance";
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.selectdistance_act_layout);
+
+	}
+
+	public void onChooseDistance(View v) {
+		Intent intent = new Intent(this, ExpeditionActivity.class);
+
+		switch (v.getId()) {
+			case R.id.distance_but_500m:
+				intent.putExtra(BUNDLE_DISTANCE, 500F);
+				break;
+		}
+
+		startActivity(intent);
+	}
+
+	public void onChooseCustomDistance(View v) {
+		EditText et = (EditText) findViewById(R.id.distance_et_custom);
+		Button but = (Button) findViewById(R.id.distance_but_custom);
+
+		if (et.getVisibility() == View.GONE) {
+			et.setVisibility(View.VISIBLE);
+			but.setText("OK!");
+		} else {
+			Intent intent = new Intent(this, ExpeditionActivity.class);
+			intent.putExtra(BUNDLE_DISTANCE,
+					Float.parseFloat(et.getText().toString()));
+			startActivity(intent);
+		}
+	}
+}

src/nctuw/littledot/localtreasure/components/TestBundleActivity.java

+package nctuw.littledot.localtreasure.components;
+
+import nctuw.littledot.localtreasure.ExpeditionActivity;
+import nctuw.littledot.localtreasure.R;
+import nctuw.littledot.util.Leg;
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class TestBundleActivity extends Activity {
+	private TextView	tvDebug;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+
+		setContentView(R.layout.bundletest_act_layout);
+		tvDebug = (TextView) findViewById(R.id.bundle_tv_debug);
+
+		Bundle bundle = getIntent().getExtras();
+		Leg.a(bundle.getParcelable(ExpeditionActivity.BUND_EXPEDITION).toString());
+	}
+}

src/nctuw/littledot/localtreasure/database/Database.java

+package nctuw.littledot.localtreasure.database;
+
+import java.util.Date;
+
+import nctuw.littledot.util.Leg;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.location.Location;
+
+public class Database {
+	private static final int		DB_VERSION											= 4;
+	public static final String	DBNAME													= "nctuw.littledot.localtreasure";
+
+	public static final String	DBTABLE_TREASURE								= "treasure";
+	public static final String	KEY_TREASURE_ID									= "tID";
+	public static final String	KEY_TREASURE_NAME								= "tName";
+	public static final String	KEY_TREASURE_NUM								= "tDays";
+
+	public static final String	DBTABLE_PROFILE									= "profile";
+	public static final String	KEY_PROFILE_ID									= "pID";
+	private static final String	KEY_PROFILE_NAME								= "pName";
+	public static final String	KEY_PROFILE_EXPEDITIONS					= "pExpeditions";
+	public static final String	KEY_PROFILE_DISTANCE_TRAVELED		= "pDistanceTraveled";
+
+	public static final String	DBTABLE_EXPEDITION							= "expedition";
+	public static final String	KEY_EXPEDITION_ID								= "eID";
+	public static final String	KEY_EXPEDITION_DISTANCE					= "eDistance";
+	public static final String	KEY_EXPEDITION_START_TIMESTAMP	= "eStartTimestamp";
+	public static final String	KEY_EXPEDITION_END_TIMESTAMP		= "eEndTimestamp";
+	public static final String	KEY_EXPEDITION_TIME							= "eTime";
+	public static final String	KEY_EXPEDITION_TRESURE					= "eTreasure";
+
+	private static final String	SQL_CREATE_TREASURE							= "create table if not exists "
+																																	+ DBTABLE_TREASURE
+																																	+ "("
+																																	+ KEY_TREASURE_ID
+																																	+ " integer not null primary key,"
+																																	+ KEY_TREASURE_NAME
+																																	+ " text default '',"
+																																	+ KEY_TREASURE_NUM
+																																	+ " integer not null default 0"
+																																	+ ");";
+
+	private static final String	SQL_CREATE_PROFILE							= "create table if not exists "
+																																	+ DBTABLE_PROFILE
+																																	+ "("
+																																	+ KEY_PROFILE_ID
+																																	+ " integer not null primary key autoincrement,"
+																																	+ KEY_PROFILE_NAME
+																																	+ " text default '<John Doe>',"
+																																	+ KEY_PROFILE_EXPEDITIONS
+																																	+ " integer not null default 0,"
+																																	+ KEY_PROFILE_DISTANCE_TRAVELED
+																																	+ " real not null default 0"
+																																	+ ");";
+
+	private static final String	SQL_CREATE_EXPEDITION						= "create table if not exists "
+																																	+ DBTABLE_EXPEDITION
+																																	+ "("
+																																	+ KEY_EXPEDITION_ID
+																																	+ " integer not null primary key autoincrement,"
+																																	+ KEY_EXPEDITION_DISTANCE
+																																	+ " real not null default 0,"
+																																	+ KEY_EXPEDITION_START_TIMESTAMP
+																																	+ " text default CURRENT_TIMESTAMP,"
+																																	+ KEY_EXPEDITION_TIME
+																																	+ " integer not null default 0,"
+																																	+ KEY_EXPEDITION_TRESURE
+																																	+ " integer not null default 0"
+																																	+ ");";
+
+	public static final int			MODE_READ												= 1;
+	public static final int			MODE_WRITE											= 2;
+
+	private final Context				mContext;
+
+	private DatabaseHelper			DBHelper;
+	private SQLiteDatabase			db;
+
+	public Database(Context ctx) {
+		this.mContext = ctx;
+		DBHelper = new DatabaseHelper(mContext);
+
+	}
+
+	private class DatabaseHelper extends SQLiteOpenHelper {
+		DatabaseHelper(Context context) {
+			super(context, DBNAME, null, DB_VERSION);
+		}
+
+		@Override
+		public void onCreate(SQLiteDatabase db) {
+			db.execSQL(SQL_CREATE_TREASURE);
+			db.execSQL(SQL_CREATE_PROFILE);
+			db.execSQL(SQL_CREATE_EXPEDITION);
+
+			db.execSQL("insert into " + DBTABLE_PROFILE + "(" + KEY_PROFILE_ID
+					+ ") values (1);");
+		}
+
+		@Override
+		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+			db.beginTransaction();
+			try {
+				// db.execSQL("alter table " + DBTABLE_PROFILE + " to TEMP");
+				// db.execSQL(SQL_CREATE_PROFILE);
+				// db.execSQL("insert into "+DBTABLE_PROFILE+" orig_table_name(col_a, col_b)				SELECT col_a, colb				FROM tmp_table_name;");
+
+				db.execSQL("drop table if exists " + DBTABLE_TREASURE + ";");
+				db.execSQL("drop table if exists " + DBTABLE_PROFILE + ";");
+				db.execSQL("drop table if exists " + DBTABLE_EXPEDITION + ";");
+				onCreate(db);
+
+				db.setTransactionSuccessful();
+			} finally {
+				db.endTransaction();
+			}
+
+		}
+	}
+
+	public void open(int mode) {
+		if (mode == MODE_WRITE)
+			db = DBHelper.getWritableDatabase();
+		else if (mode == MODE_READ)
+			db = DBHelper.getReadableDatabase();
+		else
+			throw new IllegalArgumentException("Unknown access argument");
+	}
+
+	public void close() {
+		if (db.isOpen())
+			db.close();
+	}
+
+	public int getVersion() {
+		return db.getVersion();
+	}
+
+	public void showAllData(String table) {
+		Cursor cur = db.query(table, null, null, null, null, null, null);
+		if (cur != null)
+			cur.moveToFirst();
+
+		while (!cur.isAfterLast()) {
+			String log = "";
+			for (int i = 4; i < 9; i++) {
+				log += "[" + i + "]=";
+				log += cur.getInt(i);
+			}
+			Leg.i(log);
+			cur.moveToNext();
+		}
+	}
+
+	/*************/
+	/** Queries **/
+	/*************/
+
+	public Cursor rawQuery(String sql) {
+		return rawQuery(sql, null);
+	}
+
+	public Cursor rawQuery(String sql, String[] args) {
+		Cursor cur = db.rawQuery(sql, args);
+
+		if (cur.moveToFirst())
+			return cur;
+		else
+			return null;
+	}
+
+	public int queryTreasureNum(Treasure treasure) {
+		Cursor cur = rawQuery(
+				"select * from ? where ? = ? ",
+				new String[] { DBTABLE_TREASURE, KEY_TREASURE_ID,
+						Integer.toString(treasure.getDrawableId()) });
+
+		if (cur.moveToFirst())
+			return cur.getInt(cur.getColumnIndexOrThrow(KEY_TREASURE_NUM));
+		else
+			return -1;
+	}
+
+	public int queryExpeditionNum(int profileID) {
+		Cursor cur = rawQuery("select * from ? where ? = ? ", new String[] {
+				DBTABLE_PROFILE, KEY_PROFILE_ID, Integer.toString(profileID) });
+
+		if (cur.moveToFirst())
+			return cur.getInt(cur.getColumnIndexOrThrow(KEY_PROFILE_EXPEDITIONS));
+		else
+			return -1;
+	}
+
+	public double queryDistanceTraveled(int profileID) {
+		Cursor cur = rawQuery("select * from ? where ? = ? ", new String[] {
+				DBTABLE_PROFILE, KEY_PROFILE_ID, Integer.toString(profileID) });
+
+		if (cur.moveToFirst())
+			return cur.getDouble(cur
+					.getColumnIndexOrThrow(KEY_PROFILE_DISTANCE_TRAVELED));
+		else
+			return -1;
+	}
+
+	public Profile queryProfile(int profileID) {
+		Cursor cur = rawQuery(String.format("select * from %s where %s=%d",
+				DBTABLE_PROFILE, KEY_PROFILE_ID, profileID));
+
+		if (cur != null) {
+			Leg.dumpCursor(cur);
+			Profile profile = new Profile();
+			profile.setProfileID(profileID);
+			profile.setName(cur.getString(cur.getColumnIndex(KEY_PROFILE_NAME)));
+			profile.setTotalExpeditions(cur.getLong(cur
+					.getColumnIndex(KEY_PROFILE_EXPEDITIONS)));
+			profile.setTotalDistance(cur.getDouble(cur
+					.getColumnIndex(KEY_PROFILE_EXPEDITIONS)));
+
+			return profile;
+		} else
+			return null;
+	}
+
+	/*************/
+	/** Inserts **/
+	/*************/
+
+	public long insert(String table, String[] keys, Object[] values) {
+		if (keys.length != values.length)
+			throw new IllegalArgumentException(
+					"keys-values must be of the same length");
+
+		ContentValues kvPair = new ContentValues();
+
+		for (int i = 0; i < keys.length; i++) {
+			if (values[i] instanceof String)
+				kvPair.put(keys[i], (String) values[i]);
+			else if (values[i] instanceof Integer)
+				kvPair.put(keys[i], (Integer) values[i]);
+			else if (values[i] instanceof Double)
+				kvPair.put(keys[i], (Double) values[i]);
+			else if (values[i] instanceof Float)
+				kvPair.put(keys[i], (Float) values[i]);
+			else if (values[i] instanceof Long)
+				kvPair.put(keys[i], (Long) values[i]);
+			else if (values[i] instanceof Short)
+				kvPair.put(keys[i], (Short) values[i]);
+			else if (values[i] instanceof Boolean)
+				kvPair.put(keys[i], (Boolean) values[i]);
+			else if (values[i] instanceof Byte)
+				kvPair.put(keys[i], (Byte) values[i]);
+			else if (values[i] instanceof byte[])
+				kvPair.put(keys[i], (byte[]) values[i]);
+			else
+				throw new IllegalArgumentException("Type "
+						+ values[i].getClass().getName() + " is not supported.");
+		}
+
+		long result = db.insert(table, null, kvPair);
+
+		return result;
+	}
+
+	public long insertExpedition(Location startLoc, Location endLoc,
+			double distance, Date startTime, Date endTime, Treasure prize) {
+		return 0;
+	}
+
+	/*************/
+	/** Updates **/
+	/*************/
+
+	public boolean update(String table, String[] keys, Object[] values,
+			String whereClause) {
+		if (keys.length != values.length)
+			throw new IllegalArgumentException(
+					"keys-values must be of the same length");
+
+		ContentValues kvPair = new ContentValues();
+		for (int i = 0; i < keys.length; i++) {
+			if (values[i] instanceof String)
+				kvPair.put(keys[i], (String) values[i]);
+			else if (values[i] instanceof Integer)
+				kvPair.put(keys[i], (Integer) values[i]);
+			else if (values[i] instanceof Double)
+				kvPair.put(keys[i], (Double) values[i]);
+			else if (values[i] instanceof Float)
+				kvPair.put(keys[i], (Float) values[i]);
+			else if (values[i] instanceof Long)
+				kvPair.put(keys[i], (Long) values[i]);
+			else if (values[i] instanceof Short)
+				kvPair.put(keys[i], (Short) values[i]);
+			else if (values[i] instanceof Boolean)
+				kvPair.put(keys[i], (Boolean) values[i]);
+			else if (values[i] instanceof Byte)
+				kvPair.put(keys[i], (Byte) values[i]);
+			else if (values[i] instanceof byte[])
+				kvPair.put(keys[i], (byte[]) values[i]);
+			else
+				throw new IllegalArgumentException("Type "
+						+ values[i].getClass().getName() + " is not supported.");
+		}
+
+		boolean result = db.update(table, kvPair, whereClause, null) > 0;
+
+		return result;
+	}
+
+	public boolean update(String table, String key, Object value,
+			String whereClause) {
+		return update(table, new String[] { key }, new Object[] { value },
+				whereClause);
+	}
+
+	/**
+	 * Increment the number of accumulated treasure by the specified amount.
+	 * 
+	 * @param treasure
+	 * @param increment
+	 * @return
+	 */
+	public void incrementTreasure(Treasure treasure, int increment) {
+		int ret = queryTreasureNum(treasure);
+
+		if (ret == -1) {
+			// do an insert if key does not exist yet
+			insert(DBTABLE_TREASURE, new String[] { KEY_TREASURE_NAME,
+					KEY_TREASURE_NUM }, new Object[] { treasure, increment });
+		} else {
+			// do an update if key exists
+			int newNum = ret + increment;
+
+			update(DBTABLE_TREASURE, KEY_TREASURE_NUM, newNum, KEY_TREASURE_NAME
+					+ " = " + treasure);
+		}
+	}
+
+	public void incrementExpeditions(int profileID, int increment) {
+		int ret = queryExpeditionNum(profileID);
+
+		if (ret == -1) {
+			insert(DBTABLE_PROFILE, new String[] { KEY_PROFILE_EXPEDITIONS,
+					KEY_PROFILE_DISTANCE_TRAVELED }, new Object[] { 0, 0 });
+		} else {
+			int newNum = ret + increment;
+
+			update(DBTABLE_PROFILE, KEY_PROFILE_EXPEDITIONS, newNum, KEY_PROFILE_ID
+					+ "=" + profileID);
+		}