1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.locationtracker;
18 
19 import com.android.locationtracker.data.DateUtils;
20 import com.android.locationtracker.data.TrackerDataHelper;
21 import com.android.locationtracker.data.TrackerListHelper;
22 
23 import android.app.AlertDialog;
24 import android.app.ListActivity;
25 import android.content.DialogInterface;
26 import android.content.DialogInterface.OnClickListener;
27 import android.content.Intent;
28 import android.database.Cursor;
29 import android.location.LocationManager;
30 import android.os.Bundle;
31 import android.os.Environment;
32 import android.util.Log;
33 import android.view.Menu;
34 import android.view.MenuInflater;
35 import android.view.MenuItem;
36 import android.widget.Toast;
37 
38 import java.io.BufferedWriter;
39 import java.io.File;
40 import java.io.FileWriter;
41 import java.io.IOException;
42 import java.io.Writer;
43 
44 /**
45  * Activity for location tracker service
46  *
47  * Contains facilities for starting and
48  * stopping location tracker service, as well as displaying the current location
49  * data
50  *
51  * Future enhancements:
52  *   - export data as dB
53  *   - enable/disable "start service" and "stop service" menu items as
54  *     appropriate
55  */
56 public class TrackerActivity extends ListActivity {
57 
58     static final String LOG_TAG = "LocationTracker";
59 
60     private TrackerListHelper mDataHelper;
61 
62     /**
63      * Retrieves and displays the currently logged location data from file
64      *
65      * @param icicle
66      */
67     @Override
onCreate(Bundle icicle)68     protected void onCreate(Bundle icicle) {
69         super.onCreate(icicle);
70 
71         mDataHelper = new TrackerListHelper(this);
72         mDataHelper.bindListUI(R.layout.entrylist_item);
73     }
74 
75     /**
76      * Builds the menu
77      *
78      * @param menu - menu to add items to
79      */
80     @Override
onCreateOptionsMenu(Menu menu)81     public boolean onCreateOptionsMenu(Menu menu) {
82         MenuInflater menuInflater = getMenuInflater();
83         menuInflater.inflate(R.menu.menu, menu);
84         return true;
85     }
86 
87     /**
88      * Handles menu item selection
89      *
90      * @param item - the selected menu item
91      */
92     @Override
onOptionsItemSelected(MenuItem item)93     public boolean onOptionsItemSelected(MenuItem item) {
94         switch (item.getItemId()) {
95             case R.id.start_service_menu: {
96                 startService(new Intent(TrackerActivity.this,
97                         TrackerService.class));
98                 break;
99             }
100             case R.id.stop_service_menu: {
101                 stopService(new Intent(TrackerActivity.this,
102                         TrackerService.class));
103                 break;
104             }
105             case R.id.settings_menu: {
106                 launchSettings();
107                 break;
108             }
109             case R.id.export_kml: {
110                 exportKML();
111                 break;
112             }
113             case R.id.export_csv: {
114                 exportCSV();
115                 break;
116             }
117             case R.id.clear_data_menu: {
118                 clearData();
119                 break;
120             }
121         }
122         return super.onOptionsItemSelected(item);
123     }
124 
clearData()125     private void clearData() {
126         Runnable clearAction = new Runnable() {
127             public void run() {
128                 TrackerDataHelper helper =
129                     new TrackerDataHelper(TrackerActivity.this);
130                 helper.deleteAll();
131             }
132         };
133         showConfirm(R.string.delete_confirm, clearAction);
134     }
135 
showConfirm(int textId, final Runnable onConfirmAction)136     private void showConfirm(int textId, final Runnable onConfirmAction) {
137         AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
138         dialogBuilder.setTitle(R.string.confirm_title);
139         dialogBuilder.setMessage(textId);
140         dialogBuilder.setPositiveButton(android.R.string.ok,
141                 new OnClickListener() {
142             public void onClick(DialogInterface dialog, int which) {
143                 onConfirmAction.run();
144             }
145         });
146         dialogBuilder.setNegativeButton(android.R.string.cancel,
147                 new OnClickListener() {
148             public void onClick(DialogInterface dialog, int which) {
149                 // do nothing
150             }
151         });
152         dialogBuilder.show();
153     }
154 
exportCSV()155     private void exportCSV() {
156         String exportFileName = getUniqueFileName("csv");
157         exportFile(null, exportFileName, new TrackerDataHelper(this,
158                 TrackerDataHelper.CSV_FORMATTER));
159     }
160 
exportKML()161     private void exportKML() {
162         String exportFileName = getUniqueFileName(
163                 LocationManager.NETWORK_PROVIDER + ".kml");
164         exportFile(LocationManager.NETWORK_PROVIDER, exportFileName,
165                 new TrackerDataHelper(this, TrackerDataHelper.KML_FORMATTER));
166         exportFileName = getUniqueFileName(
167                 LocationManager.GPS_PROVIDER + ".kml");
168         exportFile(LocationManager.GPS_PROVIDER, exportFileName,
169                 new TrackerDataHelper(this, TrackerDataHelper.KML_FORMATTER));
170     }
171 
exportFile(String tagFilter, String exportFileName, TrackerDataHelper trackerData)172     private void exportFile(String tagFilter,
173                             String exportFileName,
174                             TrackerDataHelper trackerData) {
175         BufferedWriter exportWriter = null;
176         Cursor cursor = trackerData.query(tagFilter);
177         try {
178             exportWriter = new BufferedWriter(new FileWriter(exportFileName));
179             exportWriter.write(trackerData.getOutputHeader());
180 
181             String line = null;
182 
183             while ((line = trackerData.getNextOutput(cursor)) != null) {
184                 exportWriter.write(line);
185             }
186             exportWriter.write(trackerData.getOutputFooter());
187             Toast.makeText(this, "Successfully exported data to " +
188                     exportFileName, Toast.LENGTH_SHORT).show();
189 
190         } catch (IOException e) {
191             Toast.makeText(this, "Error exporting file: " +
192                     e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
193 
194             Log.e(LOG_TAG, "Error exporting file", e);
195         } finally {
196             closeWriter(exportWriter);
197             if (cursor != null) {
198                 cursor.close();
199             }
200         }
201     }
202 
closeWriter(Writer exportWriter)203     private void closeWriter(Writer exportWriter) {
204         if (exportWriter != null) {
205             try {
206                 exportWriter.close();
207             } catch (IOException e) {
208                 Log.e(LOG_TAG, "error closing file", e);
209             }
210         }
211     }
212 
getUniqueFileName(String ext)213     private String getUniqueFileName(String ext) {
214         File dir = new File(Environment.getExternalStorageDirectory() + "/locationtracker");
215         if (!dir.exists()) {
216             dir.mkdir();
217         }
218         return dir + "/tracking-" + DateUtils.getCurrentTimestamp() + "." + ext;
219     }
220 
launchSettings()221     private void launchSettings() {
222         Intent settingsIntent = new Intent();
223         settingsIntent.setClass(this, SettingsActivity.class);
224         startActivity(settingsIntent);
225     }
226 }
227