1 package net.kazhik.android.tokyorunners;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.OutputStreamWriter;
6 import java.text.ParseException;
7 import java.text.SimpleDateFormat;
8 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.Iterator;
13 import android.app.ListActivity;
14 import android.content.Intent;
15 import android.database.Cursor;
16 import android.os.Bundle;
17 import android.os.Environment;
18 import android.util.Log;
19 import android.view.ContextMenu;
20 import android.view.Menu;
21 import android.view.MenuItem;
22 import android.view.View;
23 import android.view.ContextMenu.ContextMenuInfo;
24 import android.widget.AdapterView;
25 import android.widget.ArrayAdapter;
26 import android.widget.AdapterView.AdapterContextMenuInfo;
27 import android.widget.AdapterView.OnItemClickListener;
29 public class RunningHistory extends ListActivity implements OnItemClickListener {
30 private SimpleDateFormat m_startTimeFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
31 private HashMap<Long, Long> m_startTimeMap = new HashMap<Long, Long>();
33 private static final int MENU_DELETE_THIS = Menu.FIRST + 200;
34 private static final int MENU_DELETE_ALL = Menu.FIRST + 201;
35 private static final int MENU_SAVE_GPX = Menu.FIRST + 202;
37 private final static String LOGDIR = Environment
38 .getExternalStorageDirectory().getPath()
42 public void onCreate(Bundle savedInstanceState) {
43 super.onCreate(savedInstanceState);
45 setContentView(R.layout.history);
49 RunningRecordProvider.START_TIME,
50 RunningRecordProvider.DISTANCE};
51 String sortOrder = RunningRecordProvider.CURRENT_TIME + " desc";
52 Cursor cursor = managedQuery(RunningRecordProvider.REC_URI, columns, null, null, sortOrder);
54 if (cursor == null || cursor.getCount() == 0) {
57 ArrayList<String> history = new ArrayList<String>();
60 long prevStartTime = 0;
61 while (cursor.moveToNext()) {
62 startTime = cursor.getLong(0);
63 distance = (float)cursor.getLong(1);
64 // Log.d(this.getClass().getName(), "startTime:" + startTime + "; distance:" + distance);
66 if (startTime == prevStartTime) {
67 // I need "select distinct"!
70 m_startTimeMap.put(startTime / 1000 * 1000, startTime);
72 prevStartTime = startTime;
73 StringBuffer rowStr = new StringBuffer();
74 rowStr.append(m_startTimeFormatter.format(new Date(startTime)));
77 rowStr.append(distance / 1000);
78 history.add(rowStr.toString());
80 ArrayAdapter<String> historyArray = new ArrayAdapter<String>(this, R.layout.runningrecord, history);
82 setListAdapter(historyArray);
86 getListView().setOnItemClickListener(this);
88 getListView().setOnCreateContextMenuListener(this);
91 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
92 ArrayAdapter<String> historyArray = (ArrayAdapter<String>)getListAdapter();
94 Intent returnData = new Intent();
96 String[] splitStr = historyArray.getItem(position).split(" ");
97 String dateStr = splitStr[0] + " " + splitStr[1];
98 Date startTime = m_startTimeFormatter.parse(dateStr);
100 returnData.setAction(Intent.ACTION_VIEW);
101 returnData.putExtra("startTime", m_startTimeMap.get(startTime.getTime()));
103 setResult(RESULT_OK, returnData);
104 } catch (ParseException e) {
111 public void onCreateContextMenu(ContextMenu menu, View v,
112 ContextMenuInfo menuInfo) {
113 super.onCreateContextMenu(menu, v, menuInfo);
114 menu.add(0, MENU_DELETE_THIS, 0, R.string.contextmenu_deletethis);
115 menu.add(0, MENU_DELETE_ALL, 0, R.string.contextmenu_deleteall);
116 menu.add(0, MENU_SAVE_GPX, 0, R.string.contextmenu_save_gpx);
119 public boolean onContextItemSelected(MenuItem item) {
120 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
122 ArrayAdapter<String> historyArray = (ArrayAdapter<String>) getListAdapter();
123 int position = info.position;
124 String[] splitStr = historyArray.getItem(position).split(" ");
125 String dateStr = splitStr[0] + " " + splitStr[1];
128 startTime = m_startTimeFormatter.parse(dateStr).getTime();
129 startTime = m_startTimeMap.get(startTime);
130 } catch (ParseException e) {
133 switch (item.getItemId()) {
134 case MENU_DELETE_THIS:
136 String selection = RunningRecordProvider.START_TIME + " = ?";
137 String[] selectionArgs = { Long.toString(startTime) };
139 getContentResolver().delete(RunningRecordProvider.REC_URI,
140 selection, selectionArgs);
142 historyArray.remove(historyArray.getItem(position));
144 case MENU_DELETE_ALL:
145 getContentResolver().delete(RunningRecordProvider.REC_URI, null,
147 historyArray.clear();
150 saveRecordAsGpxFile(startTime);
155 return super.onContextItemSelected(item);
158 private void saveRecordAsGpxFile(long startTime) {
159 String[] columns = { RunningRecordProvider.CURRENT_TIME,
160 RunningRecordProvider.LATITUDE,
161 RunningRecordProvider.LONGITUDE,
162 RunningRecordProvider.POINT_NAME };
163 String selection = RunningRecordProvider.START_TIME + " = ?";
164 String[] selectionArgs = { Long.toString(startTime) };
165 String sortOrder = RunningRecordProvider.CURRENT_TIME + " asc";
166 Cursor cursor = managedQuery(RunningRecordProvider.REC_URI, columns,
167 selection, selectionArgs, sortOrder);
168 if (cursor == null) {
172 SimpleDateFormat formatter = new SimpleDateFormat(
173 "yyyy-MM-dd_HH_mm_ss");
174 String gpxFilePath = LOGDIR + formatter.format(new Date(startTime)) + ".xml";
175 FileOutputStream gpxFile = null;
176 OutputStreamWriter stWriter = null;
178 gpxFile = new FileOutputStream(gpxFilePath);
179 stWriter = new OutputStreamWriter(gpxFile);
181 .write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
183 + " version=\"1.0\"\n"
184 + "creator=\"Tokyo Runners\"\n"
185 + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
186 + "xmlns=\"http://www.topografix.com/GPX/1/0\"\n"
187 + "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
189 stWriter.write("<trk>\n" + "<trkseg>\n");
191 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
192 SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
194 long currentTime = 0;
197 String pointName = "";
199 while (cursor.moveToNext()) {
200 currentTime = cursor.getLong(cursor
201 .getColumnIndex(RunningRecordProvider.CURRENT_TIME));
202 latitude = cursor.getInt(cursor
203 .getColumnIndex(RunningRecordProvider.LATITUDE));
204 longitude = cursor.getInt(cursor
205 .getColumnIndex(RunningRecordProvider.LONGITUDE));
206 pointName = cursor.getString(cursor
207 .getColumnIndex(RunningRecordProvider.POINT_NAME));
209 stWriter.write("<trkpt lat=\"" + (((float)latitude) / 1E6)
210 + "\" lon=\"" + (((float)longitude) / 1E6) + "\">\n" + "<time>"
211 + dateFormat.format(currentTime) + "T"
212 + timeFormat.format(currentTime) + "Z</time>\n"
213 + "<speed>" + 0 + "</speed>\n" + "<name>"
214 + pointName + "</name>\n" + "<fix>none</fix>\n"
219 stWriter.write("</trkseg>\n" + "</trk>\n" + "</gpx>\n");
222 } catch (IOException e) {
225 if (stWriter != null) {
228 if (gpxFile != null) {
231 } catch (IOException e) {