Merge with head.

This commit is contained in:
Sandor Dornbush
2011-03-24 23:05:02 -07:00
62 changed files with 1582 additions and 436 deletions
+5 -5
View File
@@ -17,8 +17,8 @@ limitations under the License.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.maps.mytracks"
android:installLocation="auto"
android:versionCode="26"
android:versionName="1.1.3">
android:versionCode="27"
android:versionName="1.1.4">
<application android:icon="@drawable/arrow_icon"
android:label="@string/app_name"
android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent">
@@ -52,7 +52,7 @@ limitations under the License.
</intent-filter>
</activity>
<activity android:name="com.google.android.apps.mytracks.MyTracksMap"
<activity android:name="com.google.android.apps.mytracks.MapActivity"
android:label="MyTracks"
android:exported="false" />
@@ -73,7 +73,7 @@ limitations under the License.
<activity android:name="com.google.android.apps.mytracks.WaypointDetails"
android:label="@string/waypointdetails_title" />
<activity android:name="com.google.android.apps.mytracks.MyTracksSettings"
<activity android:name="com.google.android.apps.mytracks.SettingsActivity"
android:label="@string/mytracks_settings" />
<activity android:name="com.google.android.apps.mytracks.AggregatedStatsActivity"
@@ -101,7 +101,7 @@ limitations under the License.
android:exported="true"
android:permission="com.google.android.apps.mytracks.WRITE_TRACK_DATA" />
<receiver android:name="com.google.android.apps.mytracks.MyTracksReceiver">
<receiver android:name="com.google.android.apps.mytracks.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
+8 -8
View File
@@ -30,18 +30,18 @@ limitations under the License.
<string name="current_segment">Último segmento</string>
<!-- Error messages -->
<string name="error_no_location_manager">Ningún administrador de ubicación fue hallado en este aparato! </string>
<string name="error_no_gps_location_provider">Ningún proveedor GPS de ubicación fue hallado en este aparato.</string>
<string name="error_sending_to_fusiontables">Hubo un error al mandar su recorrido a Google Fusion Tables. Por favor inténtelo de nuevo más tarde.</string>
<string name="error_sending_to_docs">Hubo un error al mandar su recorrido a Google Docs. Por favor inténtelo de nuevo más tarde.</string>
<string name="error_unable_to_start_recording">No pude empezar a grabar. Por favor inténtelo de nuevo. </string>
<string name="error_unable_to_stop_recording">No pude dejar de grabar. Por favor inténtelo de nuevo.</string>
<string name="error_no_location_manager">Ningún administrador de ubicación fue hallado en este dispositivo! </string>
<string name="error_no_gps_location_provider">Ningún proveedor de ubicación GPS fue hallado en este dispositivo.</string>
<string name="error_sending_to_fusiontables">Se produjo un error al enviar su recorrido a Google Fusion Tables.</string>
<string name="error_sending_to_docs">Se produjo un error al enviar su recorrido a Google Docs.</string>
<string name="error_unable_to_start_recording">No se puede iniciar la grabación. Inténtelo de nuevo. </string>
<string name="error_unable_to_stop_recording">No se puede detener la grabación. Inténtelo de nuevo.</string>
<string name="error_unable_to_read_file">No pude leer del archivo.</string>
<string name="error_invalid_gpx_format">El archivo no tiene un format GPX válido.</string>
<string name="error_generic">Error. Por favor inténtelo de nuevo.</string>
<string name="error_generic">A ocurrido un error. Por favor, inténtelo de nuevo.</string>
<string name="error_track_does_not_exist">El recorrido no existe.</string>
<string name="error_out_of_memory">El archivo es demasiado grande (tiene que ser menor a 500 KB). Abortando.</string>
<string name="error_unable_to_insert_marker">No pude insertar la señal. La ubicación no esta disponible.</string>
<string name="error_unable_to_insert_marker">No se puede insertar el marcador. La ubicación no esta disponible.</string>
<!-- Status messages -->
<string name="wait_for_fix">Esperando una ubicación mas exacta del GPS. Asegúrese que el cielo sea visible.</string>
@@ -67,7 +67,7 @@ public class AggregatedStatsActivity extends Activity implements
sv.setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_INSET);
SharedPreferences preferences = getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
if (preferences != null) {
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
preferences.registerOnSharedPreferenceChangeListener(this);
@@ -41,17 +41,17 @@ import android.util.Log;
*
* @author Bartlomiej Niechwiej
*/
public class MyTracksReceiver extends BroadcastReceiver {
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "MyTracksReceiver.onReceive: " + intent.getAction());
Log.d(TAG, "BootReceiver.onReceive: " + intent.getAction());
if (ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent startIntent = new Intent(context, TrackRecordingService.class);
startIntent.putExtra(RESUME_TRACK_EXTRA_NAME, true);
context.startService(startIntent);
} else {
Log.w(TAG, "MyTracksReceiver: unsupported action");
Log.w(TAG, "BootReceiver: unsupported action");
}
}
}
@@ -78,7 +78,7 @@ class CheckUnits {
private static void accept(Context context, SharedPreferences preferences) {
recordCheckPerformed(preferences);
Intent startIntent = new Intent(context, MyTracksSettings.class);
Intent startIntent = new Intent(context, SettingsActivity.class);
context.startActivity(startIntent);
}
@@ -140,6 +140,12 @@ public abstract class Constants {
*/
public static final int MAX_LOADED_TRACK_POINTS = 20000;
/**
* Maximum number of track points ever loaded at once from the provider into
* memory in a single call to read points.
*/
public static final int MAX_LOADED_TRACK_POINTS_PER_BATCH = 1000;
/**
* Maximum number of way points displayed by the map overlay.
*/
@@ -216,6 +222,20 @@ public abstract class Constants {
public static final String MAPSHOP_BASE_URL =
"http://maps.google.com/maps/ms";
/*
* Default values - keep in sync with those in preferences.xml.
*/
public static final int DEFAULT_ANNOUNCEMENT_FREQUENCY = -1;
public static final int DEFAULT_AUTO_RESUME_TRACK_TIMEOUT = 10; // In min.
public static final int DEFAULT_MAX_RECORDING_DISTANCE = 200;
public static final int DEFAULT_MIN_RECORDING_DISTANCE = 5;
public static final int DEFAULT_MIN_RECORDING_INTERVAL = 0;
public static final int DEFAULT_MIN_REQUIRED_ACCURACY = 200;
public static final int DEFAULT_SPLIT_FREQUENCY = 0;
public static final String SETTINGS_NAME = "SettingsActivity";
/**
* This is an abstract utility class.
*/
@@ -61,8 +61,9 @@ public class DeleteAllTracks extends Handler {
Log.w(Constants.TAG, "deleting all!");
MyTracksProviderUtils.Factory.get(context).deleteAllTracks();
SharedPreferences prefs =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
// TODO: Go through data manager
editor.putLong(context.getString(R.string.selected_track_key), -1);
ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges(editor);
if (done != null) {
@@ -17,10 +17,10 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.io.TrackWriter;
import com.google.android.apps.mytracks.io.TrackWriterFactory;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.io.file.TrackWriter;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -113,14 +113,14 @@ public class ExportAllTracks {
*/
private void aquireLocksAndExport() {
SharedPreferences prefs =
activity.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
activity.getSharedPreferences(Constants.SETTINGS_NAME, 0);
long recordingTrackId = -1;
if (prefs != null) {
recordingTrackId =
prefs.getLong(activity.getString(R.string.recording_track_key), -1);
}
if (recordingTrackId != -1) {
wakeLock = MyTracksUtils.acquireWakeLock(activity, wakeLock);
wakeLock = SystemUtils.acquireWakeLock(activity, wakeLock);
}
// Now we can safely export everything.
@@ -16,9 +16,9 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.io.GpxImporter;
import com.google.android.apps.mytracks.io.file.GpxImporter;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -82,13 +82,13 @@ public class ImportAllTracks {
* track. Acquire a wake lock if there is no current track.
*/
private void aquireLocksAndImport() {
SharedPreferences prefs = activity.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences prefs = activity.getSharedPreferences(Constants.SETTINGS_NAME, 0);
long recordingTrackId = -1;
if (prefs != null) {
recordingTrackId = prefs.getLong(activity.getString(R.string.recording_track_key), -1);
}
if (recordingTrackId != -1) {
wakeLock = MyTracksUtils.acquireWakeLock(activity, wakeLock);
wakeLock = SystemUtils.acquireWakeLock(activity, wakeLock);
}
// Now we can safely import everything.
@@ -16,7 +16,7 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
@@ -45,7 +45,7 @@ import java.util.concurrent.BlockingQueue;
*
* @author Leif Hendrik Wilden
*/
public class MyTracksOverlay extends Overlay {
public class MapOverlay extends Overlay {
private final Drawable[] arrows;
private final int arrowWidth, arrowHeight;
@@ -79,14 +79,25 @@ public class MyTracksOverlay extends Overlay {
private static class CachedLocation {
public final boolean valid;
public final GeoPoint geoPoint;
/**
* Constructor for an invalid cached location.
*/
public CachedLocation() {
this.valid = false;
this.geoPoint = null;
}
/**
* Constructor for a potentially valid cached location.
*/
public CachedLocation(Location location) {
this.valid = MyTracksUtils.isValidLocation(location);
this.geoPoint = valid ? MyTracksUtils.getGeoPoint(location) : null;
this.valid = LocationUtils.isValidLocation(location);
this.geoPoint = valid ? LocationUtils.getGeoPoint(location) : null;
}
};
public MyTracksOverlay(Context context) {
public MapOverlay(Context context) {
this.context = context;
this.waypoints = new ArrayList<Waypoint>();
@@ -164,6 +175,13 @@ public class MyTracksOverlay extends Overlay {
pendingPoints.offer(new CachedLocation(l));
}
/**
* Adds a segment split to the map overlay.
*/
public void addSegmentSplit() {
pendingPoints.offer(new CachedLocation());
}
public void addWaypoint(Waypoint wpt) {
// Note: We don't cache waypoints, because it's not worth the effort.
if (wpt != null && wpt.getLocation() != null) {
@@ -172,7 +190,7 @@ public class MyTracksOverlay extends Overlay {
}
}
}
public int getNumLocations() {
synchronized (points) {
return points.size() + pendingPoints.size();
@@ -260,7 +278,7 @@ public class MyTracksOverlay extends Overlay {
synchronized (waypoints) {;
for (Waypoint wpt : waypoints) {
Location loc = wpt.getLocation();
drawElement(canvas, projection, MyTracksUtils.getGeoPoint(loc),
drawElement(canvas, projection, LocationUtils.getGeoPoint(loc),
wpt.getType() == Waypoint.TYPE_STATISTICS ? statsMarker
: waypointMarker, -(markerWidth / 2) + 3, -markerHeight);
}
@@ -274,7 +292,7 @@ public class MyTracksOverlay extends Overlay {
}
Point pt = drawElement(canvas, projection,
MyTracksUtils.getGeoPoint(myLocation), arrows[lastHeading],
LocationUtils.getGeoPoint(myLocation), arrows[lastHeading],
-(arrowWidth / 2) + 3, -(arrowHeight / 2));
// Draw the error circle.
float radius = projection.metersToEquatorPixels(myLocation.getAccuracy());
@@ -423,7 +441,7 @@ public class MyTracksOverlay extends Overlay {
return false;
}
final Location tapLocation = MyTracksUtils.getLocation(p);
final Location tapLocation = LocationUtils.getLocation(p);
double dmin = Double.MAX_VALUE;
Waypoint waypoint = null;
synchronized (waypoints) {
@@ -78,7 +78,7 @@ class MenuManager {
return startActivity(SensorStateActivity.class);
}
case R.id.menu_settings: {
return startActivity(MyTracksSettings.class);
return startActivity(SettingsActivity.class);
}
case R.id.menu_aggregated_stats: {
return startActivity(AggregatedStatsActivity.class);
@@ -87,7 +87,7 @@ class MenuManager {
return startActivity(WelcomeActivity.class);
}
case Constants.MENU_CLEAR_MAP: {
activity.setSelectedTrackId(-1);
activity.clearSelectedTrack();
return true;
}
}
@@ -27,15 +27,15 @@ import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.io.AuthManager;
import com.google.android.apps.mytracks.io.AuthManagerFactory;
import com.google.android.apps.mytracks.io.GpxImporter;
import com.google.android.apps.mytracks.io.SendToDocs;
import com.google.android.apps.mytracks.io.SendToFusionTables;
import com.google.android.apps.mytracks.io.SendToFusionTables.OnSendCompletedListener;
import com.google.android.apps.mytracks.io.SendToMyMaps;
import com.google.android.apps.mytracks.io.TempFileCleaner;
import com.google.android.apps.mytracks.io.TrackWriter;
import com.google.android.apps.mytracks.io.TrackWriterFactory;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.GpxImporter;
import com.google.android.apps.mytracks.io.file.TempFileCleaner;
import com.google.android.apps.mytracks.io.file.TrackWriter;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
import com.google.android.apps.mytracks.io.mymaps.MyMapsConstants;
import com.google.android.apps.mytracks.io.sendtogoogle.ResultDialogFactory;
@@ -47,7 +47,7 @@ import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.util.ApiFeatures;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -55,15 +55,11 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.TabActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -101,12 +97,13 @@ import org.xml.sax.SAXException;
* @author Leif Hendrik Wilden
*/
public class MyTracks extends TabActivity implements OnTouchListener,
OnSharedPreferenceChangeListener, ProgressIndicator {
ProgressIndicator {
/**
* Singleton instance
*/
private static MyTracks instance;
private TrackDataHub dataHub;
private ChartActivity chartActivity;
/*
@@ -151,18 +148,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
private ITrackRecordingService trackRecordingService;
/**
* The id of the currently recording track.
* Does the user want to share the current track.
*/
private long recordingTrackId = -1;
/**
* The id of the currently selected track.
*/
private long selectedTrackId = -1;
/**
* Does the user want to share the current track.
*/
private boolean shareRequested = false;
/**
@@ -234,7 +221,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
public boolean isRecording() {
if (trackRecordingService == null) {
// Fall back to alternative check method.
return isRecordingBasedOnSharedPreferences();
return dataHub.isRecording();
}
try {
return trackRecordingService.isRecording();
@@ -244,16 +231,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
Log.e(TAG, "MyTracks: Remote exception.", e);
// Fall back to alternative check method.
return isRecordingBasedOnSharedPreferences();
return dataHub.isRecording();
}
}
private boolean isRecordingBasedOnSharedPreferences() {
// TrackRecordingService guarantees that recordingTrackId is set to
// -1 if the track has been stopped.
return recordingTrackId >= 0;
}
/*
* Application lifetime events:
* ============================
@@ -265,13 +246,14 @@ public class MyTracks extends TabActivity implements OnTouchListener,
super.onCreate(savedInstanceState);
instance = this;
ApiFeatures apiFeatures = ApiFeatures.getInstance();
if (!MyTracksUtils.isRelease(this)) {
if (!SystemUtils.isRelease(this)) {
apiFeatures.getApiPlatformAdapter().enableStrictMode();
}
providerUtils = MyTracksProviderUtils.Factory.get(this);
dataHub = new TrackDataHub(this, providerUtils);
menuManager = new MenuManager(this);
sharedPreferences = getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, 0);
dialogManager = new DialogManager(this);
// The volume we want to control is the Text-To-Speech volume
@@ -287,7 +269,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("Map", res.getDrawable(
android.R.drawable.ic_menu_mapmode))
.setContent(new Intent(this, MyTracksMap.class)));
.setContent(new Intent(this, MapActivity.class)));
tabHost.addTab(tabHost.newTabSpec("tab2")
.setIndicator("Stats", res.getDrawable(R.drawable.menu_stats))
.setContent(new Intent(this, StatsActivity.class)));
@@ -312,20 +294,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
tabHost.addView(layout);
layout.setOnTouchListener(this);
if (sharedPreferences != null) {
selectedTrackId =
sharedPreferences.getLong(getString(R.string.selected_track_key), -1);
recordingTrackId = sharedPreferences.getLong(
getString(R.string.recording_track_key), -1);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
Log.d(TAG, "recordingTrackId: " + recordingTrackId
+ ", selectedTrackId: " + selectedTrackId);
if (recordingTrackId > 0) {
Intent startIntent = new Intent(this, TrackRecordingService.class);
startService(startIntent);
}
}
// This will show the eula until the user accepts or quits the app.
Eula.showEulaRequireAcceptance(this);
@@ -353,10 +321,24 @@ public class MyTracks extends TabActivity implements OnTouchListener,
@Override
protected void onDestroy() {
Log.d(TAG, "MyTracks.onDestroy");
dataHub.destroy();
tryUnbindTrackRecordingService();
super.onDestroy();
}
@Override
protected void onStop() {
Log.d(TAG, "MyTracks.onStop");
dataHub.stop();
// Clean up any temporary track files.
TempFileCleaner.clean();
super.onStop();
}
@Override
protected void onPause() {
// Called when activity is going into the background, but has not (yet) been
@@ -376,11 +358,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
@Override
protected void onStop() {
Log.d(TAG, "MyTracks.onStop");
// Clean up any temporary track files.
TempFileCleaner.clean();
super.onStop();
protected void onStart() {
Log.d(TAG, "MyTracks.onStart");
super.onStart();
dataHub.start();
}
/*
@@ -397,7 +378,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menuManager.onPrepareOptionsMenu(menu, providerUtils.getLastTrack() != null,
isRecording(), selectedTrackId >= 0);
isRecording(), dataHub.isATrackSelected());
return super.onPrepareOptionsMenu(menu);
}
@@ -455,6 +436,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
public void onActivityResult(int requestCode, int resultCode,
final Intent results) {
TrackFileFormat exportFormat = null;
final long trackId = results.getLongExtra("trackid", dataHub.getSelectedTrackId());
switch (requestCode) {
case Constants.GET_LOGIN: {
if (resultCode != RESULT_OK || auth == null || !auth.authResult(resultCode, results)) {
@@ -464,9 +446,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
case Constants.SHOW_TRACK: {
if (results != null) {
final long trackId = results.getLongExtra("trackid", -1);
if (trackId >= 0) {
setSelectedTrackId(trackId);
dataHub.loadTrack(trackId);
// The track list passed the requested action as result code. Hand
// it off to the onAcitivtyResult for further processing:
if (resultCode != Constants.SHOW_TRACK) {
@@ -480,8 +462,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
if (results != null) {
final long waypointId = results.getLongExtra("waypointid", -1);
if (waypointId >= 0) {
MyTracksMap map =
(MyTracksMap) getLocalActivityManager().getActivity("tab1");
MapActivity map =
(MapActivity) getLocalActivityManager().getActivity("tab1");
if (map != null) {
getTabHost().setCurrentTab(0);
map.showWaypoint(waypointId);
@@ -492,14 +474,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
case Constants.DELETE_TRACK: {
if (results != null && resultCode == RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
deleteTrack(trackId);
}
break;
}
case Constants.EDIT_DETAILS: {
if (results != null && resultCode == RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
Intent intent = new Intent(this, TrackDetails.class);
intent.putExtra("trackid", trackId);
startActivity(intent);
@@ -514,7 +494,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
case Constants.GET_MAP: {
// User picked a map to upload to
if (resultCode == RESULT_OK) {
results.putExtra("trackid", selectedTrackId);
results.putExtra("trackid", dataHub.getSelectedTrackId());
if (results.hasExtra("mapid")) {
sendToMyMapsMapId = results.getStringExtra("mapid");
}
@@ -528,17 +508,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
// Authenticated with Google My Maps
if (results != null && resultCode == RESULT_OK) {
final String mapId;
final long trackId;
if (results.hasExtra("mapid")) {
mapId = results.getStringExtra("mapid");
} else {
mapId = "new";
}
if (results.hasExtra("trackid")) {
trackId = results.getLongExtra("trackid", -1);
} else {
trackId = selectedTrackId;
}
sendToGoogleMaps(trackId, mapId);
} else {
@@ -549,13 +523,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
case Constants.AUTHENTICATE_TO_FUSION_TABLES: {
// Authenticated with Google Fusion Tables
if (results != null && resultCode == RESULT_OK) {
final long trackId;
if (results.hasExtra("trackid")) {
trackId = results.getLongExtra("trackid", -1);
} else {
trackId = selectedTrackId;
}
sendToFusionTables(trackId);
} else {
onSendToGoogleDone();
@@ -574,7 +541,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
case Constants.AUTHENTICATE_TO_TRIX: {
// Authenticated with Trix
if (resultCode == RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
sendToGoogleDocs(trackId);
} else {
onSendToGoogleDone();
@@ -594,19 +560,18 @@ public class MyTracks extends TabActivity implements OnTouchListener,
if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
if (results != null && resultCode == Activity.RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
if (trackId >= 0) {
saveTrack(trackId, exportFormat);
}
}
break;
case Constants.SHARE_LINK: {
Track selectedTrack = providerUtils.getTrack(selectedTrackId);
Track selectedTrack = providerUtils.getTrack(dataHub.getSelectedTrackId());
if (selectedTrack != null) {
if (!TextUtils.isEmpty(selectedTrack.getMapId())) {
shareLinkToMap(MapsFacade.buildMapUrl(selectedTrack.getMapId()));
} else if (!TextUtils.isEmpty(selectedTrack.getTableId())) {
shareLinkToMap(getFusionTablesUrl(selectedTrackId));
shareLinkToMap(getFusionTablesUrl(dataHub.getSelectedTrackId()));
} else {
shareRequested = true;
dialogManager.showDialogSafely(DIALOG_SEND_TO_GOOGLE);
@@ -627,7 +592,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
if (results != null && resultCode == Activity.RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
if (trackId >= 0) {
sendTrack(trackId, exportFormat);
}
@@ -635,7 +599,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
break;
}
case Constants.CLEAR_MAP: {
setSelectedTrackId(-1);
dataHub.unloadCurrentTrack();
break;
}
case Constants.WELCOME: {
@@ -657,19 +621,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
return false;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key != null && key.equals(getString(R.string.selected_track_key))) {
selectedTrackId = sharedPreferences.getLong(
getString(R.string.selected_track_key), -1);
}
if (key != null && key.equals(getString(R.string.recording_track_key))) {
recordingTrackId = sharedPreferences.getLong(
getString(R.string.recording_track_key), -1);
}
}
/**
* Resets status information for sending to MyMaps/Docs.
*/
@@ -715,7 +666,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
if (trackIdsImported != null && trackIdsImported.length > 0) {
// select last track from import file
setSelectedTrackId(trackIdsImported[trackIdsImported.length - 1]);
dataHub.loadTrack(trackIdsImported[trackIdsImported.length - 1]);
} else {
dialogManager.showMessageDialog(message, false/* success */);
}
@@ -787,8 +738,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
public void onClick(DialogInterface dialog, int i) {
dialog.dismiss();
providerUtils.deleteTrack(trackId);
if (trackId == selectedTrackId) {
setSelectedTrackId(-1);
if (trackId == dataHub.getSelectedTrackId()) {
dataHub.unloadCurrentTrack();
}
}});
builder.setNegativeButton(getString(R.string.no),
@@ -801,46 +752,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
dialog.show();
}
public Location getCurrentLocation() {
// TODO: Let's look at more advanced algorithms to determine the best
// current location.
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager == null) {
return null;
}
final long maxAgeMilliSeconds = 1000 * 60 * 1; // 1 minute
final long maxAgeNetworkMilliSeconds = 1000 * 60 * 10; // 10 minutes
final long now = System.currentTimeMillis();
Location loc = locationManager.getLastKnownLocation(
Constants.GPS_PROVIDER);
if (loc == null || loc.getTime() < now - maxAgeMilliSeconds) {
// We don't have a recent GPS fix, just use cell towers if available
loc = locationManager.getLastKnownLocation(
LocationManager.NETWORK_PROVIDER);
if (loc == null || loc.getTime() < now - maxAgeNetworkMilliSeconds) {
// We don't have a recent cell tower location, let the user know:
Toast.makeText(this, getString(R.string.status_no_location),
Toast.LENGTH_LONG).show();
return null;
} else {
// Let the user know we have only an approximate location:
Toast.makeText(this, getString(R.string.status_approximate_location),
Toast.LENGTH_LONG).show();
}
}
return loc;
}
public Location getLastLocation() {
if (providerUtils.getLastLocationId(recordingTrackId) < 0) {
return null;
}
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.getLastKnownLocation(Constants.GPS_PROVIDER);
}
/**
* Inserts a waypoint marker.
*
@@ -917,9 +828,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
private void startRecordingNewTrack(
ITrackRecordingService trackRecordingService) {
try {
recordingTrackId = trackRecordingService.startNewTrack();
long recordingTrackId = trackRecordingService.startNewTrack();
// Select the recording track.
setSelectedTrackId(recordingTrackId);
dataHub.loadTrack(recordingTrackId);
Toast.makeText(this, getString(R.string.status_now_recording),
Toast.LENGTH_SHORT).show();
// TODO: We catch Exception, because after eliminating the service process
@@ -954,7 +865,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
public void stopRecording() {
if (trackRecordingService != null) {
// Save the track id as the shared preference will overwrite the recording track id.
long currentTrackId = recordingTrackId;
long currentTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1);
try {
trackRecordingService.endCurrentTrack();
// TODO: We catch Exception, because after eliminating the service process
@@ -962,10 +873,13 @@ public class MyTracks extends TabActivity implements OnTouchListener,
} catch (Exception e) {
Log.e(TAG, "Unable to stop recording.", e);
}
Intent intent = new Intent(MyTracks.this, TrackDetails.class);
intent.putExtra("trackid", currentTrackId);
intent.putExtra("hasCancelButton", false);
startActivity(intent);
if (currentTrackId > 0) {
Intent intent = new Intent(MyTracks.this, TrackDetails.class);
intent.putExtra("trackid", currentTrackId);
intent.putExtra("hasCancelButton", false);
startActivity(intent);
}
}
tryUnbindTrackRecordingService();
try {
@@ -1259,44 +1173,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
return results;
}
String getSendToGoogleResultMessage() {
StringBuilder message = new StringBuilder();
SendDialog sendToGoogleDialog =
dialogManager.getSendToGoogleDialog();
if (sendToGoogleDialog.getSendToMyMaps()) {
message.append(sendToMyMapsMessage);
}
if (sendToGoogleDialog.getSendToFusionTables()) {
message.append(sendToFusionTablesMessage);
}
if (sendToGoogleDialog.getSendToDocs()) {
if (message.length() > 0) {
message.append(' ');
}
message.append(sendToDocsMessage);
}
if (sendToMyMapsSuccess && sendToFusionTablesSuccess && sendToDocsSuccess) {
message.append(' ');
message.append(getString(R.string.status_mymap_info));
}
return message.toString();
}
/**
* Writes the selected track id to the shared preferences.
* Executed on the UI thread.
*
* @param trackId the id of the track
*/
public void setSelectedTrackId(final long trackId) {
ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges(
sharedPreferences
.edit()
.putLong(getString(R.string.selected_track_key), trackId));
void clearSelectedTrack() {
dataHub.unloadCurrentTrack();
}
long getSelectedTrackId() {
return selectedTrackId;
return dataHub.getSelectedTrackId();
}
/**
@@ -1419,7 +1301,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
// @VisibleForTesting
long getRecordingTrackId() {
return recordingTrackId;
return sharedPreferences.getLong(getString(R.string.recording_track_key), -1);
}
// @VisibleForTesting
@@ -1436,4 +1318,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
ITrackRecordingService getTrackRecordingService() {
return trackRecordingService;
}
public TrackDataHub getDataHub() {
return dataHub;
}
}
@@ -54,28 +54,14 @@ import java.util.Set;
* @author Leif Hendrik Wilden
* @author Rodrigo Damazio
*/
public class MyTracksSettings extends PreferenceActivity {
public static final String SETTINGS_NAME = "MyTracksSettings";
/*
* Default values - keep in sync with those in preferences.xml.
*/
public static final int DEFAULT_AUTO_RESUME_TRACK_TIMEOUT = 10; // In min.
public static final int DEFAULT_ANNOUNCEMENT_FREQUENCY = -1;
public static final int DEFAULT_MAX_RECORDING_DISTANCE = 200;
public static final int DEFAULT_MIN_RECORDING_DISTANCE = 5;
public static final int DEFAULT_MIN_RECORDING_INTERVAL = 0;
public static final int DEFAULT_MIN_REQUIRED_ACCURACY = 200;
public static final int DEFAULT_SPLIT_FREQUENCY = 0;
public class SettingsActivity extends PreferenceActivity {
private BackupPreferencesListener backupListener;
private SharedPreferences preferences;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// The volume we want to control is the Text-To-Speech volume
@@ -86,7 +72,7 @@ public class MyTracksSettings extends PreferenceActivity {
// Tell it where to read/write preferences
PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setSharedPreferencesName(SETTINGS_NAME);
preferenceManager.setSharedPreferencesName(Constants.SETTINGS_NAME);
preferenceManager.setSharedPreferencesMode(0);
// Set up automatic preferences backup
@@ -219,7 +205,7 @@ public class MyTracksSettings extends PreferenceActivity {
@Override
public boolean onPreferenceClick(Preference preference) {
BackupActivityHelper backupHelper =
new BackupActivityHelper(MyTracksSettings.this);
new BackupActivityHelper(SettingsActivity.this);
backupHelper.writeBackup();
return true;
}
@@ -229,7 +215,7 @@ public class MyTracksSettings extends PreferenceActivity {
@Override
public boolean onPreferenceClick(Preference preference) {
BackupActivityHelper backupHelper =
new BackupActivityHelper(MyTracksSettings.this);
new BackupActivityHelper(SettingsActivity.this);
backupHelper.restoreBackup();
return true;
}
@@ -373,7 +359,7 @@ public class MyTracksSettings extends PreferenceActivity {
public void run() {
// Give feedback to the user.
Toast.makeText(
MyTracksSettings.this,
SettingsActivity.this,
R.string.settings_reset_done,
Toast.LENGTH_SHORT).show();
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,169 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import android.location.Location;
/**
* Listener for track data, for both initial and incremental loading.
*
* TODO: Allow listening to just part of the data received here.
*
* @author Rodrigo Damazio
*/
public interface TrackDataListener {
/** States for the GPS location provider. */
public enum ProviderState {
DISABLED,
NO_FIX,
BAD_FIX,
GOOD_FIX;
}
/**
* Called when the location provider changes state.
*/
void onProviderStateChange(ProviderState state);
/**
* Called when the current location changes.
* This is meant for immediate location display only - track point data is
* delivered by other methods below, such as {@link #onNewTrackPoint}.
*
* @param loc the last known location
*/
void onCurrentLocationChanged(Location loc);
/**
* Called when the current heading changes.
*
* @param heading the current heading, already accounting magnetic declination
*/
void onCurrentHeadingChanged(double heading);
// This is always followed by calls to onTrackUpdated/onNewTrackPoints/onWaypointsChanged
// The recipient has a chance to unregister here before that happens.
/**
* Called when the currently-selected track changes.
* This will be followed by calls to data methods such as
* {@link #onTrackUpdated}, {@link #clearTrackPoints},
* {@link #onNewTrackPoint(Location)}, etc., even if no track is currently
* selected (in which case you'll only get calls to clear the current data).
*
* @param track the selected track, or null if no track is selected
* @param isRecording whether we're currently recording the selected track
*/
void onSelectedTrackChanged(Track track, boolean isRecording);
// Called when the already-selected track gets updated
/**
* Called when the track and/or its statistics have been updated.
*
* @param track the updated version of the track
*/
void onTrackUpdated(Track track);
// Map, chart - points, waypoints
// Stats - track
// Points are loaded progressively in batches
// Track is always loaded
// Waypoints are always fully loaded (limit to MyTracksConstants.MAX_DISPLAYED_WAYPOINTS_POINTS)
// Initial load - clear + N * onNewTrackPoint + onNewTrackPointsDone
// New points - onNewTrackPoint + onNewTrackPointsDone
// Points passed in are already sampled (but can be invalid to denote a split)
// If needs to resample, repeats initial load
/**
* Called to clear any previously-sent track points.
* This can be called at any time that we decide the data needs to be
* reloaded, such as when it needs to be resampled.
*/
void clearTrackPoints();
/**
* Called when a new interesting track point is read.
* In this case, interesting means that the point has already undergone
* sampling and invalid point filtering.
*
* @param loc the new track point
*/
void onNewTrackPoint(Location loc);
/**
* Called when a uninteresting track point is read.
* Uninteresting points are all points that get sampled out of the track.
*
* @param loc the new track point
*/
void onSampledOutTrackPoint(Location loc);
/**
* Called when an invalid point (representing a segment split) is read.
*/
void onSegmentSplit();
/**
* Called when we're done (for the time being) sending new points.
* This gets called after every batch of calls to {@link #onNewTrackPoint},
* {@link #onSampledOutTrackPoint} and {@link #onSegmentSplit}.
*/
void onNewTrackPointsDone();
/**
* Called to clear any previously-sent waypoints.
* This can be called at any time that we decide the data needs to be
* reloaded.
*/
void clearWaypoints();
/**
* Called when a new waypoint is read.
*
* @param wpt the new waypoint
*/
void onNewWaypoint(Waypoint wpt);
/**
* Called when we're done (for the time being) sending new waypoints.
* This gets called after every batch of calls to {@link #clearWaypoints} and
* {@link #onNewWaypoint}.
*/
void onNewWaypointsDone();
/**
* Called when the display units are changed by the user.
*
* @param metric true if the units are metric, false if imperial
* @return true to reload all the data, false otherwise
*/
boolean onUnitsChanged(boolean metric);
/**
* Called when the speed/pace display unit is changed by the user.
*
* @param reportSpeed true to report speed, false for pace
* @return true to reload all the data, false otherwise
*/
boolean onReportSpeedChanged(boolean reportSpeed);
}
@@ -202,7 +202,7 @@ public class TrackList extends ListActivity
findViewById(R.id.tracklist_btn_import_all).setOnClickListener(this);
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
getSharedPreferences(Constants.SETTINGS_NAME, 0);
preferences.registerOnSharedPreferenceChangeListener(this);
metricUnits =
preferences.getBoolean(getString(R.string.metric_units_key), true);
@@ -65,7 +65,7 @@ public class WaypointDetails extends Activity
utils = new StatsUtilities(this);
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
getSharedPreferences(Constants.SETTINGS_NAME, 0);
if (preferences != null) {
boolean useMetric =
preferences.getBoolean(getString(R.string.metric_units_key), true);
@@ -59,7 +59,6 @@ public class WaypointsList extends ListActivity
private Button insertWaypointButton = null;
private Button insertStatisticsButton = null;
private long recordingTrackId = -1;
private long selectedTrackId = -1;
private MyTracksProviderUtils providerUtils;
private Cursor waypointsCursor = null;
@@ -139,7 +138,10 @@ public class WaypointsList extends ListActivity
(Button) findViewById(R.id.waypointslist_btn_insert_statistics);
insertStatisticsButton.setOnClickListener(this);
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
getSharedPreferences(Constants.SETTINGS_NAME, 0);
// TODO: Get rid of selected and recording track IDs
long selectedTrackId = -1;
if (preferences != null) {
recordingTrackId =
preferences.getLong(getString(R.string.recording_track_key), -1);
@@ -15,7 +15,7 @@
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -82,6 +82,6 @@ public class WelcomeActivity extends Activity {
AlertDialog dialog = builder.create();
dialog.show();
((TextView) dialog.findViewById(R.id.about_version_register)).
setText(MyTracksUtils.getMyTracksVersion(this));
setText(SystemUtils.getMyTracksVersion(this));
}
}
@@ -17,7 +17,6 @@ package com.google.android.apps.mytracks.io;
import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.io.docs.DocsHelper;
@@ -73,7 +72,7 @@ public class SendToDocs {
this.trackId = trackId;
SharedPreferences preferences = activity.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
if (preferences != null) {
metricUnits =
preferences.getBoolean(activity.getString(R.string.metric_units_key),
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.io;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.ProgressIndicator;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
@@ -25,8 +24,9 @@ import com.google.android.apps.mytracks.io.gdata.GDataWrapper;
import com.google.android.apps.mytracks.io.gdata.GDataWrapper.QueryFunction;
import com.google.android.apps.mytracks.stats.DoubleBuffer;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import com.google.api.client.googleapis.GoogleHeaders;
@@ -141,7 +141,7 @@ public class SendToFusionTables implements Runnable {
this.providerUtils = MyTracksProviderUtils.Factory.get(context);
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("Google-MyTracks-" + MyTracksUtils.getMyTracksVersion(context));
headers.setApplicationName("Google-MyTracks-" + SystemUtils.getMyTracksVersion(context));
headers.gdataVersion = GDATA_VERSION;
transport = new HttpTransport();
@@ -296,7 +296,7 @@ public class SendToFusionTables implements Runnable {
private boolean uploadAllTrackPoints(final Track track, String originalDescription) {
SharedPreferences preferences = context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences preferences = context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
metricUnits = preferences.getBoolean(context.getString(R.string.metric_units_key), true);
@@ -344,7 +344,7 @@ public class SendToFusionTables implements Runnable {
}
// Add to the elevation profile.
if (loc != null && MyTracksUtils.isValidLocation(loc)) {
if (loc != null && LocationUtils.isValidLocation(loc)) {
// All points go into the smoothing buffer...
elevationBuffer.setNext(metricUnits ? loc.getAltitude()
: loc.getAltitude() * UnitConversions.M_TO_FT);
@@ -566,12 +566,12 @@ public class SendToFusionTables implements Runnable {
* Decimate to 2 meter precision. Fusion tables doesn't like too many
* points:
*/
MyTracksUtils.decimate(segment, 2.0);
LocationUtils.decimate(segment, 2.0);
/* If the track still has > 2500 points, split it in pieces: */
final int maxPoints = 2500;
if (segment.getLocations().size() > maxPoints) {
splitTracks.addAll(MyTracksUtils.split(segment, maxPoints));
splitTracks.addAll(LocationUtils.split(segment, maxPoints));
} else if (segment.getLocations().size() >= 2) {
splitTracks.add(segment);
}
@@ -17,7 +17,6 @@ package com.google.android.apps.mytracks.io;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.ProgressIndicator;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
@@ -25,7 +24,7 @@ import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
import com.google.android.apps.mytracks.stats.DoubleBuffer;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
@@ -117,7 +116,7 @@ public class SendToMyMaps implements Runnable {
boolean isNewMap = mapId.equals(NEW_MAP_ID);
if (isNewMap) {
SharedPreferences preferences = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
boolean mapPublic = true;
if (preferences != null) {
mapPublic = preferences.getBoolean(
@@ -196,7 +195,7 @@ public class SendToMyMaps implements Runnable {
private boolean uploadAllTrackPoints(
final Track track, String originalDescription) {
SharedPreferences preferences = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
metricUnits =
@@ -249,7 +248,7 @@ public class SendToMyMaps implements Runnable {
}
// Add to the elevation profile.
if (loc != null && MyTracksUtils.isValidLocation(loc)) {
if (loc != null && LocationUtils.isValidLocation(loc)) {
// All points go into the smoothing buffer...
elevationBuffer.setNext(metricUnits ? loc.getAltitude()
: loc.getAltitude() * UnitConversions.M_TO_FT);
@@ -431,11 +430,11 @@ public class SendToMyMaps implements Runnable {
* Decimate to 2 meter precision. Mapshop doesn't like too many
* points:
*/
MyTracksUtils.decimate(segment, 2.0);
LocationUtils.decimate(segment, 2.0);
/* It the track still has > 500 points, split it in pieces: */
if (segment.getLocations().size() > 500) {
splitTracks.addAll(MyTracksUtils.split(segment, 500));
splitTracks.addAll(LocationUtils.split(segment, 500));
} else if (segment.getLocations().size() >= 2) {
splitTracks.add(segment);
}
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.content.TrackPointsColumns;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.WaypointsColumns;
@@ -201,7 +200,7 @@ class ExternalFileBackup {
// Dump preferences
SharedPreferences preferences =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
preferencesHelper.exportPreferences(preferences, outWriter);
} catch (IOException e) {
// We tried to delete the partially created file, but do nothing
@@ -253,7 +252,7 @@ class ExternalFileBackup {
// Restore preferences
SharedPreferences preferences =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
preferencesHelper.importPreferences(reader, preferences);
} finally {
compressedStream.close();
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
@@ -42,7 +41,7 @@ public class MyTracksBackupAgent extends BackupAgent {
ParcelFileDescriptor newState) throws IOException {
Log.i(Constants.TAG, "Performing backup");
SharedPreferences preferences = this.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
backupPreferences(data, preferences);
Log.i(Constants.TAG, "Backup complete");
@@ -92,7 +91,7 @@ public class MyTracksBackupAgent extends BackupAgent {
}
SharedPreferences preferences = this.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
PreferenceBackupHelper importer = createPreferenceBackupHelper();
importer.importPreferences(dataBuffer, preferences);
}
@@ -13,11 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import android.location.Location;
@@ -13,13 +13,13 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import android.location.Location;
@@ -362,7 +362,7 @@ public class GpxImporter extends DefaultHandler {
* @throws SAXException - thrown if track point is invalid
*/
private void onTrackPointElementEnd() throws SAXException {
if (MyTracksUtils.isValidLocation(location)) {
if (LocationUtils.isValidLocation(location)) {
if (statsBuilder == null) {
// first point did not have a time, start stats builder without it
statsBuilder = new TripStatisticsBuilder(0);
@@ -13,11 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.StringUtils;
import android.location.Location;
@@ -13,11 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.StringUtils;
import android.content.Context;
@@ -13,15 +13,15 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.SystemUtils;
import android.content.Context;
import android.location.Location;
@@ -236,7 +236,7 @@ public class TcxTrackWriter implements TrackFormatWriter {
// it. The TCX schema tightly defined the Version tag, so we can't put it
// there. They've similarly constrained the PartNumber tag, so it can't go
// there either.
pw.format("<Name>My Tracks %s by Google</Name>\n", MyTracksUtils.getMyTracksVersion(context));
pw.format("<Name>My Tracks %s by Google</Name>\n", SystemUtils.getMyTracksVersion(context));
pw.println("<Build>");
@@ -246,11 +246,11 @@ public class TcxTrackWriter implements TrackFormatWriter {
// signify that this build is newer than the one associated with the
// version code given in VersionMajor.
pw.println("<Version>");
pw.format("<VersionMajor>%d</VersionMajor>\n", MyTracksUtils.getMyTracksVersion(context));
pw.format("<VersionMinor>%d</VersionMinor>\n", MyTracksUtils.isRelease(context) ? 0 : 1);
pw.format("<VersionMajor>%s</VersionMajor>\n", SystemUtils.getMyTracksVersion(context));
pw.format("<VersionMinor>%d</VersionMinor>\n", SystemUtils.isRelease(context) ? 0 : 1);
pw.println("</Version>");
pw.format("<Type>%s</Type>\n", MyTracksUtils.isRelease(context) ? TCX_TYPE_RELEASE
pw.format("<Type>%s</Type>\n", SystemUtils.isRelease(context) ? TCX_TYPE_RELEASE
: TCX_TYPE_INTERNAL);
pw.println("</Build>");
pw.format("<LangID>%s</LangID>\n", Locale.getDefault().getLanguage());
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import android.os.Environment;
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksLocation;
@@ -22,7 +22,7 @@ import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -302,7 +302,7 @@ public class TrackWriter {
while (it.hasNext()) {
Location loc = it.next();
boolean isValid = MyTracksUtils.isValidLocation(loc);
boolean isValid = LocationUtils.isValidLocation(loc);
boolean validSegment = isValid && isLastValid;
if (!wroteFirst && validSegment) {
// Found the first two consecutive points which are valid
@@ -14,7 +14,7 @@
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
@@ -15,9 +15,9 @@
*/
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.DialogManager;
import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.maps.mytracks.R;
import android.app.Dialog;
@@ -107,7 +107,7 @@ public class SendDialog extends Dialog {
R.id.sendtogoogle_send_stats_and_points);
SharedPreferences prefs =
getContext().getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
getContext().getSharedPreferences(Constants.SETTINGS_NAME, 0);
if (prefs != null) {
sendToMyMapsCheckBox.setChecked(
prefs.getBoolean(
@@ -138,7 +138,7 @@ public class SendDialog extends Dialog {
@Override
protected void onStop() {
SharedPreferences prefs =
getContext().getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
getContext().getSharedPreferences(Constants.SETTINGS_NAME, 0);
if (prefs != null) {
Editor editor = prefs.edit();
if (editor != null) {
@@ -15,7 +15,7 @@
*/
package com.google.android.apps.mytracks.services;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.maps.mytracks.R;
import android.content.Context;
@@ -58,7 +58,7 @@ class DefaultTrackNameFactory {
/** Determines whether the preferences allow a timestamp-based track name */
protected boolean useTimestampTrackName() {
SharedPreferences prefs =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
return prefs.getBoolean(
context.getString(R.string.timestamp_track_name_key), true);
}
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.services;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.maps.mytracks.R;
import android.content.SharedPreferences;
@@ -45,7 +44,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
public PreferenceManager(TrackRecordingService service) {
this.service = service;
this.sharedPreferences = service.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
if (sharedPreferences == null) {
Log.w(Constants.TAG,
"TrackRecordingService: Couldn't get shared preferences.");
@@ -97,7 +96,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
service.setMinRecordingDistance(
sharedPreferences.getInt(
minRecordingDistanceKey,
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE));
Constants.DEFAULT_MIN_RECORDING_DISTANCE));
Log.d(Constants.TAG,
"TrackRecordingService: minRecordingDistance = "
+ service.getMinRecordingDistance());
@@ -105,12 +104,12 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
if (key == null || key.equals(maxRecordingDistanceKey)) {
service.setMaxRecordingDistance(sharedPreferences.getInt(
maxRecordingDistanceKey,
MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE));
Constants.DEFAULT_MAX_RECORDING_DISTANCE));
}
if (key == null || key.equals(minRecordingIntervalKey)) {
int minRecordingInterval = sharedPreferences.getInt(
minRecordingIntervalKey,
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
Constants.DEFAULT_MIN_RECORDING_INTERVAL);
switch (minRecordingInterval) {
case -2:
// Battery Miser
@@ -136,7 +135,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
if (key == null || key.equals(minRequiredAccuracyKey)) {
service.setMinRequiredAccuracy(sharedPreferences.getInt(
minRequiredAccuracyKey,
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY));
Constants.DEFAULT_MIN_REQUIRED_ACCURACY));
}
if (key == null || key.equals(announcementFrequencyKey)) {
service.setAnnouncementFrequency(
@@ -145,7 +144,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
if (key == null || key.equals(autoResumeTrackTimeoutKey)) {
service.setAutoResumeTrackTimeout(sharedPreferences.getInt(
autoResumeTrackTimeoutKey,
MyTracksSettings.DEFAULT_AUTO_RESUME_TRACK_TIMEOUT));
Constants.DEFAULT_AUTO_RESUME_TRACK_TIMEOUT));
}
if (key == null || key.equals(recordingTrackKey)) {
long recordingTrackId = sharedPreferences.getLong(recordingTrackKey, -1);
@@ -20,7 +20,6 @@ import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME
import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Sensor;
@@ -39,7 +38,7 @@ import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
import com.google.android.apps.mytracks.util.ApiFeatures;
import com.google.android.apps.mytracks.util.ApiPlatformAdapter;
import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -84,13 +83,13 @@ public class TrackRecordingService extends Service implements LocationListener {
private WakeLock wakeLock;
private int minRecordingDistance =
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE;
Constants.DEFAULT_MIN_RECORDING_DISTANCE;
private int maxRecordingDistance =
MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE;
Constants.DEFAULT_MAX_RECORDING_DISTANCE;
private int minRequiredAccuracy =
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY;
Constants.DEFAULT_MIN_REQUIRED_ACCURACY;
private int autoResumeTrackTimeout =
MyTracksSettings.DEFAULT_AUTO_RESUME_TRACK_TIMEOUT;
Constants.DEFAULT_AUTO_RESUME_TRACK_TIMEOUT;
private long recordingTrackId = -1;
@@ -218,7 +217,7 @@ public class TrackRecordingService extends Service implements LocationListener {
// Keep track of length along recorded track (needed when a waypoint is
// inserted):
if (MyTracksUtils.isValidLocation(location)) {
if (LocationUtils.isValidLocation(location)) {
if (lastValidLocation != null) {
length += location.distanceTo(lastValidLocation);
}
@@ -456,7 +455,7 @@ public class TrackRecordingService extends Service implements LocationListener {
if (cursor.moveToLast()) {
do {
Location location = providerUtils.createLocation(cursor);
if (MyTracksUtils.isValidLocation(location)) {
if (LocationUtils.isValidLocation(location)) {
statsBuilder.addLocation(location, location.getTime());
if (lastValidLocation != null) {
length += location.distanceTo(lastValidLocation);
@@ -633,7 +632,7 @@ public class TrackRecordingService extends Service implements LocationListener {
}
private void addLocationToStats(Location location) {
if (MyTracksUtils.isValidLocation(location)) {
if (LocationUtils.isValidLocation(location)) {
long now = System.currentTimeMillis();
statsBuilder.addLocation(location, now);
waypointStatsBuilder.addLocation(location, now);
@@ -841,7 +840,7 @@ public class TrackRecordingService extends Service implements LocationListener {
// Check if we haven't exceeded the maximum number of retry attempts.
SharedPreferences sharedPreferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
getSharedPreferences(Constants.SETTINGS_NAME, 0);
int retries = sharedPreferences.getInt(
getString(R.string.auto_resume_track_current_retry_key), 0);
Log.d(TAG,
@@ -1123,7 +1122,7 @@ public class TrackRecordingService extends Service implements LocationListener {
// Reset the number of auto-resume retries.
setAutoResumeTrackRetries(
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0), 0);
getSharedPreferences(Constants.SETTINGS_NAME, 0), 0);
// Persist the current recording track.
prefManager.setRecordingTrack(recordingTrackId);
@@ -16,7 +16,8 @@
package com.google.android.apps.mytracks.services.sensors;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.services.sensors.ant.AntChannelIdMessage;
import com.google.android.apps.mytracks.services.sensors.ant.AntChannelResponseMessage;
@@ -58,7 +59,7 @@ public class AntDirectSensorManager extends AntSensorManager {
// First read the the device id that we will be pairing with.
SharedPreferences prefs = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
if (prefs != null) {
deviceNumberHRM =
(short) prefs.getInt(context.getString(R.string.ant_heart_rate_sensor_id_key), 0);
@@ -133,7 +134,7 @@ public class AntDirectSensorManager extends AntSensorManager {
Log.i(TAG, "Found device id: " + deviceNumberHRM);
SharedPreferences prefs = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, Context.MODE_PRIVATE);
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(context.getString(R.string.ant_heart_rate_sensor_id_key), deviceNumberHRM);
editor.commit();
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.maps.mytracks.R;
@@ -71,7 +70,7 @@ public class AntSRMSensorManager extends AntSensorManager {
// First read the the device id that we will be announcing.
SharedPreferences prefs = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
if (prefs != null) {
deviceId = (byte) prefs.getInt(
context.getString(R.string.ant_srm_bridge_sensor_id_key),
@@ -133,7 +132,7 @@ public class AntSRMSensorManager extends AntSensorManager {
Log.i(Constants.TAG, "Found device id: " + deviceId);
SharedPreferences prefs = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, Context.MODE_PRIVATE);
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(context.getString(R.string.ant_srm_bridge_sensor_id_key), deviceId);
editor.commit();
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.maps.mytracks.R;
@@ -82,7 +81,7 @@ public class BluetoothSensorManager extends SensorManager {
return;
}
SharedPreferences prefs =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
String address =
prefs.getString(context.getString(R.string.bluetooth_sensor_key), null);
if (address == null) {
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.maps.mytracks.R;
import android.content.Context;
@@ -40,7 +39,7 @@ public class SensorManagerFactory {
*/
public static SensorManager getSensorManager(Context context) {
SharedPreferences prefs =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
if (prefs == null) {
return null;
}
@@ -19,7 +19,7 @@ package com.google.android.apps.mytracks.stats;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.SettingsActivity;
import android.location.Location;
import android.util.Log;
@@ -93,7 +93,7 @@ public class TripStatisticsBuilder {
private long totalLocations = 0;
private int minRecordingDistance =
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE;
Constants.DEFAULT_MIN_RECORDING_DISTANCE;
/**
* Creates a new trip starting at the given time.
@@ -16,7 +16,7 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.maps.mytracks.R;
@@ -50,7 +50,7 @@ public class ChartURLGenerator {
public static String getChartUrl(Vector<Double> distances,
Vector<Double> elevations, Track track, Context context) {
SharedPreferences preferences =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
metricUnits = preferences.getBoolean(
@@ -21,15 +21,7 @@ import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.maps.GeoPoint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.location.Location;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import java.util.ArrayList;
@@ -41,9 +33,7 @@ import java.util.Stack;
*
* @author Leif Hendrik Wilden
*/
public class MyTracksUtils {
private static final int RELEASE_SIGNATURE_HASHCODE = -1855564782;
public class LocationUtils {
/**
* Computes the distance on the two sphere between the point c0 and the line
* segment c1 to c2.
@@ -117,7 +107,7 @@ public class MyTracksUtils {
current = stack.pop();
maxDist = 0;
for (idx = current[0] + 1; idx < current[1]; ++idx) {
dist = MyTracksUtils.distance(
dist = LocationUtils.distance(
locations.get(idx),
locations.get(current[0]),
locations.get(current[1]));
@@ -255,80 +245,9 @@ public class MyTracksUtils {
(int) (location.getLongitude() * 1E6));
}
/**
* Returns whether or not this is a release build.
*/
public static boolean isRelease(Context context) {
try {
Signature [] sigs = context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
for (Signature sig : sigs) {
if (sig.hashCode() == RELEASE_SIGNATURE_HASHCODE) {
return true;
}
}
} catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Unable to get signatures", e);
}
return false;
}
/**
* Get the My Tracks version from the manifest.
*
* @return the version, or an empty string in case of failure.
*/
public static String getMyTracksVersion(Context context) {
try {
PackageInfo pi = context.getPackageManager().getPackageInfo(
"com.google.android.maps.mytracks",
PackageManager.GET_META_DATA);
return pi.versionName;
} catch (NameNotFoundException e) {
Log.w(Constants.TAG, "Failed to get version info.", e);
return "";
}
}
/**
* Tries to acquire a partial wake lock if not already acquired. Logs errors
* and gives up trying in case the wake lock cannot be acquired.
*/
public static WakeLock acquireWakeLock(Activity activity, WakeLock wakeLock) {
Log.i(Constants.TAG, "MyTracksUtils: Acquiring wake lock.");
try {
PowerManager pm = (PowerManager) activity
.getSystemService(Context.POWER_SERVICE);
if (pm == null) {
Log.e(Constants.TAG, "MyTracksUtils: Power manager not found!");
return wakeLock;
}
if (wakeLock == null) {
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
Constants.TAG);
if (wakeLock == null) {
Log.e(Constants.TAG,
"MyTracksUtils: Could not create wake lock (null).");
}
return wakeLock;
}
if (!wakeLock.isHeld()) {
wakeLock.acquire();
if (!wakeLock.isHeld()) {
Log.e(Constants.TAG,
"MyTracksUtils: Could not acquire wake lock.");
}
}
} catch (RuntimeException e) {
Log.e(Constants.TAG,
"MyTracksUtils: Caught unexpected exception: " + e.getMessage(), e);
}
return wakeLock;
}
/**
* This is a utility class w/ only static members.
*/
protected MyTracksUtils() {
private LocationUtils() {
}
}
@@ -15,7 +15,7 @@
*/
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.DescriptionGenerator;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
@@ -245,7 +245,7 @@ public class StringUtils implements DescriptionGenerator {
Vector<Double> elevations) {
boolean displaySpeed = true;
SharedPreferences preferences =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
if (preferences != null) {
displaySpeed =
preferences.getBoolean(context.getString(R.string.report_speed_key), true);
@@ -0,0 +1,111 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.Constants;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
/**
* Utility class for acessing basic Android functionality.
*
* @author Rodrigo Damazio
*/
public class SystemUtils {
private static final int RELEASE_SIGNATURE_HASHCODE = -1855564782;
/**
* Returns whether or not this is a release build.
*/
public static boolean isRelease(Context context) {
try {
Signature [] sigs = context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
for (Signature sig : sigs) {
if (sig.hashCode() == RELEASE_SIGNATURE_HASHCODE) {
return true;
}
}
} catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Unable to get signatures", e);
}
return false;
}
/**
* Get the My Tracks version from the manifest.
*
* @return the version, or an empty string in case of failure.
*/
public static String getMyTracksVersion(Context context) {
try {
PackageInfo pi = context.getPackageManager().getPackageInfo(
"com.google.android.maps.mytracks",
PackageManager.GET_META_DATA);
return pi.versionName;
} catch (NameNotFoundException e) {
Log.w(Constants.TAG, "Failed to get version info.", e);
return "";
}
}
/**
* Tries to acquire a partial wake lock if not already acquired. Logs errors
* and gives up trying in case the wake lock cannot be acquired.
*/
public static WakeLock acquireWakeLock(Activity activity, WakeLock wakeLock) {
Log.i(Constants.TAG, "LocationUtils: Acquiring wake lock.");
try {
PowerManager pm = (PowerManager) activity
.getSystemService(Context.POWER_SERVICE);
if (pm == null) {
Log.e(Constants.TAG, "LocationUtils: Power manager not found!");
return wakeLock;
}
if (wakeLock == null) {
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
Constants.TAG);
if (wakeLock == null) {
Log.e(Constants.TAG,
"LocationUtils: Could not create wake lock (null).");
}
return wakeLock;
}
if (!wakeLock.isHeld()) {
wakeLock.acquire();
if (!wakeLock.isHeld()) {
Log.e(Constants.TAG,
"LocationUtils: Could not acquire wake lock.");
}
}
} catch (RuntimeException e) {
Log.e(Constants.TAG,
"LocationUtils: Caught unexpected exception: " + e.getMessage(), e);
}
return wakeLock;
}
private SystemUtils() {}
}
@@ -36,8 +36,8 @@ public class MyTracksLocation extends Location {
this.sensorDataSet = sd;
}
public MyTracksLocation(String string) {
super(string);
public MyTracksLocation(String provider) {
super(provider);
}
public Sensor.SensorDataSet getSensorDataSet() {
@@ -301,7 +301,7 @@ public interface MyTracksProviderUtils {
* @return a new waypoint object
*/
Waypoint createWaypoint(Cursor cursor);
/**
* A lightweight wrapper around the original {@link Cursor} with a method to clean up.
*/
@@ -312,13 +312,14 @@ public interface MyTracksProviderUtils {
* @return the ID of the most recent track point ID.
*/
long getLocationId();
/**
* Should be called in case the underlying iterator hasn't reached the last record.
* Calling it if it has reached the last record is a no-op.
*/
void close();
}
/**
* A factory for creating new {@class Location}s.
*/
@@ -342,6 +343,24 @@ public interface MyTracksProviderUtils {
return new Location("gps");
}
};
/**
* A location factory which uses two location instances (one for the current location,
* and one for the previous), useful when we need to keep the last location.
*/
public class DoubleBufferedLocationFactory implements LocationFactory {
private final Location locs[] = new MyTracksLocation[] {
new MyTracksLocation("gps"),
new MyTracksLocation("gps")
};
private int lastLoc = 0;
@Override
public Location createLocation() {
lastLoc = (lastLoc + 1) % locs.length;
return locs[lastLoc];
}
}
/**
* Creates a new read-only iterator over all track points for the given track. It provides
@@ -1024,7 +1024,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
cursor = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
@@ -39,17 +39,17 @@ import java.util.List;
*
* @author Bartlomiej Niechwiej
*/
public class MyTracksOverlayTest extends AndroidTestCase {
public class MapOverlayTest extends AndroidTestCase {
private Canvas canvas;
private MockMyTracksOverlay myTracksOverlay;
private MapView mockView;
private Projection mockProjection;
/**
* A mock version of {@code MyTracksOverlay} that does not use
* A mock version of {@code MapOverlay} that does not use
* {@class MapView}.
*/
private class MockMyTracksOverlay extends MyTracksOverlay {
private class MockMyTracksOverlay extends MapOverlay {
public MockMyTracksOverlay(Context context) {
super(context);
}
@@ -1,6 +1,6 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
/**
* Tests for the CSV track exporter.
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import static com.google.android.testing.mocking.AndroidMock.eq;
import static com.google.android.testing.mocking.AndroidMock.expect;
@@ -22,6 +22,7 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
import com.google.android.apps.mytracks.io.file.GpxImporter;
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
import com.google.android.testing.mocking.AndroidMock;
import com.google.android.testing.mocking.UsesMocks;
@@ -1,5 +1,8 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.io.file.GpxTrackWriter;
import com.google.android.apps.mytracks.io.file.TrackFormatWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -1,7 +1,8 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.io.file.KmlTrackWriter;
import com.google.android.apps.mytracks.util.StringUtils;
import android.location.Location;
@@ -1,8 +1,10 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.io.file.TcxTrackWriter;
import com.google.android.apps.mytracks.io.file.TrackFormatWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -13,9 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import static com.google.android.testing.mocking.AndroidMock.expect;
import com.google.android.apps.mytracks.io.file.TempFileCleaner;
import com.google.android.testing.mocking.AndroidMock;
import com.google.android.testing.mocking.UsesMocks;
@@ -1,10 +1,11 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.file.TrackFormatWriter;
import android.test.AndroidTestCase;
@@ -1,6 +1,6 @@
// Copyright 2010 Google Inc. All Rights Reserved.
package com.google.android.apps.mytracks.io;
package com.google.android.apps.mytracks.io.file;
import static org.easymock.EasyMock.expect;
@@ -9,6 +9,8 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
import com.google.android.apps.mytracks.io.file.TrackFormatWriter;
import com.google.android.apps.mytracks.io.file.TrackWriter;
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
@@ -17,7 +17,7 @@ package com.google.android.apps.mytracks.services;
import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksProvider;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
@@ -152,7 +152,7 @@ public class TrackRecordingServiceTest
providerUtils = MyTracksProviderUtils.Factory.get(context);
sharedPreferences = context.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
// Let's use default values.
sharedPreferences.edit().clear().commit();
@@ -16,7 +16,7 @@
package com.google.android.apps.mytracks.services.sensors;
import com.dsi.ant.AntMesg;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.maps.mytracks.R;
@@ -31,7 +31,7 @@ public class AntDirectSensorManagerTest extends AndroidTestCase {
public void setUp() {
sharedPreferences = getContext().getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
// Let's use default values.
sharedPreferences.edit().clear().commit();
manager = new AntDirectSensorManager(getContext());
@@ -1,6 +1,6 @@
package com.google.android.apps.mytracks.services.sensors;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.Constants;
import com.google.android.maps.mytracks.R;
import android.content.SharedPreferences;
@@ -16,7 +16,7 @@ public class SensorManagerFactoryTest extends AndroidTestCase {
super.setUp();
sharedPreferences = getContext().getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
Constants.SETTINGS_NAME, 0);
// Let's use default values.
sharedPreferences.edit().clear().commit();
}