1 package net.kazhik.android.tokyorunners;
5 import android.app.Activity;
6 import android.app.AlertDialog;
7 import android.app.Dialog;
8 import android.content.ContentValues;
9 import android.content.Context;
10 import android.content.DialogInterface;
11 import android.content.Intent;
12 import android.content.SharedPreferences;
13 import android.database.Cursor;
14 import android.location.Location;
15 import android.location.LocationListener;
16 import android.location.LocationManager;
17 import android.location.LocationProvider;
18 import android.net.Uri;
19 import android.os.Bundle;
20 import android.os.SystemClock;
21 import android.preference.PreferenceManager;
22 import android.text.format.DateUtils;
23 import android.util.Log;
24 import android.view.GestureDetector;
25 import android.view.Menu;
26 import android.view.MenuItem;
27 import android.view.MotionEvent;
28 import android.view.View;
29 import android.view.WindowManager;
30 import android.view.View.OnClickListener;
31 import android.widget.ArrayAdapter;
32 import android.widget.Button;
33 import android.widget.Chronometer;
34 import android.widget.ListView;
35 import android.widget.TextView;
37 public class TokyoRunners extends Activity implements
38 LocationListener, GestureDetector.OnGestureListener {
40 private SharedPreferences m_prefs;
41 private LocationManager m_locMgr;
42 private long m_startTime;
43 private Chronometer m_elapsedTime;
44 private Chronometer m_lapTime;
45 private boolean m_running = false;
47 private boolean m_useGPS = false;
48 private boolean m_autosplit = false;
50 private GestureDetector m_gestureDetector;
52 private RunningRecord m_runningRecord;
54 class StartStopButton implements OnClickListener {
55 public void onClick(View v) {
56 if (m_running == true) {
63 class ResetLapButton implements OnClickListener {
64 public void onClick(View v) {
65 if (m_running == true) {
72 /** Called when the activity is first created. */
74 public void onCreate(Bundle savedInstanceState) {
75 super.onCreate(savedInstanceState);
77 m_gestureDetector = new GestureDetector(this, this);
79 if (m_gestureDetector.isLongpressEnabled() == false) {
80 Log.d(this.getClass().getName(), "Longpress disabled");
82 setContentView(R.layout.stopwatch);
84 m_prefs = PreferenceManager.getDefaultSharedPreferences(this);
86 m_useGPS = m_prefs.getBoolean("use_gps", true);
89 m_locMgr = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
91 m_autosplit = m_prefs.getBoolean("auto_split", false);
93 int interval = m_prefs.getInt("split_interval", 5);
98 m_elapsedTime = (Chronometer)findViewById(R.id.elapsed_time);
99 m_lapTime = (Chronometer)findViewById(R.id.lap_time);
101 m_runningRecord = new RunningRecord(getContentResolver());
104 Button btnStartStop = (Button)findViewById(R.id.button_start_stop);
105 btnStartStop.setOnClickListener(new StartStopButton());
107 Button btnResetLap = (Button)findViewById(R.id.button_reset_lap);
108 btnResetLap.setOnClickListener(new ResetLapButton());
110 ListView lvLaptime = (ListView)findViewById(R.id.lap_history);
111 ArrayAdapter<String> arrayAdapter
112 = new ArrayAdapter<String>(this, R.layout.laptime);
113 lvLaptime.setAdapter(arrayAdapter);
115 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
120 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
121 super.onActivityResult(requestCode, resultCode, data);
123 switch (requestCode) {
124 case Constants.REQUEST_CODE_SETTINGS:
125 m_useGPS = m_prefs.getBoolean("use_gps", true);
127 case Constants.REQUEST_CODE_HISTORY:
134 public void onDestroy() {
135 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
139 public boolean onCreateOptionsMenu(Menu menu) {
140 menu.add(Menu.NONE, Constants.MENU_SAVE, Menu.NONE, R.string.menu_save).setIcon(android.R.drawable.ic_menu_save);
141 menu.add(Menu.NONE, Constants.MENU_HISTORY, Menu.NONE, R.string.menu_history).setIcon(R.drawable.history2);
142 menu.add(Menu.NONE, Constants.MENU_MAP, Menu.NONE, R.string.menu_map).setIcon(android.R.drawable.ic_menu_mapmode);
143 menu.add(Menu.NONE, Constants.MENU_SETTING, Menu.NONE, R.string.menu_setting).setIcon(android.R.drawable.ic_menu_preferences);
145 return super.onCreateOptionsMenu(menu);
148 public boolean onPrepareOptionsMenu(Menu menu) {
149 menu.findItem(Constants.MENU_MAP).setEnabled(m_useGPS);
151 return super.onPrepareOptionsMenu(menu);
155 public Dialog onCreateDialog (int id) {
157 AlertDialog.Builder builder = new AlertDialog.Builder(this);
159 case Constants.DIALOG_SAVE_ID:
160 builder.setTitle(R.string.dialog_save_title);
161 builder.setMessage(R.string.dialog_save_message);
162 builder.setPositiveButton(R.string.dialog_yes, new DialogInterface.OnClickListener() {
164 public void onClick(DialogInterface dialog, int which) {
166 // TODO Auto-generated method stub
169 builder.setNegativeButton(R.string.dialog_no, new DialogInterface.OnClickListener() {
171 public void onClick(DialogInterface dialog, int which) {
182 AlertDialog alertDialog = builder.create();
187 public boolean onOptionsItemSelected(MenuItem item) {
189 switch (item.getItemId()) {
190 case Constants.MENU_SAVE:
191 showDialog(Constants.DIALOG_SAVE_ID);
193 case Constants.MENU_HISTORY:
194 intent = new Intent(this, RunningHistory.class);
195 intent.setAction(Intent.ACTION_VIEW);
196 intent.putExtra("files", fileList());
197 startActivityForResult(intent, Constants.REQUEST_CODE_HISTORY);
199 case Constants.MENU_MAP:
200 intent = new Intent(this, MapMode.class);
201 intent.setAction(Intent.ACTION_VIEW);
202 startActivity(intent);
204 case Constants.MENU_SETTING:
205 intent = new Intent(this, Config.class);
206 intent.setAction(Intent.ACTION_VIEW);
207 startActivityForResult(intent, Constants.REQUEST_CODE_SETTINGS);
214 public void onLocationChanged(Location location) {
215 Log.d(this.getClass().getName(),
216 "onLocationChanged(): latitude: " + location.getLatitude() +
217 "; longitude: " + location.getLongitude() );
219 m_runningRecord.addRecord(new Date(), location);
221 float distance_km = m_runningRecord.getDistance();
222 TextView distanceView = (TextView)findViewById(R.id.distance);
223 distanceView.setText(Float.toString(distance_km));
228 public void onProviderDisabled(String provider) {
232 public void onProviderEnabled(String provider) {
236 public void onStatusChanged(String provider, int status, Bundle extras) {
237 String statusStr = "";
239 case LocationProvider.AVAILABLE:
240 statusStr = "Available";
242 case LocationProvider.OUT_OF_SERVICE:
243 statusStr = "Out of service";
245 case LocationProvider.TEMPORARILY_UNAVAILABLE:
246 statusStr = "Temporarily unavailable";
249 statusStr = "Unknown status";
252 Log.d(this.getClass().getName(), "onStatusChanged(): " + statusStr);
255 private void start() {
256 m_startTime = System.currentTimeMillis();
257 long startTime = SystemClock.elapsedRealtime();
258 m_elapsedTime.setBase(startTime);
259 m_lapTime.setBase(startTime);
260 m_elapsedTime.start();
264 String strGpsFreq = m_prefs.getString("gps_frequency", "0");
265 int gps_freq =Integer.parseInt(strGpsFreq);
266 m_locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, gps_freq * 1000, 1, this);
270 Button startStopButton = (Button)findViewById(R.id.button_start_stop);
271 Button resetLapButton = (Button)findViewById(R.id.button_reset_lap);
272 startStopButton.setText(R.string.button_stop);
273 resetLapButton.setText(R.string.button_lap);
276 private void stop() {
277 m_elapsedTime.stop();
281 m_locMgr.removeUpdates(this);
284 Button startStopButton = (Button)findViewById(R.id.button_start_stop);
285 Button resetLapButton = (Button)findViewById(R.id.button_reset_lap);
286 startStopButton.setText(R.string.button_start);
287 resetLapButton.setText(R.string.button_reset);
291 private void reset() {
292 long elapsedRealTime = SystemClock.elapsedRealtime();
293 m_elapsedTime.setBase(elapsedRealTime);
294 m_lapTime.setBase(elapsedRealTime);
296 ListView listLaptime = (ListView)findViewById(R.id.lap_history);
297 ArrayAdapter<String> lapHistory = (ArrayAdapter<String>)listLaptime.getAdapter();
302 long elapsedRealTime = SystemClock.elapsedRealtime();
303 long lapTimeMillis = elapsedRealTime - m_lapTime.getBase();
305 ListView listLaptime = (ListView)findViewById(R.id.lap_history);
309 ArrayAdapter<String> lapHistory = (ArrayAdapter<String>)listLaptime.getAdapter();
311 int historyCount = lapHistory.getCount() + 1;
313 String strLaptime = "laptime " + historyCount + ": "
314 + DateUtils.formatElapsedTime(lapTimeMillis / 1000);
316 lapHistory.insert(strLaptime, 0);
318 m_lapTime.setBase(elapsedRealTime);
322 private void saveRecord() {
326 m_runningRecord.save();
330 getIntent().setData(Uri.parse("content://net.kazhik.android.tokyorunners.runningrecordprovider"));
332 ContentValues values = new ContentValues();
333 values.put("name", "Pen");
334 values.put("description", "This is a pen");
335 getContentResolver().insert(getIntent().getData(), values);
336 Cursor cur = managedQuery(getIntent().getData(), null, null, null, null);
337 while (cur.moveToNext()) {
338 Log.d(cur.getString(1), cur.getString(2));
343 FileOutputStream outFile = null;
344 OutputStreamWriter stWriter = null;
346 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss");
347 outFile = openFileOutput(formatter.format(new Date(m_startTime)) + ".xml", MODE_PRIVATE);
348 stWriter = new OutputStreamWriter(outFile);
349 m_runningRecord.save(stWriter);
350 } catch (IOException e) {
353 if (stWriter != null) {
356 if (outFile != null) {
359 } catch (IOException e) {
366 public boolean onTouchEvent(MotionEvent event) {
367 Log.d(this.getClass().getName(), "onTouchEvent():" );
368 if (m_gestureDetector.onTouchEvent(event)) {
371 return super.onTouchEvent(event);
375 public boolean onDown(MotionEvent arg0) {
376 Log.d(this.getClass().getName(), "onDown():" );
379 public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
381 Log.d(this.getClass().getName(), "onFling():" );
384 public void onLongPress(MotionEvent arg0) {
385 Log.d(this.getClass().getName(), "onLongPress():" );
387 Intent intent = new Intent(TokyoRunners.this, MapMode.class);
388 intent.setAction(Intent.ACTION_VIEW);
389 startActivity(intent);
392 public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
394 Log.d(this.getClass().getName(), "onScroll():" );
397 public void onShowPress(MotionEvent arg0) {
398 Log.d(this.getClass().getName(), "onShowPress():" );
400 public boolean onSingleTapUp(MotionEvent arg0) {
401 Log.d(this.getClass().getName(), "onSingleTapUp():" );