OSDN Git Service

speech bubble, multiple row in running history
authorkazuhiko <kazhik@orange.(none)>
Thu, 19 Nov 2009 13:33:04 +0000 (22:33 +0900)
committerkazuhiko <kazhik@orange.(none)>
Thu, 19 Nov 2009 13:33:04 +0000 (22:33 +0900)
15 files changed:
res/layout/gpxfilelist.xml [new file with mode: 0644]
res/layout/runningrecord.xml
res/values-ja/strings.xml
res/values/strings.xml
src/net/kazhik/android/tokyorunners/Config.java
src/net/kazhik/android/tokyorunners/Constants.java
src/net/kazhik/android/tokyorunners/ExLog.java
src/net/kazhik/android/tokyorunners/GpxFileList.java [new file with mode: 0644]
src/net/kazhik/android/tokyorunners/MapMode.java
src/net/kazhik/android/tokyorunners/Record.java
src/net/kazhik/android/tokyorunners/RunningHistory.java
src/net/kazhik/android/tokyorunners/RunningHistoryAdapter.java [new file with mode: 0644]
src/net/kazhik/android/tokyorunners/RunningRecord.java
src/net/kazhik/android/tokyorunners/RunningRecordProvider.java
src/net/kazhik/android/tokyorunners/TokyoRunners.java

diff --git a/res/layout/gpxfilelist.xml b/res/layout/gpxfilelist.xml
new file mode 100644 (file)
index 0000000..84fd5a6
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:background="#696969"
+  android:layout_width="wrap_content"
+  android:layout_height="fill_parent">
+  
+  <ListView
+      android:id="@+id/android:list"
+      android:layout_height="fill_parent"
+      android:layout_width="fill_parent"
+    />
+  
+  
+</LinearLayout>
index 69c5d7a..6fbd842 100644 (file)
@@ -1,9 +1,26 @@
 <?xml version="1.0" encoding="utf-8"?>
-<TextView
-  xmlns:android="http://schemas.android.com/apk/res/android"
-  android:textSize="24dp"
-  android:layout_width="fill_parent"
-  android:textColor="#7CFC00"
-  
-  android:layout_height="72dp">
-</TextView>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+       android:background="#696969" android:orientation="vertical"
+       android:layout_width="wrap_content" android:layout_height="fill_parent">
+
+       <TextView android:id="@+id/history_starttime"
+               android:textSize="24dp" android:textColor="#7CFC00"
+               android:layout_width="fill_parent" android:layout_height="wrap_content">
+       </TextView>
+
+       <LinearLayout android:orientation="horizontal"
+               android:layout_width="fill_parent" android:layout_height="wrap_content">
+               <TextView android:id="@+id/history_distance"
+                       android:layout_width="fill_parent" android:layout_height="wrap_content"
+                       android:textSize="24dp" android:gravity="left" android:textColor="#7CFC00"
+                       android:layout_weight="1" />
+               <TextView android:id="@+id/history_time"
+                       android:layout_width="fill_parent" android:layout_height="wrap_content"
+                       android:textColor="#7CFC00" android:textSize="24dp" android:gravity="left"
+                       android:layout_weight="1" />
+       </LinearLayout>
+
+
+
+</LinearLayout>
+
index 79a21dd..de4e259 100644 (file)
@@ -14,6 +14,9 @@
     <string name="menu_setting">設定</string>
     <string name="menu_save">保存</string>
     <string name="menu_history">履歴</string>
+
+    <string name="point_start">start</string>
+    <string name="point_finish">finish</string>
     
     <string name="contextmenu_deletethis">この記録を削除</string>
     <string name="contextmenu_deleteall">すべての記録を削除</string>
index 528949a..1adfa9b 100755 (executable)
@@ -16,6 +16,9 @@
     <string name="menu_setting">Settings</string>
     <string name="menu_save">Save</string>
     <string name="menu_history">History</string>
+
+    <string name="point_start">Start</string>
+    <string name="point_finish">Finish</string>
     
     <string name="contextmenu_deletethis">Delete this</string>
     <string name="contextmenu_deleteall">Delete all</string>
index 7dd3d4c..62ee613 100755 (executable)
@@ -4,7 +4,15 @@ import android.content.SharedPreferences;
 import android.os.Bundle;\r
 import android.preference.PreferenceActivity;\r
 \r
