--- /dev/null
+<?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>
<?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>
+
<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>
<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>
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
*/\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
\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
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;
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;
}
+ /**
+ * 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()) {
}
}
+ /**
+ * 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));
}
--- /dev/null
+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);
+ }
+
+
+}
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
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
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
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
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
}\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
}\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
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
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
\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
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
}\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
\r
}\r
\r
+ /* (non-Javadoc)\r
+ * @see android.app.Activity#onCreateDialog(int)\r
+ */\r
@Override\r
public Dialog onCreateDialog(int id) {\r
\r
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
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) {
}
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) {
}
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;
}
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;
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) };
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:
}
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,
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 {
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();
--- /dev/null
+/**
+ *
+ */
+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;
+ }
+
+}
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
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
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
\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
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
}\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
"<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
\r
\r
}\r
+ \r
+ /**\r
+ * Save.\r
+ */\r
public void save() {\r
\r
if (saved(m_startTime) == true) {\r
}\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
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
+ 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
}\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
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
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
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
\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
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
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;
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;
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();
}
};
+ /**
+ * 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();
}
};
- /** 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);
// 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();
}
// タイム表示
}
+ /**
+ * 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);
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) {
}
}
+ /**
+ * 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,
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;
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();
// Distance
distanceView.setText(m_runningRecord.getDistanceString());
-
}
+ /* (non-Javadoc)
+ * @see android.app.ActivityGroup#onDestroy()
+ */
@Override
public void onDestroy() {
Log.d(this.getClass().getName(), "onDestroy():");
}
+ /* (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,
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;
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) {
return alertDialog;
}
+ /* (non-Javadoc)
+ * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
+ */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
return false;
}
+ /* (non-Javadoc)
+ * @see android.location.LocationListener#onLocationChanged(android.location.Location)
+ */
public void onLocationChanged(Location location) {
ExLog.put(location.toString());
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;
}
+ /* (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) {
}
+ /**
+ * 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);
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();
}
+ /**
+ * Reset.
+ */
private void reset() {
m_runningRecord.clearRecord();
-
+
long elapsedRealTime = SystemClock.elapsedRealtime();
m_elapsedTime.setBase(elapsedRealTime);
m_lapTime.setBase(elapsedRealTime);
// 距離
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();
}
+ /**
+ * 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) {