1 package net.kazhik.android.tokyorunners;
\r
3 import java.text.SimpleDateFormat;
\r
4 import java.util.ArrayList;
\r
5 import java.util.Date;
\r
6 import java.util.List;
\r
8 import android.app.AlertDialog;
\r
9 import android.app.Dialog;
\r
10 import android.content.BroadcastReceiver;
\r
11 import android.content.Context;
\r
12 import android.content.DialogInterface;
\r
13 import android.content.Intent;
\r
14 import android.content.IntentFilter;
\r
15 import android.content.SharedPreferences;
\r
16 import android.graphics.Canvas;
\r
17 import android.graphics.Color;
\r
18 import android.graphics.Paint;
\r
19 import android.graphics.Path;
\r
20 import android.graphics.Point;
\r
21 import android.graphics.drawable.Drawable;
\r
22 import android.os.Bundle;
\r
23 import android.preference.PreferenceManager;
\r
24 import android.util.Log;
\r
25 import android.view.KeyEvent;
\r
26 import android.view.Menu;
\r
27 import android.view.MenuItem;
\r
28 import android.view.View;
\r
29 import android.view.View.OnLongClickListener;
\r
30 import android.widget.Toast;
\r
32 import com.google.android.maps.GeoPoint;
\r
33 import com.google.android.maps.ItemizedOverlay;
\r
34 import com.google.android.maps.MapActivity;
\r
35 import com.google.android.maps.MapController;
\r
36 import com.google.android.maps.MapView;
\r
37 import com.google.android.maps.MyLocationOverlay;
\r
38 import com.google.android.maps.Overlay;
\r
39 import com.google.android.maps.OverlayItem;
\r
40 import com.google.android.maps.Projection;
\r
42 public class MapMode extends MapActivity {
\r
44 private MapController m_controller;
\r
45 private List<Overlay> m_mapOverlays;
\r
46 private SplitPoints m_overlaySplitpoints;
\r
47 private GeoPoint m_prevPoint = null;
\r
48 private long m_startTime = 0;
\r
50 public class RunningRoute extends Overlay {
\r
52 private GeoPoint m_start;
\r
53 private GeoPoint m_end;
\r
55 public RunningRoute(GeoPoint ptStart, GeoPoint ptEnd) {
\r
61 public void draw(Canvas canvas, MapView mapView, boolean shadow) {
\r
62 super.draw(canvas, mapView, shadow);
\r
65 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
\r
66 paint.setStyle(Paint.Style.STROKE);
\r
67 paint.setAntiAlias(true);
\r
68 paint.setStrokeWidth(3);
\r
69 paint.setColor(Color.YELLOW);
\r
71 Path path = new Path();
\r
72 Projection projection = mapView.getProjection();
\r
73 Point pxStart = projection.toPixels(m_start, null);
\r
74 Point pxEnd = projection.toPixels(m_end, null);
\r
75 path.moveTo(pxStart.x, pxStart.y);
\r
76 path.lineTo(pxEnd.x, pxEnd.y);
\r
78 canvas.drawPath(path, paint);
\r
83 private class SplitPoints extends ItemizedOverlay<OverlayItem> {
\r
85 private ArrayList<OverlayItem> m_splitpoints = new ArrayList<OverlayItem>();
\r
87 public SplitPoints(Drawable defaultMarker) {
\r
88 super(boundCenterBottom(defaultMarker));
\r
91 public void addSplitpoint(OverlayItem overlay) {
\r
92 m_splitpoints.add(overlay);
\r
97 protected OverlayItem createItem(int idx) {
\r
98 // Log.d(this.getClass().getName(), "createItem(): index: " + idx);
\r
99 return m_splitpoints.get(idx);
\r
102 public void clearItem() {
\r
103 m_splitpoints.clear();
\r
107 public int size() {
\r
108 return m_splitpoints.size();
\r
112 protected boolean onTap(int i) {
\r
113 Log.d(this.getClass().getName(), "onTap(): index: " + i);
\r
114 if (m_splitpoints.size() > 0) {
\r
115 Toast.makeText(MapMode.this, m_splitpoints.get(i).getSnippet(),
\r
116 Toast.LENGTH_LONG).show();
\r
121 public void draw(Canvas canvas, MapView mapview, boolean shadow) {
\r
122 super.draw(canvas, mapview, shadow);
\r
128 private BroadcastReceiver m_runningRecordReceiver = new BroadcastReceiver() {
\r
130 public void onReceive(Context context, Intent intent) {
\r
131 String action = intent.getAction();
\r
132 if (action.equals("NewRunningRecord")) {
\r
133 long recordDate = intent.getLongExtra("RunningRecord", 0);
\r
135 Record rec = TokyoRunners.getRecord(recordDate);
\r
138 ExLog.put("No record: " + recordDate);
\r
142 GeoPoint gp = new GeoPoint(rec.getLatitudeE6(), rec
\r
143 .getLongitudeE6());
\r
144 m_controller.animateTo(gp);
\r
147 if (m_prevPoint != null) {
\r
148 RunningRoute route = new RunningRoute(m_prevPoint, gp);
\r
149 m_mapOverlays.add(route);
\r
152 if (rec.getName().length() > 0) {
\r
153 drawSplitPoint(gp, rec.getName(), rec.getDate());
\r
162 protected boolean isRouteDisplayed() {
\r
167 public void onResume() {
\r
168 Log.d(this.getClass().getName(), "onResume()");
\r
170 IntentFilter filter = new IntentFilter();
\r
171 filter.addAction("NewRunningRecord");
\r
173 registerReceiver(m_runningRecordReceiver, filter);
\r
176 Record rec = TokyoRunners.getRecord(m_startTime);
\r
178 MapView mapView = (MapView) findViewById(R.id.mapview);
\r
179 drawOverlays(mapView);
\r
186 public void onPause() {
\r
189 unregisterReceiver(m_runningRecordReceiver);
\r
193 public void onCreate(Bundle savedInstanceState) {
\r
194 super.onCreate(savedInstanceState);
\r
196 setContentView(R.layout.map);
\r
198 MapView mapView = (MapView) findViewById(R.id.mapview);
\r
199 mapView.setBuiltInZoomControls(true);
\r
201 m_controller = mapView.getController();
\r
202 m_controller.setZoom(16);
\r
204 m_mapOverlays = mapView.getOverlays();
\r
206 Drawable runner = getResources().getDrawable(R.drawable.runner);
\r
207 m_overlaySplitpoints = new SplitPoints(runner);
\r
209 drawOverlays(mapView);
\r
212 private void drawOverlays(MapView mapView) {
\r
214 m_mapOverlays.clear();
\r
216 MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView);
\r
217 myLocationOverlay.enableMyLocation();
\r
219 m_mapOverlays.add(myLocationOverlay);
\r
221 m_overlaySplitpoints.clearItem();
\r
225 while ((rec = TokyoRunners.getNextRecord(recTime)) != null) {
\r
226 if (rec.hasLocation()) {
\r
227 GeoPoint gp = new GeoPoint(rec.getLatitudeE6(), rec
\r
228 .getLongitudeE6());
\r
229 if (m_prevPoint != null) {
\r
230 RunningRoute route = new RunningRoute(m_prevPoint, gp);
\r
231 m_mapOverlays.add(route);
\r
235 if (rec.getName().length() > 0) {
\r
236 drawSplitPoint(gp, rec.getName(), rec.getDate());
\r
239 recTime = rec.getDate().getTime();
\r
240 if (m_startTime == 0) {
\r
241 m_startTime = recTime;
\r
247 private void drawSplitPoint(GeoPoint gp, String pointName, Date recDate) {
\r
248 SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
\r
249 String snippet = pointName + "[" + formatter.format(recDate) + "]";
\r
250 OverlayItem ovItem = new OverlayItem(gp, "", snippet);
\r
251 m_overlaySplitpoints.addSplitpoint(ovItem);
\r
252 if (m_overlaySplitpoints.size() == 1) {
\r
253 m_mapOverlays.add(m_overlaySplitpoints);
\r
257 public boolean onKeyDown(int keyCode, KeyEvent event) {
\r
258 Log.d(this.getClass().getName(), "onKeyDown():" + keyCode);
\r
259 if (keyCode == KeyEvent.KEYCODE_BACK) {
\r
260 showDialog(Constants.DIALOG_EXIT_ID);
\r
264 return super.onKeyDown(keyCode, event);
\r
269 public Dialog onCreateDialog(int id) {
\r
271 AlertDialog.Builder builder = new AlertDialog.Builder(this);
\r
273 case Constants.DIALOG_EXIT_ID:
\r
274 builder.setTitle(R.string.dialog_exit_title);
\r
275 builder.setMessage(R.string.dialog_exit_message);
\r
276 builder.setPositiveButton(R.string.dialog_yes,
\r
277 new DialogInterface.OnClickListener() {
\r
279 public void onClick(DialogInterface dialog, int which) {
\r
284 builder.setNegativeButton(R.string.dialog_no,
\r
285 new DialogInterface.OnClickListener() {
\r
287 public void onClick(DialogInterface dialog, int which) {
\r
298 AlertDialog alertDialog = builder.create();
\r
299 return alertDialog;
\r
303 public boolean onOptionsItemSelected(MenuItem item) {
\r
305 switch (item.getItemId()) {
\r
306 case Constants.MENU_SETTING:
\r
307 intent = new Intent(this, Config.class);
\r
308 intent.setAction(Intent.ACTION_VIEW);
\r
309 startActivity(intent);
\r