+// TODO: Auto-generated Javadoc\r
+/**\r
+ * The Class Config.\r
+ */\r
 public class Config extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {\r
+       \r
+       /* (non-Javadoc)\r
+        * @see android.preference.PreferenceActivity#onCreate(android.os.Bundle)\r
+        */\r
        public void onCreate(Bundle savedInstanceState) {\r
                super.onCreate(savedInstanceState);\r
 \r
@@ -43,7 +51,10 @@ public class Config extends PreferenceActivity implements SharedPreferences.OnSh
 */\r
 \r
 //     @Override\r
-       public void onSharedPreferenceChanged(SharedPreferences pref, String key) {\r
+       /* (non-Javadoc)\r
+ * @see android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged(android.content.SharedPreferences, java.lang.String)\r
+ */\r
+public void onSharedPreferenceChanged(SharedPreferences pref, String key) {\r
                // if "use_gps" is false, disable "gps_frequency"\r
                \r
        }\r
index c780286..845aea6 100755 (executable)
@@ -2,12 +2,24 @@ package net.kazhik.android.tokyorunners;
 \r
 import android.view.Menu;\r
 \r
+// TODO: Auto-generated Javadoc\r
+/**\r
+ * The Class Constants.\r
+ */\r
 public class Constants {\r
+       \r
+       /** The Constant MENU_SETTING. */\r
        public static final int MENU_SETTING = Menu.FIRST + 1;\r
+       \r
+       /** The Constant MENU_HISTORY. */\r
        public static final int MENU_HISTORY = Menu.FIRST + 2;\r
 \r
+       /** The Constant DIALOG_EXIT_ID. */\r
        public static final int DIALOG_EXIT_ID = 4001;\r
        \r
+       /** The Constant REQUEST_CODE_SETTINGS. */\r
        public static final int REQUEST_CODE_SETTINGS = 1000;\r
+       \r
+       /** The Constant REQUEST_CODE_HISTORY. */\r
        public static final int REQUEST_CODE_HISTORY = 1001;\r
 }\r
index 6fdd55f..d3ec4d5 100644 (file)
@@ -1,7 +1,7 @@
 package net.kazhik.android.tokyorunners;
 
-import java.io.File;
 import java.io.BufferedWriter;
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -13,13 +13,28 @@ import java.util.Date;
 import android.os.Environment;
 import android.util.Log;
 
+// TODO: Auto-generated Javadoc
+/**
+ * The Class ExLog.
+ */
 public class ExLog {
+       
+       /** The Constant LOGDIR. */
        private final static String LOGDIR = Environment
                        .getExternalStorageDirectory().getPath()
                        + "/tokyorunners/";
+       
+       /** The Constant LOGFILE. */
        private final static String LOGFILE = LOGDIR + "log.txt";
+    
+    /** The Constant m_formatter. */
     private final static SimpleDateFormat m_formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
 
+       /**
+        * Put.
+        * 
+        * @param logtext the logtext
+        */
        public static void put(String logtext) {
                Date now = new Date();
                BufferedWriter logWriter = null;
@@ -59,6 +74,15 @@ public class ExLog {
 
        }
 
+       /**
+        * Mkdir_p.
+        * 
+        * @param dir the dir
+        * 
+        * @return true, if successful
+        * 
+        * @throws IOException Signals that an I/O exception has occurred.
+        */
        public static boolean mkdir_p(File dir) throws IOException {
                if (!dir.exists()) {
                        if (!dir.mkdirs()) {
@@ -73,6 +97,15 @@ public class ExLog {
                }
        }
 
+       /**
+        * Mkdir_p.
+        * 
+        * @param dir the dir
+        * 
+        * @return true, if successful
+        * 
+        * @throws IOException Signals that an I/O exception has occurred.
+        */
        public static boolean mkdir_p(String dir) throws IOException {
                return mkdir_p(new File(dir));
        }
diff --git a/src/net/kazhik/android/tokyorunners/GpxFileList.java b/src/net/kazhik/android/tokyorunners/GpxFileList.java
new file mode 100644 (file)
index 0000000..a7f8830
--- /dev/null
@@ -0,0 +1,80 @@
+package net.kazhik.android.tokyorunners;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Formatter;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class GpxFileList extends ListActivity implements OnItemClickListener {
+
+       private final static String LOGDIR = Environment
+                       .getExternalStorageDirectory().getPath()
+                       + "/tokyorunners/";
+
+       private static final int MENU_DELETE_THIS = Menu.FIRST + 200;
+       private static final int MENU_DELETE_ALL = Menu.FIRST + 201;
+       
+       @Override
+       public void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+
+               setContentView(R.layout.gpxfilelist);
+
+               ArrayList<String> history = new ArrayList<String>();
+               ArrayAdapter<String> historyArray = new ArrayAdapter<String>(this,
+                               R.layout.runningrecord, history);
+
+               setListAdapter(historyArray);
+
+               // イベントリスナを登録
+               getListView().setOnItemClickListener(this);
+
+               getListView().setOnCreateContextMenuListener(this);
+       }
+
+       public void onItemClick(AdapterView<?> parent, View view, int position,
+                       long id) {
+               
+               // GPXファイルを読み込む
+               finish();
+
+       }
+
+
+       @SuppressWarnings("unchecked")
+       public boolean onContextItemSelected(MenuItem item) {
+               AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+                               .getMenuInfo();
+               ArrayAdapter<String> historyArray = (ArrayAdapter<String>) getListAdapter();
+               int position = info.position;
+               switch (item.getItemId()) {
+               default:
+                       break;
+               }
+               switch (item.getItemId()) {
+               case MENU_DELETE_THIS:
+                       historyArray.remove(historyArray.getItem(position));
+                       break;
+               case MENU_DELETE_ALL:
+                       historyArray.clear();
+                       break;
+               default:
+                       break;
+               }
+               return super.onContextItemSelected(item);
+       }
+
+
+}
index 3246174..a362f89 100755 (executable)
@@ -18,7 +18,11 @@ import android.graphics.Color;
 import android.graphics.Paint;\r
 import android.graphics.Path;\r
 import android.graphics.Point;\r
+import android.graphics.RectF;\r
+import android.graphics.Paint.FontMetrics;\r
 import android.graphics.drawable.Drawable;\r
+import android.graphics.drawable.ShapeDrawable;\r
+import android.graphics.drawable.shapes.PathShape;\r
 import android.os.Bundle;\r
 import android.os.Debug;\r
 import android.util.Log;\r
@@ -36,36 +40,88 @@ import com.google.android.maps.Overlay;
 import com.google.android.maps.OverlayItem;\r
 import com.google.android.maps.Projection;\r
 \r
+// TODO: Auto-generated Javadoc\r
+/**\r
+ * The Class MapMode.\r
+ */\r
 public class MapMode extends MapActivity {\r
 \r
+       /** The m_controller. */\r
        private MapController m_controller;\r
+       \r
+       /** The m_map overlays. */\r
        private List<Overlay> m_mapOverlays;\r
+       \r
+       /** The m_overlay splitpoints. */\r
        private SplitPoints m_overlaySplitpoints;\r
+       \r
+       /** The m_prev point. */\r
        private GeoPoint m_prevPoint = null;\r
+       \r
+       /** The m_start time. */\r
        private long m_startTime = 0;\r
-       private final SimpleDateFormat m_timeFormatter = new SimpleDateFormat("HH:mm:ss");\r
+       \r
+       /** The m_time formatter. */\r
+       private final SimpleDateFormat m_timeFormatter = new SimpleDateFormat(\r
+                       "HH:mm:ss");\r
+\r
+       /** The m_route paint. */\r
+       private static Paint m_routePaint;\r
+       \r
+       /** The m_text paint. */\r
+       private static Paint m_textPaint;\r
+       \r
+       /** The m_info paint. */\r
+       private static Paint m_infoPaint;\r
 \r
+       static {\r
+               m_routePaint = new Paint(Paint.ANTI_ALIAS_FLAG);\r
+               m_routePaint.setStyle(Paint.Style.STROKE);\r
+               m_routePaint.setAntiAlias(true);\r
+               m_routePaint.setStrokeWidth(3);\r
+               m_routePaint.setColor(Color.YELLOW);\r
+\r
+               m_textPaint = new Paint();\r
+               m_textPaint.setColor(Color.BLACK);\r
+\r
+               m_infoPaint = new Paint();\r
+               m_infoPaint.setTextSize(20);\r
+               m_infoPaint.setAntiAlias(true);\r
+               m_infoPaint.setFakeBoldText(true);\r
+               m_infoPaint.setColor(Color.MAGENTA);\r
+\r
+       }\r
+\r
+       /**\r
+        * The Class RunningRoute.\r
+        */\r
        public class RunningRoute extends Overlay {\r
 \r
+               /** The m_start. */\r
                private GeoPoint m_start;\r
+               \r
+               /** The m_end. */\r
                private GeoPoint m_end;\r
 \r
+               /**\r
+                * Instantiates a new running route.\r
+                * \r
+                * @param ptStart the pt start\r
+                * @param ptEnd the pt end\r
+                */\r
                public RunningRoute(GeoPoint ptStart, GeoPoint ptEnd) {\r
                        m_start = ptStart;\r
                        m_end = ptEnd;\r
                }\r
 \r
+               /* (non-Javadoc)\r
+                * @see com.google.android.maps.Overlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean)\r
+                */\r
                @Override\r
                public void draw(Canvas canvas, MapView mapView, boolean shadow) {\r
                        super.draw(canvas, mapView, shadow);\r
 \r
                        if (!shadow) {\r
-                               Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);\r
-                               paint.setStyle(Paint.Style.STROKE);\r
-                               paint.setAntiAlias(true);\r
-                               paint.setStrokeWidth(3);\r
-                               paint.setColor(Color.YELLOW);\r
-\r
                                Path path = new Path();\r
                                Projection projection = mapView.getProjection();\r
                                Point pxStart = projection.toPixels(m_start, null);\r
@@ -73,39 +129,192 @@ public class MapMode extends MapActivity {
                                path.moveTo(pxStart.x, pxStart.y);\r
                                path.lineTo(pxEnd.x, pxEnd.y);\r
 \r
-                               canvas.drawPath(path, paint);\r
+                               canvas.drawPath(path, m_routePaint);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * The Class TextOverlay.\r
+        */\r
+       public class TextOverlay extends Overlay {\r
+\r
+               /** The m_text. */\r
+               private String m_text;\r
+               \r
+               /** The m_point. */\r
+               private GeoPoint m_point;\r
+\r
+               /**\r
+                * Instantiates a new text overlay.\r
+                * \r
+                * @param point the point\r
+                * @param text the text\r
+                */\r
+               public TextOverlay(GeoPoint point, String text) {\r
+                       m_point = point;\r
+                       m_text = text;\r
+               }\r
+\r
+               /* (non-Javadoc)\r
+                * @see com.google.android.maps.Overlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean)\r
+                */\r
+               @Override\r
+               public void draw(Canvas canvas, MapView mapView, boolean shadow) {\r
+                       super.draw(canvas, mapView, shadow);\r
+\r
+                       if (!shadow) {\r
+                               Projection projection = mapView.getProjection();\r
+                               Point pt = projection.toPixels(m_point, null);\r
+\r
+                               drawBalloon(canvas, pt);\r
+                       }\r
+               }\r
+\r
+               /**\r
+                * Draw balloon.\r
+                * \r
+                * @param canvas the canvas\r
+                * @param pt the pt\r
+                */\r
+               private void drawBalloon(Canvas canvas, Point pt) {\r
+                       float textWidth = m_textPaint.measureText(m_text);\r
+                       float textX = pt.x - textWidth / 2;\r
+\r
+                       FontMetrics fontMetrics = m_textPaint.getFontMetrics();\r
+                       float textY = pt.y - (fontMetrics.ascent + fontMetrics.descent) / 2;\r
+\r
+                       float margin = 5;\r
+                       float balloonStartX = textX - margin;\r
+                       float balloonEndX = textX + textWidth + margin;\r
+                       float balloonStartY = textY + fontMetrics.ascent - margin;\r
+                       float balloonEndY = textY + fontMetrics.descent + margin;\r
+\r
+                       RectF infoRect = new RectF(balloonStartX, balloonStartY,\r
+                                       balloonEndX, balloonEndY);\r
+\r
+                       final float radius = 5;\r
+                       canvas.drawRoundRect(infoRect, radius, radius, m_infoPaint);\r
+\r
+                       float balloonCenterX = (balloonStartX + balloonEndX) / 2;\r
+\r
+                       // ポイントを指す三角形を描画\r
+                       // int triangleWidth = (int) textX / 2;\r
+                       int triangleWidth = (int) textWidth / 2;\r
+                       int triangleHeight = triangleWidth / 2;\r
+\r
+                       // 三角形の頂点を表わすポイントの生成\r
+                       Point point = new Point((int) balloonCenterX - triangleWidth / 2,\r
+                                       (int) balloonEndY);\r
+                       Point[] cornerPoint = new Point[3];\r
+                       cornerPoint[0] = new Point(0, 0);\r
+                       cornerPoint[1] = new Point(triangleWidth, 0);\r
+                       cornerPoint[2] = new Point(triangleWidth / 2, triangleHeight);\r
+\r
+                       drawShape(canvas, point, cornerPoint, m_infoPaint.getColor());\r
+\r
+                       canvas.drawText(m_text, textX, textY, m_textPaint);\r
+\r
+               }\r
+\r
+               /**\r
+                * 多角形の描画.\r
+                * \r
+                * @param canvas the canvas\r
+                * @param point 描画位置\r
+                * @param corners 描画する頂点を表わすポイント\r
+                * @param color 描画色\r
+                */\r
+               private void drawShape(Canvas canvas, Point point, Point[] corners,\r
+                               int color) {\r
+                       float maxWidth = 0;\r
+                       float maxHeight = 0;\r
+\r
+                       // Pointを結ぶ頂点のパス作成\r
+                       Path path = new Path();\r
+                       for (int cornerCnt = 0; cornerCnt < corners.length; cornerCnt++) {\r
+                               int x = corners[cornerCnt].x;\r
+                               int y = corners[cornerCnt].y;\r
+                               // はじめの頂点はmoveTo\r
+                               if (cornerCnt == 0) {\r
+                                       path.moveTo(x, y);\r
+                               } else {\r
+                                       path.lineTo(x, y);\r
+                               }\r
+\r
+                               if (maxWidth < x) {\r
+                                       maxWidth = x;\r
+                               }\r
+                               if (maxHeight < y) {\r
+                                       maxHeight = y;\r
+                               }\r
                        }\r
+                       // パスを閉じる\r
+                       path.close();\r
+\r
+                       ShapeDrawable drawable = new ShapeDrawable(new PathShape(path,\r
+                                       maxWidth, maxHeight));\r
+                       drawable.getPaint().setColor(color);\r
+                       drawable.setBounds(point.x, point.y, point.x + (int) maxWidth,\r
+                                       point.y + (int) maxHeight);\r
+                       drawable.draw(canvas);\r
                }\r
        }\r
 \r
+       /**\r
+        * The Class SplitPoints.\r
+        */\r
        private class SplitPoints extends ItemizedOverlay<OverlayItem> {\r
 \r
+               /** The m_splitpoints. */\r
                private ArrayList<OverlayItem> m_splitpoints = new ArrayList<OverlayItem>();\r
 \r
+               /**\r
+                * Instantiates a new split points.\r
+                * \r
+                * @param defaultMarker the default marker\r
+                */\r
                public SplitPoints(Drawable defaultMarker) {\r
                        super(boundCenterBottom(defaultMarker));\r
                }\r
 \r
+               /**\r
+                * Adds the splitpoint.\r
+                * \r
+                * @param overlay the overlay\r
+                */\r
                public void addSplitpoint(OverlayItem overlay) {\r
                        m_splitpoints.add(overlay);\r
                        populate();\r
                }\r
 \r
+               /* (non-Javadoc)\r
+                * @see com.google.android.maps.ItemizedOverlay#createItem(int)\r
+                */\r
                @Override\r
                protected OverlayItem createItem(int idx) {\r
-//                     Log.d(this.getClass().getName(), "createItem(): index: " + idx);\r
+                       // Log.d(this.getClass().getName(), "createItem(): index: " + idx);\r
                        return m_splitpoints.get(idx);\r
                }\r
 \r
+               /**\r
+                * Clear item.\r
+                */\r
                public void clearItem() {\r
                        m_splitpoints.clear();\r
                }\r
-               \r
+\r
+               /* (non-Javadoc)\r
+                * @see com.google.android.maps.ItemizedOverlay#size()\r
+                */\r
                @Override\r
                public int size() {\r
                        return m_splitpoints.size();\r
                }\r
 \r
+               /* (non-Javadoc)\r
+                * @see com.google.android.maps.ItemizedOverlay#onTap(int)\r
+                */\r
                @Override\r
                protected boolean onTap(int i) {\r
                        Log.d(this.getClass().getName(), "onTap(): index: " + i);\r
@@ -116,13 +325,16 @@ public class MapMode extends MapActivity {
                        return true;\r
                }\r
 \r
+               /* (non-Javadoc)\r
+                * @see com.google.android.maps.ItemizedOverlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean)\r
+                */\r
                public void draw(Canvas canvas, MapView mapview, boolean shadow) {\r
                        super.draw(canvas, mapview, shadow);\r
 \r
                }\r
        }\r
 \r
-\r
+       /** The m_running record receiver. */\r
        private BroadcastReceiver m_runningRecordReceiver = new BroadcastReceiver() {\r
                @Override\r
                public void onReceive(Context context, Intent intent) {\r
@@ -136,7 +348,7 @@ public class MapMode extends MapActivity {
                                        ExLog.put("No record: " + recordDate);\r
                                        return;\r
                                }\r
-                               \r
+\r
                                GeoPoint gp = new GeoPoint(rec.getLatitudeE6(), rec\r
                                                .getLongitudeE6());\r
                                m_controller.animateTo(gp);\r
@@ -148,7 +360,9 @@ public class MapMode extends MapActivity {
                                }\r
                                // Split point\r
                                if (rec.getName().length() > 0) {\r
-                                       drawSplitPoint(gp, rec.getName(), rec.getDate());\r
+                                       //drawSplitPoint(gp, rec.getName(), rec.getDate());\r
+                                       TextOverlay textOverlay = new TextOverlay(gp, rec.getName());\r
+                                       m_mapOverlays.add(textOverlay);\r
                                }\r
                                m_prevPoint = gp;\r
                        }\r
@@ -156,11 +370,17 @@ public class MapMode extends MapActivity {
                }\r
        };\r
 \r
+       /* (non-Javadoc)\r
+        * @see com.google.android.maps.MapActivity#isRouteDisplayed()\r
+        */\r
        @Override\r
        protected boolean isRouteDisplayed() {\r
                return false;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see com.google.android.maps.MapActivity#onResume()\r
+        */\r
        @Override\r
        public void onResume() {\r
                super.onResume();\r
@@ -176,9 +396,11 @@ public class MapMode extends MapActivity {
                        drawOverlays(mapView);\r
                }\r
 \r
-\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see com.google.android.maps.MapActivity#onPause()\r
+        */\r
        @Override\r
        public void onPause() {\r
                super.onPause();\r
@@ -186,6 +408,9 @@ public class MapMode extends MapActivity {
                unregisterReceiver(m_runningRecordReceiver);\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see com.google.android.maps.MapActivity#onCreate(android.os.Bundle)\r
+        */\r
        @Override\r
        public void onCreate(Bundle savedInstanceState) {\r
                super.onCreate(savedInstanceState);\r
@@ -205,20 +430,27 @@ public class MapMode extends MapActivity {
 \r
                long time1 = System.currentTimeMillis();\r
                drawOverlays(mapView);\r
-               Log.d(this.getClass().getName(), "drawOverlays() -- " + (System.currentTimeMillis() - time1));\r
+               Log.d(this.getClass().getName(), "drawOverlays() -- "\r
+                               + (System.currentTimeMillis() - time1));\r
        }\r
-       \r
+\r
+       /**\r
+        * Draw overlays.\r
+        * \r
+        * @param mapView the map view\r
+        */\r
        private void drawOverlays(MapView mapView) {\r
-               \r
+\r
                m_mapOverlays.clear();\r
-               \r
-               MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView);\r
+\r
+               MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this,\r
+                               mapView);\r
                myLocationOverlay.enableMyLocation();\r
 \r
                m_mapOverlays.add(myLocationOverlay);\r
 \r
                m_overlaySplitpoints.clearItem();\r
-               \r
+\r
                Iterator<Record> it = TokyoRunners.getRecordIterator();\r
                while (it.hasNext()) {\r
                        Record rec = it.next();\r
@@ -232,18 +464,28 @@ public class MapMode extends MapActivity {
                                m_prevPoint = gp;\r
 \r
                                if (rec.getName().length() > 0) {\r
-                                       drawSplitPoint(gp, rec.getName(), rec.getDate());\r
+                                       TextOverlay textOverlay = new TextOverlay(gp, rec.getName());\r
+                                       m_mapOverlays.add(textOverlay);\r
+                                       // drawSplitPoint(gp, rec.getName(), rec.getDate());\r
                                }\r
                        }\r
                        if (m_startTime == 0) {\r
                                m_startTime = rec.getDate().getTime();\r
                        }\r
                }\r
-               \r
+\r
        }\r
 \r
+       /**\r
+        * Draw split point.\r
+        * \r
+        * @param gp the gp\r
+        * @param pointName the point name\r
+        * @param recDate the rec date\r
+        */\r
        private void drawSplitPoint(GeoPoint gp, String pointName, Date recDate) {\r
-               String snippet = pointName + "[" + m_timeFormatter.format(recDate) + "]";\r
+               String snippet = pointName + "[" + m_timeFormatter.format(recDate)\r
+                               + "]";\r
                OverlayItem ovItem = new OverlayItem(gp, "", snippet);\r
                m_overlaySplitpoints.addSplitpoint(ovItem);\r
                if (m_overlaySplitpoints.size() == 1) {\r
@@ -251,6 +493,9 @@ public class MapMode extends MapActivity {
                }\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)\r
+        */\r
        public boolean onKeyDown(int keyCode, KeyEvent event) {\r
                if (keyCode == KeyEvent.KEYCODE_BACK) {\r
                        showDialog(Constants.DIALOG_EXIT_ID);\r
@@ -261,6 +506,9 @@ public class MapMode extends MapActivity {
 \r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.app.Activity#onCreateDialog(int)\r
+        */\r
        @Override\r
        public Dialog onCreateDialog(int id) {\r
 \r
@@ -296,6 +544,9 @@ public class MapMode extends MapActivity {
                return alertDialog;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)\r
+        */\r
        @Override\r
        public boolean onOptionsItemSelected(MenuItem item) {\r
                Intent intent;\r
index 681ddd0..0879575 100644 (file)
@@ -4,34 +4,89 @@ import java.util.Date;
 
 import android.location.Location;
 
+// TODO: Auto-generated Javadoc
+/**
+ * The Class Record.
+ */
 public class Record {
-       private Date m_date;
+       
+       /** The m_time. */
+       private long m_time;
+       
+       /** The m_location. */
        private Location m_location;
+       
+       /** The m_name. */
        private String m_name;
+       
+       /** The m_distance. */
        private float m_distance;
        
-       Record(Date date, Location loc, float distance, String name) {
-               m_date = date;
+       /**
+        * Instantiates a new record.
+        * 
+        * @param recTime the rec time
+        * @param loc the loc
+        * @param distance the distance
+        * @param name the name
+        */
+       Record(long recTime, Location loc, float distance, String name) {
+               m_time = recTime;
                m_location = loc;
                m_distance = distance;
                m_name = name;
        }
+       
+       /**
+        * Checks for location.
+        * 
+        * @return true, if successful
+        */
        public boolean hasLocation() {
                return (m_location != null)? true: false;
        }
+       
+       /**
+        * Gets the location.
+        * 
+        * @return the location
+        */
        public Location getLocation() {
                return m_location;
        }
+       
+       /**
+        * Gets the date.
+        * 
+        * @return the date
+        */
        public Date getDate() {
-               return m_date;
+               return new Date(m_time);
        }
+       
+       /**
+        * Gets the time.
+        * 
+        * @return the time
+        */
        public long getTime() {
-               return m_date.getTime();
+               return m_time;
        }
+       
+       /**
+        * Gets the distance.
+        * 
+        * @return the distance
+        */
        public float getDistance() {
                return m_distance;
        }
        
+       /**
+        * Gets the latitude.
+        * 
+        * @return the latitude
+        */
        public double getLatitude() {
                double retVal = 0;
                if (m_location != null) {
@@ -39,9 +94,21 @@ public class Record {
                }
                return retVal;
        }
+       
+       /**
+        * Gets the latitude e6.
+        * 
+        * @return the latitude e6
+        */
        public int getLatitudeE6() {
                return (int)(getLatitude() * 1E6);
        }
+       
+       /**
+        * Gets the longitude.
+        * 
+        * @return the longitude
+        */
        public double getLongitude() {
                double retVal = 0;
                if (m_location != null) {
@@ -49,9 +116,21 @@ public class Record {
                }
                return retVal;
        }
+       
+       /**
+        * Gets the longitude e6.
+        * 
+        * @return the longitude e6
+        */
        public int getLongitudeE6() {
                return (int)(getLongitude() * 1E6);
        }
+       
+       /**
+        * Gets the name.
+        * 
+        * @return the name
+        */
        public String getName() {
                return m_name;
        }
index cbde72b..1ac9477 100644 (file)
@@ -3,7 +3,6 @@ package net.kazhik.android.tokyorunners;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -21,128 +20,147 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.AdapterView.OnItemClickListener;
 
+/**
+ * The Class RunningHistory.
+ */
 public class RunningHistory extends ListActivity implements OnItemClickListener {
-    private SimpleDateFormat m_startTimeFormatter = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
-    private HashMap<Long, Long> m_startTimeMap = new HashMap<Long, Long>();
        
+       /** The m_start time formatter. */
+       private SimpleDateFormat m_startTimeFormatter = new SimpleDateFormat(
+                       "yyyy/MM/dd hh:mm:ss");
+       
+       /** The m_start time map. */
+       private HashMap<Integer, Long> m_startTimeMap = new HashMap<Integer, Long>();
+
+       /** The Constant MENU_DELETE_THIS. */
        private static final int MENU_DELETE_THIS = Menu.FIRST + 200;
+       
+       /** The Constant MENU_DELETE_ALL. */
        private static final int MENU_DELETE_ALL = Menu.FIRST + 201;
-       private static final int MENU_SAVE_GPX = Menu.FIRST + 202;
        
+       /** The Constant MENU_SAVE_GPX. */
+       private static final int MENU_SAVE_GPX = Menu.FIRST + 202;
+
+       /** The Constant LOGDIR. */
        private final static String LOGDIR = Environment
                        .getExternalStorageDirectory().getPath()
                        + "/tokyorunners/";
-       
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        setContentView(R.layout.history);
-
-        // 履歴データを読み込む
-        String[] columns = {
-                       RunningRecordProvider.START_TIME,
-                       RunningRecordProvider.CURRENT_TIME,
-                       RunningRecordProvider.DISTANCE};
-        String sortOrder = RunningRecordProvider.CURRENT_TIME + " desc";
-        Cursor cursor = managedQuery(RunningRecordProvider.REC_URI, columns, null, null, sortOrder);
-
-        if (cursor == null || cursor.getCount() == 0) {
-               return;
-        }
-        ArrayList<String> history = new ArrayList<String>();
-       long startTime = 0;
-       long currentTime = 0;
-       float distance = 0;
-       long prevStartTime = 0;
-        while (cursor.moveToNext()) {
-               startTime = cursor.getLong(0);
-               currentTime = cursor.getLong(1);
-               distance = (float)cursor.getLong(2);
-//             Log.d(this.getClass().getName(), "startTime:" + startTime +  "; distance:" + distance);
-               
-               if (startTime == prevStartTime) {
-                       // I need "select distinct"!
-                       continue;
-               }
-               m_startTimeMap.put(startTime / 1000 * 1000, startTime);
-               
-               prevStartTime = startTime;
-               StringBuffer rowStr = new StringBuffer();
-               rowStr.append(m_startTimeFormatter.format(new Date(startTime)));
-               rowStr.append("  ");
-
-               rowStr.append(distance / 1000);
-               rowStr.append("km"); // TODO: i18n
-               rowStr.append("  ");
-
-               long finalTime = currentTime - startTime;
-               Formatter finalTimeFormatter = new Formatter();
-               rowStr.append(finalTimeFormatter.format("%d:%02d:%02d",
-                               finalTime / 1000 / 60 / 60,
-                               finalTime / 1000 / 60 % 60,
-                               finalTime / 1000 % 60));
-               history.add(rowStr.toString());
-        }
-        ArrayAdapter<String> historyArray = new ArrayAdapter<String>(this, R.layout.runningrecord, history);
-
-        setListAdapter(historyArray);
-
-  
-        // イベントリスナを登録
-        getListView().setOnItemClickListener(this);
-        
-               getListView().setOnCreateContextMenuListener(this);
-    }
 
-       public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        ArrayAdapter<String> historyArray = (ArrayAdapter<String>)getListAdapter();
-        
-               Intent returnData = new Intent();
-               try {
-                       String[] splitStr = historyArray.getItem(position).split(" ");
-                       String dateStr = splitStr[0] + " " + splitStr[1];
-                       Date startTime = m_startTimeFormatter.parse(dateStr);
+       /* (non-Javadoc)
+        * @see android.app.Activity#onCreate(android.os.Bundle)
+        */
+       @Override
+       public void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+
+               setContentView(R.layout.history);
+
+               // 履歴データを読み込む
+               String[] columns = { RunningRecordProvider.START_TIME,
+                               RunningRecordProvider.CURRENT_TIME,
+                               RunningRecordProvider.DISTANCE };
+               String sortOrder = RunningRecordProvider.CURRENT_TIME + " desc";
+               Cursor cursor = managedQuery(RunningRecordProvider.REC_URI, columns,
+                               null, null, sortOrder);
+
+               if (cursor == null || cursor.getCount() == 0) {
+                       return;
+               }
+               ArrayList<String[]> history = new ArrayList<String[]>();
+               long startTime = 0;
+               long currentTime = 0;
+               float distance = 0;
+               long prevStartTime = 0;
+               while (cursor.moveToNext()) {
+                       startTime = cursor.getLong(0);
+                       currentTime = cursor.getLong(1);
+                       distance = (float) cursor.getLong(2);
+                       // Log.d(this.getClass().getName(), "startTime:" + startTime +
+                       // "; currentTime:" + currentTime + "; distance:" + distance);
+
+                       if (startTime == prevStartTime) {
+                               // I need "select distinct"!
+                               continue;
+                       }
+                       m_startTimeMap.put(history.size(), startTime);
+
+                       String[] hist = new String[3];
+                       prevStartTime = startTime;
+                       StringBuffer rowStr;
                        
-                       returnData.setAction(Intent.ACTION_VIEW);
-                       returnData.putExtra("startTime", m_startTimeMap.get(startTime.getTime()));
+                       rowStr = new StringBuffer();
+                       rowStr.append(m_startTimeFormatter.format(new Date(startTime)));
+                       rowStr.append("  ");
+                       hist[0] = rowStr.toString();
+
+                       rowStr = new StringBuffer();
+                       rowStr.append(distance / 1000);
+                       rowStr.append("km"); // TODO: i18n
+                       rowStr.append("  ");
+                       hist[1] = rowStr.toString();
+
+                       rowStr = new StringBuffer();
+                       long finalTime = currentTime - startTime;
+                       Formatter finalTimeFormatter = new Formatter();
+                       rowStr.append(finalTimeFormatter.format("%d:%02d:%02d",
+                                       finalTime / 1000 / 60 / 60, finalTime / 1000 / 60 % 60,
+                                       finalTime / 1000 % 60));
+                       hist[2] = rowStr.toString();
                        
-                       setResult(RESULT_OK, returnData);
-               } catch (ParseException e) {
-                       e.printStackTrace();
+                       history.add(hist);
                }
-               finish();
                
+               setListAdapter(new RunningHistoryAdapter(this, R.layout.runningrecord,
+                               history));
+
+               // イベントリスナを登録
+               getListView().setOnItemClickListener(this);
+
+               getListView().setOnCreateContextMenuListener(this);
+       }
+
+       /* (non-Javadoc)
+        * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
+        */
+       public void onItemClick(AdapterView<?> parent, View view, int position,
+                       long id) {
+               Intent returnData = new Intent();
+               long startTime = m_startTimeMap.get(position);
+
+               returnData.setAction(Intent.ACTION_VIEW);
+               returnData.putExtra("startTime", startTime);
+
+               setResult(RESULT_OK, returnData);
+               finish();
+
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
+        */
        public void onCreateContextMenu(ContextMenu menu, View v,
                        ContextMenuInfo menuInfo) {
                super.onCreateContextMenu(menu, v, menuInfo);
-        menu.add(0, MENU_DELETE_THIS, 0, R.string.contextmenu_deletethis);
+               menu.add(0, MENU_DELETE_THIS, 0, R.string.contextmenu_deletethis);
                menu.add(0, MENU_DELETE_ALL, 0, R.string.contextmenu_deleteall);
                menu.add(0, MENU_SAVE_GPX, 0, R.string.contextmenu_save_gpx);
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
+        */
        public boolean onContextItemSelected(MenuItem item) {
                AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
                                .getMenuInfo();
-               ArrayAdapter<String> historyArray = (ArrayAdapter<String>) getListAdapter();
+               RunningHistoryAdapter historyArray = (RunningHistoryAdapter) getListAdapter();
                int position = info.position;
-               String[] splitStr = historyArray.getItem(position).split(" ");
-               String dateStr = splitStr[0] + " " + splitStr[1];
                long startTime = 0;
                switch (item.getItemId()) {
                case MENU_DELETE_THIS:
-                       try {
-                               startTime = m_startTimeFormatter.parse(dateStr).getTime();
-                               startTime = m_startTimeMap.get(startTime);
-                       } catch (ParseException e) {
-                               e.printStackTrace();
-                       }
+                       startTime = m_startTimeMap.get(position);
 
                        String selection = RunningRecordProvider.START_TIME + " = ?";
                        String[] selectionArgs = { Long.toString(startTime) };
@@ -158,12 +176,7 @@ public class RunningHistory extends ListActivity implements OnItemClickListener
                        historyArray.clear();
                        break;
                case MENU_SAVE_GPX:
-                       try {
-                               startTime = m_startTimeFormatter.parse(dateStr).getTime();
-                               startTime = m_startTimeMap.get(startTime);
-                       } catch (ParseException e) {
-                               e.printStackTrace();
-                       }
+                       startTime = m_startTimeMap.get(position);
                        saveRecordAsGpxFile(startTime);
                        break;
                default:
@@ -171,7 +184,12 @@ public class RunningHistory extends ListActivity implements OnItemClickListener
                }
                return super.onContextItemSelected(item);
        }
-       
+
+       /**
+        * Save record as gpx file.
+        * 
+        * @param startTime the start time
+        */
        private void saveRecordAsGpxFile(long startTime) {
                String[] columns = { RunningRecordProvider.CURRENT_TIME,
                                RunningRecordProvider.LATITUDE,
@@ -185,10 +203,10 @@ public class RunningHistory extends ListActivity implements OnItemClickListener
                if (cursor == null) {
                        return;
                }
-               
-               SimpleDateFormat formatter = new SimpleDateFormat(
-                               "yyyy-MM-dd_HH_mm_ss");
-               String gpxFilePath = LOGDIR + formatter.format(new Date(startTime)) + ".xml";
+
+               SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss");
+               String gpxFilePath = LOGDIR + formatter.format(new Date(startTime))
+                               + ".xml";
                FileOutputStream gpxFile = null;
                OutputStreamWriter stWriter = null;
                try {
@@ -223,16 +241,15 @@ public class RunningHistory extends ListActivity implements OnItemClickListener
                                pointName = cursor.getString(cursor
                                                .getColumnIndex(RunningRecordProvider.POINT_NAME));
 
-                               stWriter.write("<trkpt lat=\"" + (((float)latitude) / 1E6)
-                                               + "\" lon=\"" + (((float)longitude) / 1E6) + "\">\n" + "<time>"
-                                               + dateFormat.format(currentTime) + "T"
+                               stWriter.write("<trkpt lat=\"" + (((float) latitude) / 1E6)
+                                               + "\" lon=\"" + (((float) longitude) / 1E6) + "\">\n"
+                                               + "<time>" + dateFormat.format(currentTime) + "T"
                                                + timeFormat.format(currentTime) + "Z</time>\n"
-                                               + "<speed>" + 0 + "</speed>\n" + "<name>"
-                                               + pointName + "</name>\n" + "<fix>none</fix>\n"
-                                               + "</trkpt>\n");
+                                               + "<speed>" + 0 + "</speed>\n" + "<name>" + pointName
+                                               + "</name>\n" + "<fix>none</fix>\n" + "</trkpt>\n");
 
                        }
-                       
+
                        stWriter.write("</trkseg>\n" + "</trk>\n" + "</gpx>\n");
                        stWriter.flush();
 
diff --git a/src/net/kazhik/android/tokyorunners/RunningHistoryAdapter.java b/src/net/kazhik/android/tokyorunners/RunningHistoryAdapter.java
new file mode 100644 (file)
index 0000000..83d353b
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * 
+ */
+package net.kazhik.android.tokyorunners;
+
+import java.util.List;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+/**
+ * @author kazhik
+ *
+ */
+public class RunningHistoryAdapter extends ArrayAdapter<String[]> {
+
+       private final LayoutInflater m_layoutInflater;
+       private final int m_resourceId;
+       private List<String[]> m_history;
+       
+       public RunningHistoryAdapter(Context context, int textViewResourceId,
+                       List<String[]> objects) {
+               super(context, textViewResourceId, objects);
+               m_resourceId = textViewResourceId;
+               m_history = objects;
+               m_layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+               
+               
+       }
+       
+       @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+               View viewHistoryRow;
+               if (convertView == null) {
+                       viewHistoryRow = m_layoutInflater.inflate(m_resourceId, parent, false);
+               } else {
+                       viewHistoryRow = convertView;
+               }
+               String[] rowdata = m_history.get(position);
+               TextView textStartTime = (TextView)viewHistoryRow.findViewById(R.id.history_starttime);
+               textStartTime.setText(rowdata[0]);
+               TextView textDistance = (TextView)viewHistoryRow.findViewById(R.id.history_distance);
+               textDistance.setText(rowdata[1]);
+               TextView textTime = (TextView)viewHistoryRow.findViewById(R.id.history_time);
+               textTime.setText(rowdata[2]);
+               
+               return viewHistoryRow;
+       }
+
+}
index 4f83081..84f9d74 100755 (executable)
@@ -13,50 +13,92 @@ import android.database.Cursor;
 import android.location.Location;\r
 import android.util.Log;\r
 \r
+// TODO: Auto-generated Javadoc\r
+/**\r
+ * The Class RunningRecord.\r
+ */\r
 public class RunningRecord {\r
+       \r
+       /** The m_record list. */\r
        private ArrayList<Record> m_recordList = new ArrayList<Record>();\r
+       \r
+       /** The m_distance. */\r
        private float m_distance = 0;\r
+       \r
+       /** The m_prev location. */\r
        private Location m_prevLocation = null;\r
+       \r
+       /** The m_split interval. */\r
        private int m_splitInterval = 0;\r
+       \r
+       /** The m_last split. */\r
        private int m_lastSplit = 0;\r
+       \r
+       /** The m_start time. */\r
        private long m_startTime = 0;\r
+       \r
+       /** The m_distance unit. */\r
        private String m_distanceUnit = "km";\r
+       \r
+       /** The m_content resolver. */\r
        private ContentResolver m_contentResolver;\r
 \r
+       /**\r
+        * Instantiates a new running record.\r
+        */\r
        public RunningRecord() {\r
                \r
        }\r
+       \r
+       /**\r
+        * Instantiates a new running record.\r
+        * \r
+        * @param contentResolver the content resolver\r
+        */\r
        public RunningRecord(ContentResolver contentResolver) {\r
                m_contentResolver = contentResolver;\r
        }\r
-       public String addRecord(Date date, Location loc, String pointName, boolean persistent) {\r
-               //Log.d(this.getClass().getName(), date.toLocaleString());\r
+       \r
+       /**\r
+        * Adds the record.\r
+        * \r
+        * @param recTime the rec time\r
+        * @param loc the loc\r
+        * @param pointName the point name\r
+        * @param persistent the persistent\r
+        * \r
+        * @return the string\r
+        */\r
+       public String addRecord(long recTime, Location loc, String pointName, boolean persistent) {\r
+//             Log.d(this.getClass().getName(), "starttime: " + m_startTime + "; currentTime: " + recTime);\r
                // これまでの走行距離を計算\r
                if (m_prevLocation != null && loc != null) {\r
-                       float distance = m_prevLocation.distanceTo(loc);\r
+//                     float distance = m_prevLocation.distanceTo(loc);\r
 //                     Log.d(this.getClass().getName(), "distance: " + distance);\r
                        m_distance += m_prevLocation.distanceTo(loc);\r
                }\r
                if (m_startTime == 0) {\r
-                       m_startTime = date.getTime();\r
+                       m_startTime = recTime;\r
                }\r
                m_prevLocation = loc;\r
                \r
-               // スプリットポイントを通過した場合     \r
-               if (m_splitInterval > 0 && m_distance > m_lastSplit + m_splitInterval && pointName.length() == 0 ) {\r
-                       pointName = getDistanceString() + m_distanceUnit;\r
+               // スプリットポイントを通過した場合\r
+               if (m_splitInterval > 0 && m_distance > m_lastSplit + m_splitInterval) {\r
+                       if (pointName.length() == 0) {\r
+                               pointName = getDistanceString() + m_distanceUnit;\r
+                       }\r
                        m_lastSplit += m_splitInterval;\r
                }\r
                \r
                // リストに記録を保持\r
-               Record newRecord = new Record(date, loc, m_distance, pointName);\r
+               Record newRecord = new Record(recTime, loc, m_distance, pointName);\r
                m_recordList.add(newRecord);\r
                \r
                // データベースに記録を保存\r
                if (persistent) {\r
                ContentValues values = new ContentValues();\r
                values.put(RunningRecordProvider.START_TIME, m_startTime);\r
-               values.put(RunningRecordProvider.CURRENT_TIME, date.getTime());\r
+               values.put(RunningRecordProvider.CURRENT_TIME, recTime);\r
                values.put(RunningRecordProvider.POINT_NAME, pointName);\r
                values.put(RunningRecordProvider.DISTANCE, (int)m_distance);\r
                values.put(RunningRecordProvider.LATITUDE, newRecord.getLatitudeE6());\r
@@ -73,14 +115,33 @@ public class RunningRecord {
                return pointName;\r
                \r
        }\r
-       public String addRecord(Date date, Location loc, String pointName) {\r
-               return addRecord(date, loc, pointName, true);\r
+       \r
+       /**\r
+        * Adds the record.\r
+        * \r
+        * @param recTime the rec time\r
+        * @param loc the loc\r
+        * @param pointName the point name\r
+        * \r
+        * @return the string\r
+        */\r
+       public String addRecord(long recTime, Location loc, String pointName) {\r
+               return addRecord(recTime, loc, pointName, true);\r
        }\r
+       \r
+       /**\r
+        * Gets the prev location.\r
+        * \r
+        * @return the prev location\r
+        */\r
        public Location getPrevLocation() {\r
                return m_prevLocation;\r
        }\r
                \r
        \r
+       /**\r
+        * Clear record.\r
+        */\r
        public void clearRecord() {\r
                m_distance = 0;\r
                m_lastSplit = 0;\r
@@ -89,6 +150,13 @@ public class RunningRecord {
                m_recordList.clear();\r
        }\r
        \r
+       /**\r
+        * Gets the record.\r
+        * \r
+        * @param date the date\r
+        * \r
+        * @return the record\r
+        */\r
        public Record getRecord(Date date) {\r
                Record rec = null;\r
                \r
@@ -102,10 +170,23 @@ public class RunningRecord {
                \r
                return null;\r
        }\r
+       \r
+       /**\r
+        * Gets the iterator.\r
+        * \r
+        * @return the iterator\r
+        */\r
        public Iterator<Record> getIterator() {\r
                return m_recordList.iterator();\r
        }\r
        \r
+       /**\r
+        * Gets the next record.\r
+        * \r
+        * @param date the date\r
+        * \r
+        * @return the next record\r
+        */\r
        public Record getNextRecord(Date date) {\r
                Record rec = null;\r
                \r
@@ -120,10 +201,20 @@ public class RunningRecord {
                return null;\r
        }\r
        \r
+       /**\r
+        * Sets the split interval.\r
+        * \r
+        * @param interval the new split interval\r
+        */\r
        public void setSplitInterval(int interval) {\r
                m_splitInterval = interval * 1000;\r
        }\r
 \r
+       /**\r
+        * Gets the distance string.\r
+        * \r
+        * @return the distance string\r
+        */\r
        public String getDistanceString() {\r
                // メートル以下を切り捨ててからキロメートルに変換\r
                int distance_m = (int)m_distance;\r
@@ -131,10 +222,22 @@ public class RunningRecord {
        }\r
        \r
 \r
+       /**\r
+        * Gets the distance unit.\r
+        * \r
+        * @return the distance unit\r
+        */\r
        public String getDistanceUnit() {\r
                return m_distanceUnit;\r
        }\r
        \r
+       /**\r
+        * Save.\r
+        * \r
+        * @param stWriter the st writer\r
+        * \r
+        * @throws IOException Signals that an I/O exception has occurred.\r
+        */\r
        public void save(OutputStreamWriter stWriter) throws IOException {\r
                stWriter.write(\r
                        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +\r
@@ -150,7 +253,7 @@ public class RunningRecord {
                        "<trkseg>\n");\r
                \r
 \r
-           SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");           \r
+           SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");   \r
            SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");             \r
 \r
                for (Iterator<Record> it = m_recordList.iterator(); it.hasNext();) {\r
@@ -175,6 +278,10 @@ public class RunningRecord {
                \r
                \r
        }\r
+       \r
+       /**\r
+        * Save.\r
+        */\r
        public void save() {\r
        \r
                if (saved(m_startTime) == true) {\r
@@ -199,6 +306,13 @@ public class RunningRecord {
                }\r
        }\r
 \r
+       /**\r
+        * Saved.\r
+        * \r
+        * @param startTime the start time\r
+        * \r
+        * @return true, if successful\r
+        */\r
        private boolean saved(long startTime) {\r
                String[] columns = { RunningRecordProvider.CURRENT_TIME };\r
                String selection = RunningRecordProvider.START_TIME + " = ?";\r
index cd33cae..d7187b0 100755 (executable)
@@ -11,30 +11,71 @@ import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;\r
 import android.provider.BaseColumns;\r
 \r
+// TODO: Auto-generated Javadoc\r
+/**\r
+ * The Class RunningRecordProvider.\r
+ */\r
 public class RunningRecordProvider extends ContentProvider {\r
 \r
+       /** The Constant DB_NAME. */\r
        public static final String DB_NAME = "tokyorunners.db";\r
+       \r
+       /** The Constant TABLE_NAME. */\r
        public static final String TABLE_NAME = "running_record";\r
        \r
+       /** The Constant START_TIME. */\r
        public static final String START_TIME = "start_datetime";\r
+       \r
+       /** The Constant CURRENT_TIME. */\r
        public static final String CURRENT_TIME = "current_datetime";\r
+       \r
+       /** The Constant POINT_NAME. */\r
        public static final String POINT_NAME = "point_name";\r
+       \r
+       /** The Constant DISTANCE. */\r
        public static final String DISTANCE = "distance";\r
+       \r
+       /** The Constant LATITUDE. */\r
        public static final String LATITUDE = "latitude";\r
+       \r
+       /** The Constant LONGITUDE. */\r
        public static final String LONGITUDE = "longitude";\r
        \r
+    /** The Constant AUTHORITY. */\r
     private static final String AUTHORITY = "net.kazhik.android.tokyorunners.runningrecordprovider";\r
+    \r
+    /** The Constant REC_PATH. */\r
     private static final String REC_PATH = "runningrecords";\r
+    \r
+    /** The Constant REC_URI. */\r
     public static final Uri REC_URI = Uri.parse("content://" + AUTHORITY + "/" + REC_PATH);\r
+    \r
+    /** The Constant RUNNING_RECORDS. */\r
     private static final int RUNNING_RECORDS = 1;\r
+    \r
+    /** The m_database helper. */\r
     private DatabaseHelper m_databaseHelper;\r
+    \r
+    /** The m_uri matcher. */\r
     private UriMatcher m_uriMatcher;\r
 \r
+    /**\r
+     * The Class DatabaseHelper.\r
+     */\r
     private static class DatabaseHelper extends SQLiteOpenHelper {\r
+        \r
+        /**\r
+         * Instantiates a new database helper.\r
+         * \r
+         * @param context the context\r
+         */\r
         DatabaseHelper(Context context) {\r
             super(context, DB_NAME, null, 1);\r
         }\r
 \r
+        /* (non-Javadoc)\r
+         * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)\r
+         */\r
         @Override\r
         public void onCreate(SQLiteDatabase db) {\r
             db.execSQL("CREATE TABLE " + TABLE_NAME + " ("\r
@@ -47,6 +88,9 @@ public class RunningRecordProvider extends ContentProvider {
                        + LONGITUDE + " INTEGER);");\r
         }\r
 \r
+        /* (non-Javadoc)\r
+         * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)\r
+         */\r
         @Override\r
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
             db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);\r
@@ -56,6 +100,9 @@ public class RunningRecordProvider extends ContentProvider {
     }\r
     \r
 \r
+       /* (non-Javadoc)\r
+        * @see android.content.ContentProvider#onCreate()\r
+        */\r
        @Override\r
        public boolean onCreate() {\r
         m_databaseHelper = new DatabaseHelper(getContext());\r
@@ -64,6 +111,9 @@ public class RunningRecordProvider extends ContentProvider {
         return true;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.content.ContentProvider#query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)\r
+        */\r
        @Override\r
        public Cursor query(Uri uri, String[] projection, String selection,\r
                        String[] selectionArgs, String sortOrder) {\r
@@ -75,6 +125,9 @@ public class RunningRecordProvider extends ContentProvider {
         return c;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.content.ContentProvider#insert(android.net.Uri, android.content.ContentValues)\r
+        */\r
        @Override\r
        public Uri insert(Uri uri, ContentValues values) {\r
                if (m_uriMatcher.match(uri) != RUNNING_RECORDS) {\r
@@ -85,6 +138,9 @@ public class RunningRecordProvider extends ContentProvider {
                return null;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.content.ContentProvider#update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[])\r
+        */\r
        @Override\r
        public int update(Uri uri, ContentValues values, String selection,\r
                        String[] selectionArgs) {\r
@@ -100,6 +156,10 @@ public class RunningRecordProvider extends ContentProvider {
 \r
                return updateCount;\r
        }\r
+       \r
+       /* (non-Javadoc)\r
+        * @see android.content.ContentProvider#delete(android.net.Uri, java.lang.String, java.lang.String[])\r
+        */\r
        @Override\r
        public int delete(Uri uri, String selection, String[] selectionArgs) {\r
                SQLiteDatabase db = m_databaseHelper.getWritableDatabase();\r
@@ -115,6 +175,9 @@ public class RunningRecordProvider extends ContentProvider {
                return deleteCount;\r
        }\r
 \r
+       /* (non-Javadoc)\r
+        * @see android.content.ContentProvider#getType(android.net.Uri)\r
+        */\r
        @Override\r
        public String getType(Uri uri) {\r
                return null;\r
index a031028..bd1e3d9 100755 (executable)
@@ -1,8 +1,13 @@
 package net.kazhik.android.tokyorunners;
 
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Iterator;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserFactory;
+
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.TabActivity;
@@ -19,6 +24,7 @@ import android.media.AudioManager;
 import android.media.ToneGenerator;
 import android.os.Bundle;
 import android.os.Debug;
+import android.os.Handler;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.text.format.DateUtils;
@@ -35,23 +41,52 @@ import android.widget.Chronometer;
 import android.widget.ListView;
 import android.widget.TabHost;
 import android.widget.TextView;
+import android.widget.Toast;
 
+// TODO: Auto-generated Javadoc
+/**
+ * The Class TokyoRunners.
+ */
 public class TokyoRunners extends TabActivity implements LocationListener {
 
+       /** The m_prefs. */
        private SharedPreferences m_prefs;
-       private LocationManager m_locMgr;
+       
+       /** The m_loc mgr. */
+       private LocationManager m_locMgr = null;
+       
+       /** The m_elapsed time. */
        private Chronometer m_elapsedTime;
+       
+       /** The m_lap time. */
        private Chronometer m_lapTime;
+       
+       /** The m_running. */
        private boolean m_running = false;
 
+       /** The m_use gps. */
        private boolean m_useGPS = false;
+       
+       /** The m_autosplit. */
        private boolean m_autosplit = false;
 
+    /** The m_handler. */
+    private Handler m_handler = new Handler();
+    
+       /** The m_running record. */
        private static RunningRecord m_runningRecord;
-       
+
+       /** The Constant m_minAccuracy. */
        private static final int m_minAccuracy = 200;
 
+       /**
+        * The Class StartStopButton.
+        */
        class StartStopButton implements OnClickListener {
+               
+               /* (non-Javadoc)
+                * @see android.view.View.OnClickListener#onClick(android.view.View)
+                */
                public void onClick(View v) {
                        if (m_running == true) {
                                stop();
@@ -61,7 +96,14 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                }
        };
 
+       /**
+        * The Class ResetLapButton.
+        */
        class ResetLapButton implements OnClickListener {
+               
+               /* (non-Javadoc)
+                * @see android.view.View.OnClickListener#onClick(android.view.View)
+                */
                public void onClick(View v) {
                        if (m_running == true) {
                                lap();
@@ -71,7 +113,11 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                }
        };
 
-       /** Called when the activity is first created. */
+       /**
+        * Called when the activity is first created.
+        * 
+        * @param savedInstanceState the saved instance state
+        */
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
@@ -112,20 +158,7 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                // GPS設定
                m_useGPS = m_prefs.getBoolean("use_gps", true);
                if (m_useGPS) {
-                       m_locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
-
-                       String strGpsFreq = m_prefs.getString("gps_frequency", "0");
-                       int gps_freq = Integer.parseInt(strGpsFreq);
-                       m_locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
-                                       gps_freq * 1000, 5, this);
-
-                       m_autosplit = m_prefs.getBoolean("auto_split", false);
-                       if (m_autosplit) {
-                               int interval = Integer.parseInt(m_prefs.getString(
-                                               "split_interval", "5"));
-                               m_runningRecord.setSplitInterval(interval);
-                       }
-
+                       initGps();
                }
 
                // タイム表示
@@ -149,6 +182,29 @@ public class TokyoRunners extends TabActivity implements LocationListener {
 
        }
 
+       /**
+        * Inits the gps.
+        */
+       private void initGps() {
+               m_locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+
+               String strGpsFreq = m_prefs.getString("gps_frequency", "0");
+               int gps_freq = Integer.parseInt(strGpsFreq);
+               m_locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+                               gps_freq * 1000, 5, this);
+
+               m_autosplit = m_prefs.getBoolean("auto_split", false);
+               if (m_autosplit) {
+                       int interval = Integer.parseInt(m_prefs.getString("split_interval",
+                                       "5"));
+                       m_runningRecord.setSplitInterval(interval);
+               }
+
+       }
+
+       /* (non-Javadoc)
+        * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
+        */
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
@@ -156,7 +212,13 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                switch (requestCode) {
                case Constants.REQUEST_CODE_SETTINGS:
                        m_useGPS = m_prefs.getBoolean("use_gps", true);
-                       m_autosplit = m_prefs.getBoolean("auto_split", false);
+                       if (m_useGPS) {
+                               initGps();
+                       } else {
+                               if (m_locMgr != null) {
+                                       m_locMgr.removeUpdates(this);
+                               }
+                       }
                        break;
                case Constants.REQUEST_CODE_HISTORY:
                        if (data != null) {
@@ -167,6 +229,109 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                }
        }
 
+    /**
+     * Read gpx file.
+     * 
+     * @param filename the filename
+     */
+    private void readGpxFile(String filename) {
+
+        XmlPullParserFactory pullMaker;
+        try {
+            pullMaker = XmlPullParserFactory.newInstance();
+
+            XmlPullParser parser = pullMaker.newPullParser();
+            InputStream fis = getAssets().open(filename);
+
+            parser.setInput(fis, null);
+
+            // state flags
+            boolean inTrackPoint = false;
+            boolean inElevation = false;
+            boolean inName = false;
+            boolean inTime = false;
+            Location loc = null;
+            long currentTime = 0;
+            String pointName = null;
+            SimpleDateFormat timeFormatter = new SimpleDateFormat("y'-'M'-'d'T'H':'m':'s'Z'");
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.END_DOCUMENT) {
+                switch (eventType) {
+                case XmlPullParser.START_DOCUMENT:
+                    break;
+                case XmlPullParser.START_TAG:
+                    if (parser.getName().compareTo("trkpt") == 0) {
+
+                        // now get the lat and lon
+                        String lat = parser.getAttributeValue(null, "lat");
+                        String lon = parser.getAttributeValue(null, "lon");
+
+                        loc = new Location(LocationManager.GPS_PROVIDER);
+                               loc.setLatitude(Double.parseDouble(lat));
+                               loc.setLongitude(Double.parseDouble(lon));
+
+                        inTrackPoint = true;
+                    } else if (parser.getName().compareTo("ele") == 0) {
+                        if (inTrackPoint) {
+                            inElevation = true;
+                        }
+                    } else if (parser.getName().compareTo("name") == 0) {
+                        if (inTrackPoint) {
+                            inName = true;
+                        }
+                    } else if (parser.getName().compareTo("time") == 0) {
+                        if (inTrackPoint) {
+                            inTime = true;
+                        }
+                    }
+                    break;
+                case XmlPullParser.END_TAG:
+                    if (parser.getName().equals("trkpt")) {
+                        inTrackPoint = false;
+                               m_runningRecord.addRecord(currentTime, loc, pointName, false);
+
+                        loc = null;
+
+                    } else if (parser.getName().equals("ele")) {
+                        inElevation = false;
+                    } else if (parser.getName().equals("name")) {
+                        inName = false;
+                    } else if (parser.getName().equals("time")) {
+                        inTime = false;
+                    }
+                    break;
+                case XmlPullParser.TEXT:
+                    if (inTrackPoint) {
+                        if (inElevation) {
+                        } else if (inName) {
+                               pointName = parser.getText();
+                        } else if (inTime) {
+                               String timeStr = parser.getText();
+                            currentTime = timeFormatter.parse(timeStr).getTime();
+                        }
+                    }
+                    break;
+
+                }
+                eventType = parser.next();
+            }
+
+        } catch (Exception e) {
+            Log.e("xml_perf", "Pull parser failed", e);
+        }
+        m_handler.post(new Runnable() {
+            public void run() {
+                Toast.makeText(getApplicationContext(), "Finished XmlPull parsing", Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+       
+       /**
+        * Read history.
+        * 
+        * @param startTime the start time
+        */
        private void readHistory(long startTime) {
 
                String[] columns = { RunningRecordProvider.CURRENT_TIME,
@@ -181,14 +346,12 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                if (cursor == null) {
                        return;
                }
-               
+
                Log.d(this.getClass().getName(), "row count:" + cursor.getCount());
 
                reset();
-               
-               ListView listLaptime = (ListView) findViewById(R.id.lap_history);
-               ArrayAdapter<String> lapHistory = (ArrayAdapter<String>) listLaptime
-                               .getAdapter();
+
+               ArrayAdapter<String> lapHistory = getLapHistoryAdapter();
 
                long currentTime = 0;
                int latitude = 0;
@@ -200,27 +363,31 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                TextView lapTimeView = (TextView) findViewById(R.id.lap_time);
                TextView distanceView = (TextView) findViewById(R.id.distance);
 
+               int idxCurrentTime = cursor
+                               .getColumnIndex(RunningRecordProvider.CURRENT_TIME);
+               int idxLatitude = cursor.getColumnIndex(RunningRecordProvider.LATITUDE);
+               int idxLongitude = cursor
+                               .getColumnIndex(RunningRecordProvider.LONGITUDE);
+               int idxPointName = cursor
+                               .getColumnIndex(RunningRecordProvider.POINT_NAME);
+
                while (cursor.moveToNext()) {
-                       currentTime = cursor.getLong(cursor
-                                       .getColumnIndex(RunningRecordProvider.CURRENT_TIME));
-                       latitude = cursor.getInt(cursor
-                                       .getColumnIndex(RunningRecordProvider.LATITUDE));
-                       longitude = cursor.getInt(cursor
-                                       .getColumnIndex(RunningRecordProvider.LONGITUDE));
-                       pointName = cursor.getString(cursor
-                                       .getColumnIndex(RunningRecordProvider.POINT_NAME));
+                       currentTime = cursor.getLong(idxCurrentTime);
+                       latitude = cursor.getInt(idxLatitude);
+                       longitude = cursor.getInt(idxLongitude);
+                       pointName = cursor.getString(idxPointName);
 
                        // Laptime History
                        Location loc = null;
-                       
+
                        if (latitude != 0 && longitude != 0) {
                                loc = new Location(LocationManager.GPS_PROVIDER);
 
                                loc.setLatitude((double) (latitude / 1E6));
                                loc.setLongitude((double) (longitude / 1E6));
                        }
-                       m_runningRecord.addRecord(new Date(currentTime), loc, pointName, false);
-                       
+                       m_runningRecord.addRecord(currentTime, loc, pointName, false);
+
                        if (pointName.length() == 0) {
                        } else if (currentTime != startTime) {
                                StringBuffer strBuff = new StringBuffer();
@@ -245,9 +412,11 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                // Distance
                distanceView.setText(m_runningRecord.getDistanceString());
 
-       
        }
 
+       /* (non-Javadoc)
+        * @see android.app.ActivityGroup#onDestroy()
+        */
        @Override
        public void onDestroy() {
                Log.d(this.getClass().getName(), "onDestroy():");
@@ -263,6 +432,9 @@ public class TokyoRunners extends TabActivity implements LocationListener {
 
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
+        */
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                menu.add(Menu.NONE, Constants.MENU_HISTORY, Menu.NONE,
@@ -272,6 +444,10 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                                android.R.drawable.ic_menu_preferences);
                return super.onCreateOptionsMenu(menu);
        }
+
+       /* (non-Javadoc)
+        * @see android.app.Activity#onPrepareOptionsMenu(android.view.Menu)
+        */
        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {
                boolean enabled;
@@ -281,10 +457,13 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                        enabled = false;
                }
                menu.findItem(Constants.MENU_HISTORY).setEnabled(enabled);
-               
+
                return super.onPrepareOptionsMenu(menu);
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#onCreateDialog(int)
+        */
        @Override
        public Dialog onCreateDialog(int id) {
 
@@ -320,6 +499,9 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                return alertDialog;
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
+        */
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                Intent intent;
@@ -340,6 +522,9 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                return false;
        }
 
+       /* (non-Javadoc)
+        * @see android.location.LocationListener#onLocationChanged(android.location.Location)
+        */
        public void onLocationChanged(Location location) {
                ExLog.put(location.toString());
 
@@ -347,42 +532,42 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                if (m_running == false) {
                        return;
                }
-               
+
                // 音声出力でスタートを知らせる
                Location prevLocation = m_runningRecord.getPrevLocation();
                if (prevLocation == null) {
                        ToneGenerator toneGenerator = new ToneGenerator(
-                               AudioManager.STREAM_SYSTEM,
-                               ToneGenerator.MAX_VOLUME);
+                                       AudioManager.STREAM_SYSTEM, ToneGenerator.MAX_VOLUME);
                        toneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP);
                        toneGenerator.stopTone();
                }
 
-               
                // 精度が低いデータは無視
                // 移動距離が精度より小さい場合も無視
                if (location.hasAccuracy()) {
                        if (location.getAccuracy() > m_minAccuracy) {
-                               ExLog.put("Accuracy low: " + location.getAccuracy() + ";" + m_minAccuracy);
+                               ExLog.put("Accuracy low: " + location.getAccuracy() + ";"
+                                               + m_minAccuracy);
                                return;
                        }
-                       if (prevLocation != null && prevLocation.distanceTo(location) < location.getAccuracy()) {
-                               ExLog.put("Move not enough: " + location.getAccuracy() + ";" + prevLocation.distanceTo(location));
+                       if (prevLocation != null
+                                       && prevLocation.distanceTo(location) < location
+                                                       .getAccuracy()) {
+                               ExLog.put("Move not enough: " + location.getAccuracy() + ";"
+                                               + prevLocation.distanceTo(location));
                                return;
                        }
-                       
+
                }
-               
-               Date recDate = new Date(location.getTime());
-               String pointName = m_runningRecord.addRecord(recDate, location, "");
+
+               String pointName = m_runningRecord.addRecord(location.getTime(),
+                               location, "");
 
                // ラップタイム履歴
                if (pointName.length() > 0) {
                        String laptimeStr = calculateSplitAndLap();
 
-                       ListView listLaptime = (ListView) findViewById(R.id.lap_history);
-                       ArrayAdapter<String> lapHistory = (ArrayAdapter<String>) listLaptime
-                                       .getAdapter();
+                       ArrayAdapter<String> lapHistory = getLapHistoryAdapter();
 
                        String strLaptime = pointName + ": " + laptimeStr;
 
@@ -400,16 +585,25 @@ public class TokyoRunners extends TabActivity implements LocationListener {
 
        }
 
+       /* (non-Javadoc)
+        * @see android.location.LocationListener#onProviderDisabled(java.lang.String)
+        */
        public void onProviderDisabled(String provider) {
                Log.d(this.getClass().getName(), "onProviderDisabled()");
                m_locMgr.removeUpdates(this);
 
        }
 
+       /* (non-Javadoc)
+        * @see android.location.LocationListener#onProviderEnabled(java.lang.String)
+        */
        public void onProviderEnabled(String provider) {
                Log.d(this.getClass().getName(), "onProviderEnabled()");
        }
 
+       /* (non-Javadoc)
+        * @see android.location.LocationListener#onStatusChanged(java.lang.String, int, android.os.Bundle)
+        */
        public void onStatusChanged(String provider, int status, Bundle extras) {
                String statusStr = "";
                switch (status) {
@@ -430,14 +624,29 @@ public class TokyoRunners extends TabActivity implements LocationListener {
 
        }
 
+       /**
+        * Start.
+        */
        private void start() {
                reset();
                m_elapsedTime.start();
                m_lapTime.start();
 
-               Location startPoint = m_locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
-               
-               m_runningRecord.addRecord(new Date(), startPoint, "start");
+               long currentTime = System.currentTimeMillis();
+               Location startPoint = null;
+               if (m_useGPS) {
+                       startPoint = m_locMgr
+                                       .getLastKnownLocation(LocationManager.GPS_PROVIDER);
+
+                       if (Math.abs(currentTime - startPoint.getTime()) > 3 * 1000) {
+                               Log.d(this.getClass().getName(), "GPS data isn't accurate.");
+                               startPoint = null;
+                       } else {
+                               currentTime = startPoint.getTime();
+                       }
+               }
+               m_runningRecord.addRecord(currentTime, startPoint,
+                               getString(R.string.point_start));
 
                Button startStopButton = (Button) findViewById(R.id.button_start_stop);
                Button resetLapButton = (Button) findViewById(R.id.button_reset_lap);
@@ -450,10 +659,24 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                m_running = true;
        }
 
+       /**
+        * Stop.
+        */
        private void stop() {
-               Location finishPoint = m_locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
-
-               m_runningRecord.addRecord(new Date(), finishPoint, "finish");
+               long currentTime = System.currentTimeMillis();
+               Location finishPoint = null;
+               if (m_useGPS) {
+                       finishPoint = m_locMgr
+                                       .getLastKnownLocation(LocationManager.GPS_PROVIDER);
+                       if (Math.abs(System.currentTimeMillis() - finishPoint.getTime()) > 3 * 1000) {
+                               Log.d(this.getClass().getName(), "GPS data isn't accurate.");
+                               finishPoint = null;
+                       } else {
+                               currentTime = finishPoint.getTime();
+                       }
+               }
+               m_runningRecord.addRecord(currentTime, finishPoint,
+                               getString(R.string.point_finish));
 
                m_elapsedTime.stop();
                m_lapTime.stop();
@@ -470,9 +693,12 @@ public class TokyoRunners extends TabActivity implements LocationListener {
 
        }
 
+       /**
+        * Reset.
+        */
        private void reset() {
                m_runningRecord.clearRecord();
-               
+
                long elapsedRealTime = SystemClock.elapsedRealtime();
                m_elapsedTime.setBase(elapsedRealTime);
                m_lapTime.setBase(elapsedRealTime);
@@ -480,14 +706,17 @@ public class TokyoRunners extends TabActivity implements LocationListener {
                // 距離
                TextView distanceView = (TextView) findViewById(R.id.distance);
                distanceView.setText(m_runningRecord.getDistanceString());
-               
-               ListView listLaptime = (ListView) findViewById(R.id.lap_history);
-               ArrayAdapter<String> lapHistory = (ArrayAdapter<String>) listLaptime
-                               .getAdapter();
+
+               ArrayAdapter<String> lapHistory = getLapHistoryAdapter();
                lapHistory.clear();
 
        }
 
+       /**
+        * Calculate split and lap.
+        * 
+        * @return the string
+        */
        private String calculateSplitAndLap() {
                long elapsedRealTime = SystemClock.elapsedRealtime();
                long splitTimeMillis = elapsedRealTime - m_elapsedTime.getBase();
@@ -502,42 +731,81 @@ public class TokyoRunners extends TabActivity implements LocationListener {
 
        }
 
+       /**
+        * Gets the lap history adapter.
+        * 
+        * @return the lap history adapter
+        */
+       @SuppressWarnings("unchecked")
+       private ArrayAdapter<String> getLapHistoryAdapter() {
+               ListView listLaptime = (ListView) findViewById(R.id.lap_history);
+
+               return (ArrayAdapter<String>) listLaptime.getAdapter();
+
+       }
+
+       /**
+        * Lap.
+        */
        private void lap() {
                String laptimeStr = calculateSplitAndLap();
 
-               ListView listLaptime = (ListView) findViewById(R.id.lap_history);
-
-               ArrayAdapter<String> lapHistory = (ArrayAdapter<String>) listLaptime
-                               .getAdapter();
+               ArrayAdapter<String> lapHistory = getLapHistoryAdapter();
 
                String strLapNo = Integer.toString(lapHistory.getCount() + 1);
 
                lapHistory.insert(strLapNo + ": " + laptimeStr, 0);
 
-               m_runningRecord.addRecord(new Date(), null, strLapNo);
+               m_runningRecord.addRecord(System.currentTimeMillis(), null, strLapNo);
 
        }
 
+       /**
+        * Gets the record.
+        * 
+        * @param recordTime the record time
+        * 
+        * @return the record
+        */
        public static Record getRecord(long recordTime) {
 
                return m_runningRecord.getRecord(new Date(recordTime));
 
        }
 
+       /**
+        * Gets the next record.
+        * 
+        * @param recordTime the record time
+        * 
+        * @return the next record
+        */
        public static Record getNextRecord(long recordTime) {
 
                return m_runningRecord.getNextRecord(new Date(recordTime));
 
        }
+
+       /**
+        * Gets the record iterator.
+        * 
+        * @return the record iterator
+        */
        public static Iterator<Record> getRecordIterator() {
                return m_runningRecord.getIterator();
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#dispatchKeyEvent(android.view.KeyEvent)
+        */
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
                return super.dispatchKeyEvent(event);
        }
 
+       /* (non-Javadoc)
+        * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
+        */
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {