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
17package com.android.locationtracker;
18
19import com.android.locationtracker.data.DateUtils;
20import com.android.locationtracker.data.TrackerDataHelper;
21import com.android.locationtracker.data.TrackerListHelper;
22
23import android.app.AlertDialog;
24import android.app.ListActivity;
25import android.content.DialogInterface;
26import android.content.DialogInterface.OnClickListener;
27import android.content.Intent;
28import android.database.Cursor;
29import android.location.LocationManager;
30import android.os.Bundle;
31import android.os.Environment;
32import android.util.Log;
33import android.view.Menu;
34import android.view.MenuInflater;
35import android.view.MenuItem;
36import android.widget.Toast;
37
38import java.io.BufferedWriter;
39import java.io.File;
40import java.io.FileWriter;
41import java.io.IOException;
42import 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 */
56public 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
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
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
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
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
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
155    private void exportCSV() {
156        String exportFileName = getUniqueFileName("csv");
157        exportFile(null, exportFileName, new TrackerDataHelper(this,
158                TrackerDataHelper.CSV_FORMATTER));
159    }
160
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
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
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
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
221    private void launchSettings() {
222        Intent settingsIntent = new Intent();
223        settingsIntent.setClass(this, SettingsActivity.class);
224        startActivity(settingsIntent);
225    }
226}
227