Merge heads

This commit is contained in:
youtaol
2012-05-04 17:04:45 +08:00
parent a12f4bcbe8
commit fd90dcffa6
189 changed files with 3288 additions and 3323 deletions
@@ -0,0 +1,55 @@
/*
* Copyright 2012 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.util.ApiAdapterFactory;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.FragmentActivity;
import android.view.MenuItem;
/**
* An abstract class for all My Tracks activities.
*
* @author Jimmy Shih
*/
public class AbstractMyTracksActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != android.R.id.home) {
return super.onOptionsItemSelected(item);
}
onHomeSelected();
return true;
}
/**
* Callback when the home menu item is selected.
*/
protected void onHomeSelected() {
finish();
}
}
@@ -1,128 +1,59 @@
/*
* Copyright 2012 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.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MenuItem;
import android.widget.ScrollView;
import android.widget.TextView;
import java.util.List;
/**
* Activity for viewing the combined statistics for all the recorded tracks.
*
* Other features to add - menu items to change setings.
* An activity to view aggregated stats from all recorded tracks.
*
* @author Fergus Nelson
*/
public class AggregatedStatsActivity extends Activity implements
OnSharedPreferenceChangeListener {
private final StatsUtilities utils;
private MyTracksProviderUtils tracksProvider;
private boolean metricUnits = true;
public AggregatedStatsActivity() {
this.utils = new StatsUtilities(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
Log.d(Constants.TAG, "StatsActivity: onSharedPreferences changed "
+ key);
if (key != null) {
if (key.equals(getString(R.string.metric_units_key))) {
metricUnits = sharedPreferences.getBoolean(
getString(R.string.metric_units_key), true);
utils.setMetricUnits(metricUnits);
utils.updateUnits();
loadAggregatedStats();
}
}
}
public class AggregatedStatsActivity extends AbstractMyTracksActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.tracksProvider = MyTracksProviderUtils.Factory.get(this);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.stats);
ScrollView sv = ((ScrollView) findViewById(R.id.scrolly));
sv.setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_INSET);
SharedPreferences preferences = getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
if (preferences != null) {
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
preferences.registerOnSharedPreferenceChangeListener(this);
}
utils.setMetricUnits(metricUnits);
utils.updateUnits();
utils.setSpeedLabel(R.id.speed_label, R.string.stat_speed, R.string.stat_pace);
utils.setSpeedLabels();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (metrics.heightPixels > 600) {
((TextView) findViewById(R.id.speed_register)).setTextSize(80.0f);
}
loadAggregatedStats();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != android.R.id.home) {
return false;
}
startActivity(new Intent(this, TrackListActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
setContentView(R.layout.aggregated_stats);
StatsUtils.setTripStatisticsValues(this, getTripStatistics());
StatsUtils.setLocationValues(this, null, false);
}
/**
* 1. Reads tracks from the db
* 2. Merges the trip stats from the tracks
* 3. Updates the view
* Gets the aggregated trip statistics for all the recorded tracks or null if
* there is no track.
*/
private void loadAggregatedStats() {
List<Track> tracks = retrieveTracks();
TripStatistics rollingStats = null;
private TripStatistics getTripStatistics() {
List<Track> tracks = MyTracksProviderUtils.Factory.get(this).getAllTracks();
TripStatistics tripStatistics = null;
if (!tracks.isEmpty()) {
rollingStats = new TripStatistics(tracks.iterator().next()
.getStatistics());
tripStatistics = new TripStatistics(tracks.iterator().next().getStatistics());
for (int i = 1; i < tracks.size(); i++) {
rollingStats.merge(tracks.get(i).getStatistics());
tripStatistics.merge(tracks.get(i).getStatistics());
}
}
updateView(rollingStats);
}
private List<Track> retrieveTracks() {
return tracksProvider.getAllTracks();
}
private void updateView(TripStatistics aggStats) {
if (aggStats != null) {
utils.setAllStats(aggStats);
}
return tripStatistics;
}
}
@@ -48,8 +48,8 @@ public class BootReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
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);
Intent startIntent = new Intent(context, TrackRecordingService.class)
.putExtra(RESUME_TRACK_EXTRA_NAME, true);
context.startService(startIntent);
Intent removeTempFilesIntent = new Intent(context, RemoveTempFilesService.class);
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.ChartValueSeries.ZoomSettings;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
@@ -75,7 +76,7 @@ public class ChartView extends View {
/**
* Unscaled top border of the chart.
*/
private static final int TOP_BORDER = 15;
private static final int TOP_BORDER = 16;
/**
* Device scaled top border of the chart.
@@ -85,7 +86,7 @@ public class ChartView extends View {
/**
* Unscaled bottom border of the chart.
*/
private static final float BOTTOM_BORDER = 40;
private static final float BOTTOM_BORDER = 8;
/**
* Device scaled bottom border of the chart.
@@ -190,7 +191,7 @@ public class ChartView extends View {
pointer.setBounds(0, 0,
pointer.getIntrinsicWidth(), pointer.getIntrinsicHeight());
statsMarker = getResources().getDrawable(R.drawable.ylw_pushpin);
statsMarker = getResources().getDrawable(R.drawable.yellow_pushpin);
markerWidth = statsMarker.getIntrinsicWidth();
markerHeight = statsMarker.getIntrinsicHeight();
statsMarker.setBounds(0, 0, markerWidth, markerHeight);
@@ -214,7 +215,7 @@ public class ChartView extends View {
R.color.elevation_border,
new ZoomSettings(MAX_INTERVALS,
new int[] {5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000}),
R.string.stat_elevation);
R.string.stats_elevation);
series[SPEED_SERIES] =
new ChartValueSeries(context,
@@ -222,7 +223,7 @@ public class ChartView extends View {
R.color.speed_border,
new ZoomSettings(MAX_INTERVALS, 0, Integer.MIN_VALUE,
new int[] {1, 5, 10, 20, 50}),
R.string.stat_speed);
R.string.stats_speed);
series[POWER_SERIES] =
new ChartValueSeries(context,
R.color.power_fill,
@@ -269,8 +270,8 @@ public class ChartView extends View {
public void setReportSpeed(boolean reportSpeed, Context c) {
series[SPEED_SERIES].setTitle(c.getString(reportSpeed
? R.string.stat_speed
: R.string.stat_pace));
? R.string.stats_speed
: R.string.stats_pace));
}
private void addDataPointInternal(double[] theData) {
@@ -485,8 +486,7 @@ public class ChartView extends View {
}
}
if (nearestWaypoint != null && dmin < 100) {
Intent intent = new Intent(getContext(), MarkerDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
Intent intent = IntentUtils.newIntent(getContext(), MarkerDetailActivity.class)
.putExtra(MarkerDetailActivity.EXTRA_MARKER_ID, nearestWaypoint.getId());
getContext().startActivity(intent);
return true;
@@ -509,10 +509,16 @@ public class ChartView extends View {
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
updateEffectiveDimensionsIfChanged(
View.MeasureSpec.getSize(widthMeasureSpec), View.MeasureSpec.getSize(heightMeasureSpec));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas c) {
synchronized (data) {
updateEffectiveDimensionsIfChanged(c);
// Keep original state.
c.save();
@@ -742,13 +748,16 @@ public class ChartView extends View {
/**
* Updates the effective dimensions where the graph will be drawn, only if the
* dimensions of the given canvas have changed since the last call.
* dimensions have changed since the last call.
*
* @param newWidth the new width
* @param newHeight the new height
*/
private void updateEffectiveDimensionsIfChanged(Canvas c) {
if (w != c.getWidth() || h != c.getHeight()) {
private void updateEffectiveDimensionsIfChanged(int newWidth, int newHeight) {
if (w != newWidth || h != newHeight) {
// Dimensions have changed (for example due to orientation change).
w = c.getWidth();
h = c.getHeight();
w = newWidth;
h = newHeight;
updateEffectiveDimensions();
setUpPath();
}
@@ -33,14 +33,6 @@ public abstract class Constants {
*/
public static final String SDCARD_TOP_DIR = "MyTracks";
/*
* Main screen tab tags:
*/
public static final String MAP_TAB_TAG = "map";
public static final String STATS_TAB_TAG = "stats";
public static final String CHART_TAB_TAG = "chart";
/**
* The number of distance readings to smooth to get a stable signal.
*/
@@ -27,7 +27,8 @@ public interface ContextualActionModeCallback {
* Invoked when an item is selected.
*
* @param itemId the context menu item id
* @param id the row id of the item that is selected
* @param position the position of the selected row
* @param id the id of the selected row, if available
*/
public boolean onClick(int itemId, long id);
public boolean onClick(int itemId, int position, long id);
}
@@ -17,14 +17,9 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.fragments.AboutDialogFragment;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.maps.mytracks.R;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.FragmentActivity;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -33,13 +28,11 @@ import android.view.View.OnClickListener;
*
* @author Sandor Dornbush
*/
public class HelpActivity extends FragmentActivity {
public class HelpActivity extends AbstractMyTracksActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.help);
findViewById(R.id.help_ok).setOnClickListener(new OnClickListener() {
@@ -54,14 +47,4 @@ public class HelpActivity extends FragmentActivity {
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != android.R.id.home) {
return false;
}
startActivity(new Intent(this, TrackListActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
}
}
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.UriUtils;
import com.google.android.maps.mytracks.R;
@@ -140,8 +141,8 @@ public class ImportActivity extends Activity {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!importAll && trackId != -1L) {
Intent intent = new Intent(ImportActivity.this, TrackDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
Intent intent = IntentUtils.newIntent(
ImportActivity.this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
}
@@ -21,6 +21,7 @@ import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.maps.TrackPathPainter;
import com.google.android.apps.mytracks.maps.TrackPathPainterFactory;
import com.google.android.apps.mytracks.maps.TrackPathUtilities;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.GeoPoint;
@@ -145,7 +146,7 @@ public class MapOverlay extends Overlay implements OnSharedPreferenceChangeListe
arrow.setBounds(0, 0, arrowWidth, arrowHeight);
}
statsMarker = resources.getDrawable(R.drawable.ylw_pushpin);
statsMarker = resources.getDrawable(R.drawable.yellow_pushpin);
markerWidth = statsMarker.getIntrinsicWidth();
markerHeight = statsMarker.getIntrinsicHeight();
statsMarker.setBounds(0, 0, markerWidth, markerHeight);
@@ -442,10 +443,8 @@ public class MapOverlay extends Overlay implements OnSharedPreferenceChangeListe
}
}
if (waypoint != null &&
dmin < 15000000 / Math.pow(2, mapView.getZoomLevel())) {
Intent intent = new Intent(context, MarkerDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
if (waypoint != null && dmin < 15000000 / Math.pow(2, mapView.getZoomLevel())) {
Intent intent = IntentUtils.newIntent(context, MarkerDetailActivity.class)
.putExtra(MarkerDetailActivity.EXTRA_MARKER_ID, waypoint.getId());
context.startActivity(intent);
return true;
@@ -19,17 +19,12 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -41,18 +36,17 @@ import android.widget.TextView;
*
* @author Leif Hendrik Wilden
*/
public class MarkerDetailActivity extends FragmentActivity {
public class MarkerDetailActivity extends AbstractMyTracksActivity {
public static final String EXTRA_MARKER_ID = "marker_id";
private static final String TAG = MarkerDetailActivity.class.getSimpleName();
private long markerId;
private Waypoint waypoint;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.marker_detail);
markerId = getIntent().getLongExtra(EXTRA_MARKER_ID, -1L);
@@ -62,7 +56,7 @@ public class MarkerDetailActivity extends FragmentActivity {
return;
}
Waypoint waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(markerId);
waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(markerId);
if (waypoint == null) {
Log.d(TAG, "waypoint is null");
finish();
@@ -78,58 +72,17 @@ public class MarkerDetailActivity extends FragmentActivity {
waypointSection.setVisibility(View.VISIBLE);
statisticsSection.setVisibility(View.GONE);
TextView markerType = (TextView) findViewById(R.id.marker_detail_marker_type);
markerType.setText(getString(R.string.marker_detail_marker_type, waypoint.getCategory()));
TextView description = (TextView) findViewById(R.id.marker_detail_description);
description.setText(getString(R.string.marker_detail_description, waypoint.getDescription()));
TextView markerType = (TextView) findViewById(R.id.marker_detail_waypoint_marker_type);
markerType.setText(getString(
R.string.marker_detail_waypoint_marker_type, waypoint.getCategory()));
TextView description = (TextView) findViewById(R.id.marker_detail_waypoint_description);
description.setText(getString(
R.string.marker_detail_waypoint_description, waypoint.getDescription()));
} else {
waypointSection.setVisibility(View.GONE);
statisticsSection.setVisibility(View.VISIBLE);
SharedPreferences preferences = getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
boolean metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
boolean reportSpeed = preferences.getBoolean(getString(R.string.report_speed_key), true);
StatsUtils.setSpeedLabel(this, R.id.marker_detail_max_speed_label, R.string.stat_max_speed,
R.string.stat_fastest_pace, reportSpeed);
StatsUtils.setSpeedLabel(this, R.id.marker_detail_average_speed_label,
R.string.stat_average_speed, R.string.stat_average_pace, reportSpeed);
StatsUtils.setSpeedLabel(this, R.id.marker_detail_average_moving_speed_label,
R.string.stat_average_moving_speed, R.string.stat_average_moving_pace, reportSpeed);
TripStatistics tripStatistics = waypoint.getStatistics();
StatsUtils.setDistanceValue(this, R.id.marker_detail_total_distance_value,
tripStatistics.getTotalDistance(), metricUnits);
StatsUtils.setSpeedValue(this, R.id.marker_detail_max_speed_value,
tripStatistics.getMaxSpeed(), reportSpeed, metricUnits);
StatsUtils.setTimeValue(
this, R.id.marker_detail_total_time_value, tripStatistics.getTotalTime());
StatsUtils.setSpeedValue(this, R.id.marker_detail_average_speed_value,
tripStatistics.getAverageSpeed(), reportSpeed, metricUnits);
StatsUtils.setTimeValue(
this, R.id.marker_detail_moving_time_value, tripStatistics.getMovingTime());
StatsUtils.setSpeedValue(this, R.id.marker_detail_average_moving_speed_value,
tripStatistics.getAverageMovingSpeed(), reportSpeed, metricUnits);
StatsUtils.setAltitudeValue(this, R.id.marker_detail_elevation_value,
waypoint.getLocation().getAltitude(), metricUnits);
StatsUtils.setAltitudeValue(this, R.id.marker_detail_elevation_gain_value,
tripStatistics.getTotalElevationGain(), metricUnits);
StatsUtils.setAltitudeValue(this, R.id.marker_detail_min_elevation_value,
tripStatistics.getMinElevation(), metricUnits);
StatsUtils.setAltitudeValue(this, R.id.marker_detail_max_elevation_value,
tripStatistics.getMaxElevation(), metricUnits);
StatsUtils.setGradeValue(
this, R.id.marker_detail_min_grade_value, tripStatistics.getMinGrade());
StatsUtils.setGradeValue(
this, R.id.marker_detail_max_grade_value, tripStatistics.getMaxGrade());
StatsUtils.setTripStatisticsValues(this, waypoint.getStatistics());
StatsUtils.setLocationValues(this, waypoint.getLocation(), false);
}
}
@@ -139,24 +92,30 @@ public class MarkerDetailActivity extends FragmentActivity {
return true;
}
@Override
protected void onHomeSelected() {
Intent intent = IntentUtils.newIntent(this, MarkerListActivity.class)
.putExtra(MarkerListActivity.EXTRA_TRACK_ID, waypoint.getTrackId());
startActivity(intent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.marker_detail_show_on_map:
startActivity(new Intent(this, TrackDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId));
return true;
intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId);
startActivity(intent);
return true;
case R.id.marker_detail_edit:
startActivity(new Intent(this, MarkerEditActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId));
intent = IntentUtils.newIntent(this, MarkerEditActivity.class)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId);
startActivity(intent);
return true;
case R.id.marker_detail_delete:
DeleteOneMarkerDialogFragment.newInstance(markerId).show(getSupportFragmentManager(),
DeleteOneMarkerDialogFragment.newInstance(markerId, waypoint.getTrackId()).show(
getSupportFragmentManager(),
DeleteOneMarkerDialogFragment.DELETE_ONE_MARKER_DIALOG_TAG);
return true;
default:
@@ -20,81 +20,98 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.content.WaypointCreationRequest.WaypointType;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
/**
* An activity to add/edit a marker.
*
* @author Jimmy Shih
*/
public class MarkerEditActivity extends Activity {
public class MarkerEditActivity extends AbstractMyTracksActivity {
private static final String TAG = MarkerEditActivity.class.getSimpleName();
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_MARKER_ID = "marker_id";
public static final String EXTRA_STATISTICS_MARKER = "statistics_marker";
private long trackId;
private long markerId;
private boolean statisticsMarker;
private TrackRecordingServiceConnection trackRecordingServiceConnection;
private Waypoint waypoint;
// UI elements
private View typeSection;
private RadioGroup type;
private EditText name;
private View statisticsSection;
private EditText statisticsName;
private View waypointSection;
private AutoCompleteTextView markerType;
private EditText description;
private EditText waypointName;
private AutoCompleteTextView waypointMarkerType;
private EditText waypointDescription;
private Button done;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.marker_edit);
trackId = getIntent().getLongExtra(EXTRA_TRACK_ID, -1L);
markerId = getIntent().getLongExtra(EXTRA_MARKER_ID, -1L);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
statisticsMarker = getIntent().getBooleanExtra(EXTRA_STATISTICS_MARKER, true);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
// Setup UI elements
typeSection = findViewById(R.id.marker_edit_type_section);
type = (RadioGroup) findViewById(R.id.marker_edit_type);
type.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
boolean statistics = checkedId == R.id.marker_edit_type_statistics;
name.setText(
statistics ? R.string.marker_edit_type_statistics : R.string.marker_edit_type_waypoint);
updateUiByMarkerType(statistics);
boolean statistics = checkedId == R.id.marker_edit_statistics;
statisticsSection.setVisibility(statistics ? View.VISIBLE : View.GONE);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
int nextMarkerNumber = trackId == -1L ? -1
: MyTracksProviderUtils.Factory.get(MarkerEditActivity.this)
.getNextMarkerNumber(trackId, statistics);
if (statistics) {
String name = nextMarkerNumber == -1 ? getString(R.string.marker_type_statistics)
: getString(R.string.marker_statistics_name_format, nextMarkerNumber);
statisticsName.setText(name);
statisticsName.selectAll();
} else {
String name = nextMarkerNumber == -1 ? getString(R.string.marker_type_waypoint)
: getString(R.string.marker_waypoint_name_format, nextMarkerNumber);
waypointName.setText(name);
waypointName.selectAll();
waypointMarkerType.setText("");
waypointDescription.setText("");
}
}
});
name = (EditText) findViewById(R.id.marker_edit_name);
statisticsSection = findViewById(R.id.marker_edit_statistics_section);
statisticsName = (EditText) findViewById(R.id.marker_edit_statistics_name);
waypointSection = findViewById(R.id.marker_edit_waypoint_section);
markerType = (AutoCompleteTextView) findViewById(R.id.marker_edit_marker_type);
waypointName = (EditText) findViewById(R.id.marker_edit_waypoint_name);
waypointMarkerType = (AutoCompleteTextView) findViewById(R.id.marker_edit_waypoint_marker_type);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.waypoint_types, android.R.layout.simple_dropdown_item_1line);
markerType.setAdapter(adapter);
description = (EditText) findViewById(R.id.marker_edit_description);
waypointMarkerType.setAdapter(adapter);
waypointDescription = (EditText) findViewById(R.id.marker_edit_waypoint_description);
Button cancel = (Button) findViewById(R.id.marker_edit_cancel);
cancel.setOnClickListener(new OnClickListener() {
@@ -113,9 +130,9 @@ public class MarkerEditActivity extends Activity {
private void updateUiByMarkerId() {
final boolean newMarker = markerId == -1L;
setTitle(newMarker ? R.string.marker_edit_add_title : R.string.menu_edit);
setTitle(newMarker ? R.string.menu_insert_marker : R.string.menu_edit);
typeSection.setVisibility(newMarker ? View.VISIBLE : View.GONE);
done.setText(newMarker ? R.string.marker_edit_add : R.string.generic_save);
done.setText(newMarker ? R.string.generic_add : R.string.generic_save);
done.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -129,7 +146,7 @@ public class MarkerEditActivity extends Activity {
});
if (newMarker) {
type.check(R.id.marker_edit_type_statistics);
type.check(statisticsMarker ? R.id.marker_edit_statistics : R.id.marker_edit_waypoint);
} else {
waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(markerId);
if (waypoint == null) {
@@ -137,29 +154,19 @@ public class MarkerEditActivity extends Activity {
finish();
return;
}
name.setText(waypoint.getName());
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
updateUiByMarkerType(statistics);
if (!statistics) {
markerType.setText(waypoint.getCategory());
description.setText(waypoint.getDescription());
}
statisticsSection.setVisibility(statistics ? View.VISIBLE : View.GONE);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
if (statistics) {
statisticsName.setText(waypoint.getName());
} else {
waypointName.setText(waypoint.getName());
waypointMarkerType.setText(waypoint.getCategory());
waypointDescription.setText(waypoint.getDescription());
}
}
}
/**
* Updates the UI by marker type.
*
* @param statistics true for a statistics marker
*/
private void updateUiByMarkerType(boolean statistics) {
name.setCompoundDrawablesWithIntrinsicBounds(
statistics ? R.drawable.ylw_pushpin : R.drawable.blue_pushpin, 0, 0, 0);
name.setImeOptions(statistics ? EditorInfo.IME_ACTION_DONE : EditorInfo.IME_ACTION_NEXT);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
}
@Override
protected void onResume() {
super.onResume();
@@ -172,54 +179,37 @@ public class MarkerEditActivity extends Activity {
trackRecordingServiceConnection.unbind();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != android.R.id.home) {
return false;
}
finish();
return true;
}
/**
* Adds a marker.
*/
private void addMarker() {
boolean statistics = type.getCheckedRadioButtonId() == R.id.marker_edit_type_statistics;
WaypointType waypointType = statistics ? WaypointType.STATISTICS : WaypointType.MARKER;
String markerCategory = statistics ? null : markerType.getText().toString();
String markerDescription = statistics ? null : description.getText().toString();
String markerIconUrl = getString(
statistics ? R.string.marker_statistics_icon_url : R.string.marker_waypoint_icon_url);
boolean statistics = type.getCheckedRadioButtonId() == R.id.marker_edit_statistics;
PreferencesUtils.setBoolean(this, R.string.pick_statistics_marker_key, statistics);
WaypointType waypointType = statistics ? WaypointType.STATISTICS : WaypointType.WAYPOINT;
String markerName = statistics ? statisticsName.getText().toString()
: waypointName.getText().toString();
String markerCategory = statistics ? null : waypointMarkerType.getText().toString();
String markerDescription = statistics ? null : waypointDescription.getText().toString();
String markerIconUrl = getString(statistics ? R.string.marker_statistics_icon_url
: R.string.marker_waypoint_icon_url);
WaypointCreationRequest waypointCreationRequest = new WaypointCreationRequest(
waypointType, name.getText().toString(), markerCategory, markerDescription, markerIconUrl);
ITrackRecordingService trackRecordingService =
trackRecordingServiceConnection.getServiceIfBound();
if (trackRecordingService == null) {
Log.d(TAG, "Unable to add marker, no track recording service");
} else {
try {
if (trackRecordingService.insertWaypoint(waypointCreationRequest) != -1L) {
Toast.makeText(this, R.string.marker_edit_add_success, Toast.LENGTH_SHORT).show();
return;
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to add marker", e);
} catch (IllegalStateException e) {
Log.e(TAG, "Unable to add marker.", e);
}
}
Toast.makeText(this, R.string.marker_edit_add_error, Toast.LENGTH_LONG).show();
waypointType, markerName, markerCategory, markerDescription, markerIconUrl);
TrackRecordingServiceConnectionUtils.addMarker(
this, trackRecordingServiceConnection, waypointCreationRequest);
}
/**
* Saves a marker.
*/
private void saveMarker() {
waypoint.setName(name.getText().toString());
if (waypoint.getType() == Waypoint.TYPE_WAYPOINT) {
waypoint.setCategory(markerType.getText().toString());
waypoint.setDescription(description.getText().toString());
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
if (statistics) {
waypoint.setName(statisticsName.getText().toString());
} else {
waypoint.setName(waypointName.getText().toString());
waypoint.setCategory(waypointMarkerType.getText().toString());
waypoint.setDescription(waypointDescription.getText().toString());
}
MyTracksProviderUtils.Factory.get(this).updateWaypoint(waypoint);
}
@@ -20,7 +20,10 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.MarkerAddDialogFragment;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -31,8 +34,6 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
@@ -48,14 +49,13 @@ import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
/**
* Activity to show a list of markers in a track.
*
* @author Leif Hendrik Wilden
*/
public class MarkerListActivity extends FragmentActivity {
public class MarkerListActivity extends AbstractMyTracksActivity {
public static final String EXTRA_TRACK_ID = "track_id";
@@ -72,7 +72,7 @@ public class MarkerListActivity extends FragmentActivity {
private ContextualActionModeCallback contextualActionModeCallback =
new ContextualActionModeCallback() {
@Override
public boolean onClick(int itemId, long id) {
public boolean onClick(int itemId, int position, long id) {
return handleContextItem(itemId, id);
}
};
@@ -110,9 +110,7 @@ public class MarkerListActivity extends FragmentActivity {
return;
}
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.marker_list);
SharedPreferences sharedPreferences = getSharedPreferences(
@@ -124,12 +122,12 @@ public class MarkerListActivity extends FragmentActivity {
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startActivity(new Intent(MarkerListActivity.this, MarkerDetailActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(MarkerDetailActivity.EXTRA_MARKER_ID, id));
Intent intent = IntentUtils.newIntent(MarkerListActivity.this, MarkerDetailActivity.class)
.putExtra(MarkerDetailActivity.EXTRA_MARKER_ID, id);
startActivity(intent);
}
});
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.marker_list_item, null, 0) {
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) {
@Override
public void bindView(View view, Context context, Cursor cursor) {
int typeIndex = cursor.getColumnIndex(WaypointsColumns.TYPE);
@@ -139,40 +137,22 @@ public class MarkerListActivity extends FragmentActivity {
int descriptionIndex = cursor.getColumnIndex(WaypointsColumns.DESCRIPTION);
boolean statistics = cursor.getInt(typeIndex) == Waypoint.TYPE_STATISTICS;
TextView name = (TextView) view.findViewById(R.id.marker_list_item_name);
name.setText(cursor.getString(nameIndex));
name.setCompoundDrawablesWithIntrinsicBounds(statistics ? R.drawable.ylw_pushpin
: R.drawable.blue_pushpin, 0, 0, 0);
TextView category = (TextView) view.findViewById(R.id.marker_list_item_category);
if (!statistics) {
category.setText(cursor.getString(categoryIndex));
}
category.setVisibility(statistics || category.getText().length() == 0 ? View.GONE : View.VISIBLE);
TextView time = (TextView) view.findViewById(R.id.marker_list_item_time);
long timeValue = cursor.getLong(timeIndex);
if (timeValue == 0) {
time.setVisibility(View.GONE);
} else {
time.setText(StringUtils.formatDateTime(MarkerListActivity.this, timeValue));
time.setVisibility(View.VISIBLE);
}
TextView description = (TextView) view.findViewById(R.id.marker_list_item_description);
if (!statistics) {
description.setText(cursor.getString(descriptionIndex));
}
description.setVisibility(statistics || description.getText().length() == 0 ? View.GONE : View.VISIBLE);
String name = cursor.getString(nameIndex);
int iconId = statistics ? R.drawable.yellow_pushpin : R.drawable.blue_pushpin;
String category = statistics ? null : cursor.getString(categoryIndex);
long time = cursor.getLong(timeIndex);
String startTime = time == 0
? null : StringUtils.formatDateTime(MarkerListActivity.this, time);
String description = statistics ? null : cursor.getString(descriptionIndex);
ListItemUtils.setListItem(view, name, iconId, category, null, null, startTime, description);
}
};
listView.setAdapter(resourceCursorAdapter);
ApiAdapterFactory.getApiAdapter().configureListViewContextualMenu(
this, listView, R.menu.marker_list_context_menu, R.id.marker_list_item_name,
contextualActionModeCallback);
ApiAdapterFactory.getApiAdapter().configureListViewContextualMenu(this, listView,
R.menu.list_context_menu, R.id.list_item_name, contextualActionModeCallback);
final long firstWaypointId = MyTracksProviderUtils.Factory.get(this).getFirstWaypointId(trackId);
final long firstWaypointId = MyTracksProviderUtils.Factory.get(this)
.getFirstWaypointId(trackId);
getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
@@ -215,12 +195,9 @@ public class MarkerListActivity extends FragmentActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.marker_list_insert_marker:
startActivity(new Intent(this, MarkerEditActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
MarkerAddDialogFragment.newInstance(trackId)
.show(getSupportFragmentManager(), MarkerAddDialogFragment.MARKER_ADD_DIALOG_TAG);
return true;
case R.id.marker_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
@@ -232,7 +209,7 @@ public class MarkerListActivity extends FragmentActivity {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.marker_list_context_menu, menu);
getMenuInflater().inflate(R.menu.list_context_menu, menu);
}
@Override
@@ -252,19 +229,21 @@ public class MarkerListActivity extends FragmentActivity {
* @return true if handled.
*/
private boolean handleContextItem(int itemId, long markerId) {
Intent intent;
switch (itemId) {
case R.id.marker_list_context_menu_show_on_map:
startActivity(new Intent(this, TrackDetailActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId));
case R.id.list_context_menu_show_on_map:
intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId);
startActivity(intent);
return true;
case R.id.marker_list_context_menu_edit:
startActivity(new Intent(this, MarkerEditActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId));
case R.id.list_context_menu_edit:
intent = IntentUtils.newIntent(this, MarkerEditActivity.class)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId);
startActivity(intent);
return true;
case R.id.marker_list_context_menu_delete:
DeleteOneMarkerDialogFragment.newInstance(markerId).show(getSupportFragmentManager(),
case R.id.list_context_menu_delete:
DeleteOneMarkerDialogFragment.newInstance(markerId, trackId).show(
getSupportFragmentManager(),
DeleteOneMarkerDialogFragment.DELETE_ONE_MARKER_DIALOG_TAG);
return true;
default:
@@ -39,7 +39,8 @@ public class MyTracksApplication extends Application {
ApiAdapterFactory.getApiAdapter().enableStrictMode();
}
AnalyticsUtils.sendPageViews(this, "/appstart");
startService(new Intent(this, RemoveTempFilesService.class));
Intent intent = new Intent(this, RemoveTempFilesService.class);
startService(intent);
}
/**
@@ -28,17 +28,17 @@ import android.os.Bundle;
import android.widget.Toast;
/**
* An activity to export all the tracks to the SD card.
* An activity to save all the tracks to the SD card.
*
* @author Sandor Dornbush
*/
public class ExportActivity extends Activity {
public class SaveAllActivity extends Activity {
public static final String EXTRA_TRACK_FILE_FORMAT = "track_file_format";
private static final int DIALOG_PROGRESS_ID = 0;
private ExportAsyncTask exportAsyncTask;
private SaveAllAsyncTask saveAllAsyncTask;
private ProgressDialog progressDialog;
@Override
@@ -46,22 +46,22 @@ public class ExportActivity extends Activity {
super.onCreate(savedInstanceState);
Object retained = getLastNonConfigurationInstance();
if (retained instanceof ExportAsyncTask) {
exportAsyncTask = (ExportAsyncTask) retained;
exportAsyncTask.setActivity(this);
if (retained instanceof SaveAllAsyncTask) {
saveAllAsyncTask = (SaveAllAsyncTask) retained;
saveAllAsyncTask.setActivity(this);
} else {
Intent intent = getIntent();
TrackFileFormat trackFileFormat = intent.getParcelableExtra(EXTRA_TRACK_FILE_FORMAT);
exportAsyncTask = new ExportAsyncTask(this, trackFileFormat);
exportAsyncTask.execute();
saveAllAsyncTask = new SaveAllAsyncTask(this, trackFileFormat);
saveAllAsyncTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
exportAsyncTask.setActivity(null);
return exportAsyncTask;
saveAllAsyncTask.setActivity(null);
return saveAllAsyncTask;
}
@Override
@@ -70,10 +70,10 @@ public class ExportActivity extends Activity {
return null;
}
progressDialog = DialogUtils.createHorizontalProgressDialog(
this, R.string.export_progress_message, new DialogInterface.OnCancelListener() {
this, R.string.save_all_progress_message, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
exportAsyncTask.cancel(true);
saveAllAsyncTask.cancel(true);
finish();
}
});
@@ -102,7 +102,7 @@ public class ExportActivity extends Activity {
/**
* Sets the progress dialog value.
*
* @param number the number of tracks exported
* @param number the number of tracks saved
* @param max the maximum number of tracks
*/
public void setProgressDialogValue(int number, int max) {
@@ -31,13 +31,13 @@ import android.os.AsyncTask;
import android.os.PowerManager.WakeLock;
/**
* AsyncTask to export all the tracks to the SD card.
* AsyncTask to save all the tracks to the SD card.
*
* @author Jimmy Shih
*/
public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
public class SaveAllAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private ExportActivity exportActivity;
private SaveAllActivity saveAllActivity;
private final TrackFileFormat trackFileFormat;
private final Context context;
private final MyTracksProviderUtils myTracksProviderUtils;
@@ -56,40 +56,40 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
/**
* Creates an AsyncTask.
*
* @param exportActivity the activity currently associated with this AsyncTask
* @param saveAllActivity the activity currently associated with this AsyncTask
* @param trackFileFormat the track file format
*/
public ExportAsyncTask(ExportActivity exportActivity, TrackFileFormat trackFileFormat) {
this.exportActivity = exportActivity;
public SaveAllAsyncTask(SaveAllActivity saveAllActivity, TrackFileFormat trackFileFormat) {
this.saveAllActivity = saveAllActivity;
this.trackFileFormat = trackFileFormat;
context = exportActivity.getApplicationContext();
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(exportActivity);
context = saveAllActivity.getApplicationContext();
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(saveAllActivity);
// Get the wake lock if not recording
if (PreferencesUtils.getRecordingTrackId(exportActivity) == -1L) {
wakeLock = SystemUtils.acquireWakeLock(exportActivity, wakeLock);
if (PreferencesUtils.getRecordingTrackId(saveAllActivity) == -1L) {
wakeLock = SystemUtils.acquireWakeLock(saveAllActivity, wakeLock);
}
success = false;
completed = false;
messageId = R.string.export_error;
messageId = R.string.save_all_error;
}
/**
* Sets the current {@link ExportActivity} associated with this AyncTask.
* Sets the current {@link SaveAllActivity} associated with this AyncTask.
*
* @param exportActivity the current {@link ExportActivity}, can be null
* @param saveAllActivity the current {@link SaveAllActivity}, can be null
*/
public void setActivity(ExportActivity exportActivity) {
this.exportActivity = exportActivity;
if (completed && exportActivity != null) {
exportActivity.onAsyncTaskCompleted(success, messageId);
public void setActivity(SaveAllActivity saveAllActivity) {
this.saveAllActivity = saveAllActivity;
if (completed && saveAllActivity != null) {
saveAllActivity.onAsyncTaskCompleted(success, messageId);
}
}
@Override
protected void onPreExecute() {
if (exportActivity != null) {
exportActivity.showProgressDialog();
if (saveAllActivity != null) {
saveAllActivity.showProgressDialog();
}
}
@@ -99,7 +99,7 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
try {
cursor = myTracksProviderUtils.getTracksCursor(null, null, TracksColumns._ID);
if (cursor == null) {
messageId = R.string.export_success;
messageId = R.string.save_all_success;
return true;
}
int count = cursor.getCount();
@@ -123,7 +123,7 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
}
publishProgress(i + 1, count);
}
messageId = R.string.export_success;
messageId = R.string.save_all_success;
return true;
} finally {
if (cursor != null) {
@@ -138,8 +138,8 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override
protected void onProgressUpdate(Integer... values) {
if (exportActivity != null) {
exportActivity.setProgressDialogValue(values[0], values[1]);
if (saveAllActivity != null) {
saveAllActivity.setProgressDialogValue(values[0], values[1]);
}
}
@@ -147,8 +147,8 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
protected void onPostExecute(Boolean result) {
success = result;
completed = true;
if (exportActivity != null) {
exportActivity.onAsyncTaskCompleted(success, messageId);
if (saveAllActivity != null) {
saveAllActivity.onAsyncTaskCompleted(success, messageId);
}
}
@@ -1,260 +0,0 @@
/*
* 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 static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.SearchEngine;
import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;
import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
import com.google.android.apps.mytracks.content.SearchEngineProvider;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
/**
* Activity to search for tracks or waypoints.
*
* @author Rodrigo Damazio
*/
public class SearchActivity extends ListActivity {
private static final String ICON_FIELD = "icon";
private static final String NAME_FIELD = "name";
private static final String DESCRIPTION_FIELD = "description";
private static final String CATEGORY_FIELD = "category";
private static final String TIME_FIELD = "time";
private static final String STATS_FIELD = "stats";
private static final String TRACK_ID_FIELD = "trackId";
private static final String WAYPOINT_ID_FIELD = "waypointId";
public static final String EXTRA_TRACK_ID = "track_id";
private static final boolean LOG_SCORES = true;
private MyTracksProviderUtils providerUtils;
private SearchEngine engine;
private LocationManager locationManager;
private SharedPreferences preferences;
private SearchRecentSuggestions suggestions;
private boolean metricUnits;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
providerUtils = MyTracksProviderUtils.Factory.get(this);
engine = new SearchEngine(providerUtils);
suggestions = SearchEngineProvider.newHelper(this);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
setContentView(R.layout.search_list);
handleIntent(getIntent());
}
@Override
protected void onResume() {
super.onResume();
metricUnits =
preferences.getBoolean(getString(R.string.metric_units_key), true);
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (!Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.e(TAG, "Got bad search intent: " + intent);
finish();
return;
}
String textQuery = intent.getStringExtra(SearchManager.QUERY);
Location currentLocation = locationManager.getLastKnownLocation("gps");
long currentTrackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
long currentTimestamp = System.currentTimeMillis();
final SearchQuery query =
new SearchQuery(textQuery, currentLocation, currentTrackId, currentTimestamp);
// Do the actual search in a separate thread.
new Thread() {
@Override
public void run() {
doSearch(query);
}
}.start();
}
private void doSearch(SearchQuery query) {
SortedSet<ScoredResult> scoredResults = engine.search(query);
final List<? extends Map<String, ?>> displayResults = prepareResultsforDisplay(scoredResults);
if (LOG_SCORES) {
Log.i(TAG, "Search scores: " + displayResults);
}
// Then go back to the UI thread to display them.
runOnUiThread(new Runnable() {
@Override
public void run() {
showSearchResults(displayResults);
}
});
// Save the query as a suggestion for the future.
suggestions.saveRecentQuery(query.textQuery, null);
}
private List<Map<String, Object>> prepareResultsforDisplay(
Collection<ScoredResult> scoredResults) {
ArrayList<Map<String, Object>> output = new ArrayList<Map<String, Object>>(scoredResults.size());
for (ScoredResult result : scoredResults) {
Map<String, Object> resultMap = new HashMap<String, Object>();
if (result.track != null) {
prepareTrackForDisplay(result.track, resultMap);
} else {
prepareWaypointForDisplay(result.waypoint, resultMap);
}
resultMap.put("score", result.score);
output.add(resultMap);
}
return output;
}
private void prepareWaypointForDisplay(Waypoint waypoint, Map<String, Object> resultMap) {
// Look up the owner track.
// TODO: It may be more appropriate to do this as a join in the retrieval phase of the search.
String trackName = null;
long trackId = waypoint.getTrackId();
if (trackId > 0) {
Track track = providerUtils.getTrack(trackId);
if (track != null) {
trackName = track.getName();
}
}
resultMap.put(ICON_FIELD, waypoint.getType() == Waypoint.TYPE_STATISTICS
? R.drawable.ylw_pushpin : R.drawable.blue_pushpin);
resultMap.put(NAME_FIELD, waypoint.getName());
resultMap.put(DESCRIPTION_FIELD, waypoint.getDescription());
resultMap.put(CATEGORY_FIELD, waypoint.getCategory());
// In the same place as we show time for tracks, show the track name for waypoints.
resultMap.put(TIME_FIELD, getString(R.string.search_track_location, trackName));
resultMap.put(STATS_FIELD, StringUtils.formatDateTime(this, waypoint.getLocation().getTime()));
resultMap.put(TRACK_ID_FIELD, waypoint.getTrackId());
resultMap.put(WAYPOINT_ID_FIELD, waypoint.getId());
}
private void prepareTrackForDisplay(Track track, Map<String, Object> resultMap) {
TripStatistics stats = track.getStatistics();
resultMap.put(ICON_FIELD, R.drawable.track);
resultMap.put(NAME_FIELD, track.getName());
resultMap.put(DESCRIPTION_FIELD, track.getDescription());
resultMap.put(CATEGORY_FIELD, track.getCategory());
resultMap.put(TIME_FIELD, StringUtils.formatDateTime(this, stats.getStartTime()));
resultMap.put(STATS_FIELD, StringUtils.formatTimeDistance(
this, stats.getTotalTime(), stats.getTotalDistance(), metricUnits));
resultMap.put(TRACK_ID_FIELD, track.getId());
}
/**
* Shows the given search results.
* Must be run from the UI thread.
*
* @param data the results to show, properly ordered
*/
private void showSearchResults(List<? extends Map<String, ?>> data) {
SimpleAdapter adapter = new SimpleAdapter(this, data,
// TODO: Custom view for search results.
R.layout.mytracks_list_item,
new String[] {
ICON_FIELD,
NAME_FIELD,
DESCRIPTION_FIELD,
CATEGORY_FIELD,
TIME_FIELD,
STATS_FIELD,
},
new int[] {
R.id.track_list_item_icon,
R.id.track_list_item_name,
R.id.track_list_item_description,
R.id.track_list_item_category,
R.id.track_list_item_time,
R.id.track_list_item_stats,
});
setListAdapter(adapter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
@SuppressWarnings("unchecked")
Map<String, Object> clickedData = (Map<String, Object>) getListAdapter().getItem(position);
startActivity(createViewDataIntent(clickedData));
}
private Intent createViewDataIntent(Map<String, Object> clickedData) {
Intent intent = new Intent(this, TrackDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
if (clickedData.containsKey(WAYPOINT_ID_FIELD)) {
intent.putExtra(
TrackDetailActivity.EXTRA_MARKER_ID, (Long) clickedData.get(WAYPOINT_ID_FIELD));
} else {
intent.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, (Long) clickedData.get(TRACK_ID_FIELD));
}
return intent;
}
}
@@ -0,0 +1,423 @@
/*
* 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.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.SearchEngine;
import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;
import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
import com.google.android.apps.mytracks.content.SearchEngineProvider;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
/**
* An activity to display a list of search results.
*
* @author Rodrigo Damazio
*/
public class SearchListActivity extends AbstractMyTracksActivity {
private static final String TAG = SearchListActivity.class.getSimpleName();
private static final String NAME_FIELD = "name";
private static final String ICON_FIELD = "icon";
private static final String CATEGORY_FIELD = "category";
private static final String TOTAL_TIME_FIELD = "totalTime";
private static final String TOTAL_DISTANCE_FIELD = "totalDistance";
private static final String START_TIME_FIELD = "startTime";
private static final String DESCRIPTION_FIELD = "description";
private static final String TRACK_ID_FIELD = "trackId";
private static final String MARKER_ID_FIELD = "markerId";
private final OnSharedPreferenceChangeListener
sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (PreferencesUtils.getRecordingTrackIdKey(SearchListActivity.this).equals(key)) {
recordingTrackId = PreferencesUtils.getRecordingTrackId(SearchListActivity.this);
arrayAdapter.notifyDataSetChanged();
}
}
};
// Callback when an item is selected in the contextual action mode
private ContextualActionModeCallback
contextualActionModeCallback = new ContextualActionModeCallback() {
@Override
public boolean onClick(int itemId, int position, long id) {
return handleContextItem(itemId, position);
}
};
private MyTracksProviderUtils myTracksProviderUtils;
private SearchEngine searchEngine;
private SearchRecentSuggestions searchRecentSuggestions;
private LocationManager locationManager;
private long recordingTrackId;
private boolean metricUnits;
private ArrayAdapter<Map<String, Object>> arrayAdapter;
// UI elements
private ListView listView;
private MenuItem searchMenuItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setContentView(R.layout.search_list);
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
searchEngine = new SearchEngine(myTracksProviderUtils);
searchRecentSuggestions = SearchEngineProvider.newHelper(this);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
SharedPreferences sharedPreferences = getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
recordingTrackId = PreferencesUtils.getRecordingTrackId(this);
listView = (ListView) findViewById(R.id.search_list);
listView.setEmptyView(findViewById(R.id.search_list_empty));
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Map<String, Object> item = arrayAdapter.getItem(position);
Long trackId = (Long) item.get(TRACK_ID_FIELD);
Long markerId = (Long) item.get(MARKER_ID_FIELD);
Intent intent;
if (markerId != null) {
intent = IntentUtils.newIntent(SearchListActivity.this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId);
} else {
intent = IntentUtils.newIntent(SearchListActivity.this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
}
startActivity(intent);
}
});
arrayAdapter = new ArrayAdapter<Map<String, Object>>(
this, R.layout.list_item, R.id.list_item_name) {
@Override
public View getView(int position, View convertView, android.view.ViewGroup parent) {
View view;
if (convertView == null) {
view = getLayoutInflater().inflate(R.layout.list_item, parent, false);
} else {
view = convertView;
}
Map<String, Object> resultMap = getItem(position);
String name = (String) resultMap.get(NAME_FIELD);
int iconId = (Integer) resultMap.get(ICON_FIELD);
String category = (String) resultMap.get(CATEGORY_FIELD);
String totalTime = (String) resultMap.get(TOTAL_TIME_FIELD);
String totalDistance = (String) resultMap.get(TOTAL_DISTANCE_FIELD);
String startTime = (String) resultMap.get(START_TIME_FIELD);
String description = (String) resultMap.get(DESCRIPTION_FIELD);
ListItemUtils.setListItem(view,
name,
iconId,
category,
totalTime,
totalDistance,
startTime,
description);
return view;
}
};
listView.setAdapter(arrayAdapter);
ApiAdapterFactory.getApiAdapter().configureListViewContextualMenu(this, listView,
R.menu.list_context_menu, R.id.list_item_name, contextualActionModeCallback);
handleIntent(getIntent());
}
@Override
protected void onResume() {
super.onResume();
metricUnits = PreferencesUtils.isMetricUnits(this);
}
@Override
public void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_list, menu);
searchMenuItem = menu.findItem(R.id.search_list_search);
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.list_context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
if (handleContextItem(item.getItemId(), adapterContextMenuInfo.position)) {
return true;
}
return super.onContextItemSelected(item);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(searchMenuItem)) {
return true;
}
}
return super.onKeyUp(keyCode, event);
}
/**
* Handles a context item selection.
*
* @param itemId the menu item id
* @param position the position of the selected row
* @return true if handled.
*/
private boolean handleContextItem(int itemId, int position) {
Map<String, Object> item = arrayAdapter.getItem(position);
Long trackId = (Long) item.get(TRACK_ID_FIELD);
Long markerId = (Long) item.get(MARKER_ID_FIELD);
Intent intent;
switch (itemId) {
case R.id.list_context_menu_show_on_map:
if (markerId != null) {
intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_MARKER_ID, markerId);
} else {
intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
}
startActivity(intent);
return true;
case R.id.list_context_menu_edit:
if (markerId != null) {
intent = IntentUtils.newIntent(this, MarkerEditActivity.class)
.putExtra(MarkerEditActivity.EXTRA_MARKER_ID, markerId);
} else {
intent = IntentUtils.newIntent(this, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId);
}
startActivity(intent);
// Close the search result since its content can change after edit.
finish();
return true;
case R.id.list_context_menu_delete:
if (markerId != null) {
DeleteOneMarkerDialogFragment.newInstance(markerId, trackId).show(
getSupportFragmentManager(),
DeleteOneMarkerDialogFragment.DELETE_ONE_MARKER_DIALOG_TAG);
} else {
DeleteOneTrackDialogFragment.newInstance(trackId).show(getSupportFragmentManager(),
DeleteOneTrackDialogFragment.DELETE_ONE_TRACK_DIALOG_TAG);
}
return true;
default:
return false;
}
}
/**
* Handles the intent.
*
* @param intent the intent
*/
private void handleIntent(Intent intent) {
if (!Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.e(TAG, "Invalid intent action: " + intent);
finish();
return;
}
String textQuery = intent.getStringExtra(SearchManager.QUERY);
setTitle(textQuery);
Location currentLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
final SearchQuery query = new SearchQuery(textQuery, currentLocation, -1L, System
.currentTimeMillis());
new Thread() {
@Override
public void run() {
doSearch(query);
}
}.start();
}
/**
* Do the search.
*
* @param query the query
*/
private void doSearch(SearchQuery query) {
SortedSet<ScoredResult> scoredResults = searchEngine.search(query);
final List<Map<String, Object>> displayResults = prepareResultsforDisplay(scoredResults);
// Use the UI thread to display the results
runOnUiThread(new Runnable() {
@Override
public void run() {
arrayAdapter.clear();
ApiAdapterFactory.getApiAdapter().addAllToArrayAdapter(arrayAdapter, displayResults);
}
});
// Save the query as a suggestion for the future
searchRecentSuggestions.saveRecentQuery(query.textQuery, null);
}
/**
* Prepares the result for display.
*
* @param scoredResults a list of score results
* @return a list of result maps
*/
private List<Map<String, Object>> prepareResultsforDisplay(
Collection<ScoredResult> scoredResults) {
ArrayList<Map<String, Object>> output = new ArrayList<Map<String, Object>>(scoredResults
.size());
for (ScoredResult result : scoredResults) {
Map<String, Object> resultMap = new HashMap<String, Object>();
if (result.track != null) {
prepareTrackForDisplay(result.track, resultMap);
} else {
prepareMarkerForDisplay(result.waypoint, resultMap);
}
output.add(resultMap);
}
return output;
}
/**
* Prepares a marker for display by filling in a result map.
*
* @param waypoint the marker
* @param resultMap the result map
*/
private void prepareMarkerForDisplay(Waypoint waypoint, Map<String, Object> resultMap) {
/*
* TODO: It may be more appropriate to obtain the track name as a join in
* the retrieval phase of the search.
*/
String trackName = null;
long trackId = waypoint.getTrackId();
if (trackId != -1L) {
Track track = myTracksProviderUtils.getTrack(trackId);
if (track != null) {
trackName = track.getName();
}
}
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
resultMap.put(NAME_FIELD, waypoint.getName());
resultMap.put(ICON_FIELD, statistics ? R.drawable.yellow_pushpin : R.drawable.blue_pushpin);
resultMap.put(CATEGORY_FIELD, statistics ? null : waypoint.getCategory());
long time = waypoint.getLocation().getTime();
String startTime = StringUtils.formatDateTime(this, time);
resultMap.put(START_TIME_FIELD, time == 0 || startTime.equals(trackName) ? null : startTime);
// Display the marker's track name in the total time field
resultMap.put(TOTAL_TIME_FIELD, trackName == null ? null
: getString(R.string.search_list_marker_track_location, trackName));
resultMap.put(TOTAL_DISTANCE_FIELD, null);
resultMap.put(DESCRIPTION_FIELD, statistics ? null : waypoint.getDescription());
resultMap.put(TRACK_ID_FIELD, waypoint.getTrackId());
resultMap.put(MARKER_ID_FIELD, waypoint.getId());
}
/**
* Prepares a track for display by filling in a result map.
*
* @param track the track
* @param resultMap the result map
*/
private void prepareTrackForDisplay(Track track, Map<String, Object> resultMap) {
boolean isRecording = track.getId() == recordingTrackId;
TripStatistics tripStatitics = track.getStatistics();
resultMap.put(NAME_FIELD, track.getName());
resultMap.put(ICON_FIELD, isRecording ? R.drawable.menu_record_track : R.drawable.track);
resultMap.put(CATEGORY_FIELD, track.getCategory());
resultMap.put(TOTAL_TIME_FIELD, isRecording ? null : StringUtils.formatElapsedTime(
tripStatitics.getTotalTime()));
resultMap.put(TOTAL_DISTANCE_FIELD, isRecording ? null : StringUtils.formatDistance(
this, tripStatitics.getTotalDistance(), metricUnits));
String startTime = StringUtils.formatDateTime(this, tripStatitics.getStartTime());
if (startTime.equals(track.getName())) {
startTime = null;
}
resultMap.put(START_TIME_FIELD, startTime);
resultMap.put(DESCRIPTION_FIELD, track.getDescription());
resultMap.put(TRACK_ID_FIELD, track.getId());
resultMap.put(MARKER_ID_FIELD, null);
}
}
@@ -27,7 +27,6 @@ import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import com.google.protobuf.InvalidProtocolBufferException;
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
@@ -41,12 +40,10 @@ import java.util.TimerTask;
*
* @author Sandor Dornbush
*/
public class SensorStateActivity extends Activity {
public class SensorStateActivity extends AbstractMyTracksActivity {
private static final long REFRESH_PERIOD_MS = 250;
private final StatsUtilities utils;
/**
* This timer periodically invokes the refresh timer task.
*/
@@ -91,11 +88,6 @@ public class SensorStateActivity extends Activity {
*/
private boolean isVisible = false;
public SensorStateActivity() {
utils = new StatsUtilities(this);
Log.w(TAG, "SensorStateActivity()");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -239,18 +231,18 @@ public class SensorStateActivity extends Activity {
}
private void updateSensorData(Sensor.SensorDataSet sds) {
if (sds == null) {
utils.setUnknown(R.id.sensor_state_last_sensor_time);
utils.setUnknown(R.id.sensor_state_power);
utils.setUnknown(R.id.sensor_state_cadence);
utils.setUnknown(R.id.sensor_state_battery);
} else {
((TextView) findViewById(R.id.sensor_state_last_sensor_time)).setText(getLastSensorTime(sds));
((TextView) findViewById(R.id.sensor_state_power)).setText(getPower(sds));
((TextView) findViewById(R.id.sensor_state_cadence)).setText(getCadence(sds));
((TextView) findViewById(R.id.sensor_state_heart_rate)).setText(getHeartRate(sds));
((TextView) findViewById(R.id.sensor_state_battery)).setText(getBattery(sds));
}
String lastSensorTime = sds == null ? getString(R.string.value_unknown)
: getLastSensorTime(sds);
String power = sds == null ? getString(R.string.value_unknown) : getPower(sds);
String cadence = sds == null ? getString(R.string.value_unknown) : getCadence(sds);
String heartRate = sds == null ? getString(R.string.value_unknown) : getHeartRate(sds);
String battery = sds == null ? getString(R.string.value_unknown) : getBattery(sds);
((TextView) findViewById(R.id.sensor_state_last_sensor_time)).setText(lastSensorTime);
((TextView) findViewById(R.id.sensor_state_power)).setText(power);
((TextView) findViewById(R.id.sensor_state_cadence)).setText(cadence);
((TextView) findViewById(R.id.sensor_state_heart_rate)).setText(heartRate);
((TextView) findViewById(R.id.sensor_state_battery)).setText(battery);
}
/**
@@ -325,8 +317,7 @@ public class SensorStateActivity extends Activity {
String value;
if (sds.hasBatteryLevel() && sds.getBatteryLevel().hasValue()
&& sds.getBatteryLevel().getState() == Sensor.SensorState.SENDING) {
String format = getString(R.string.value_integer_percent);
value = String.format(format, sds.getBatteryLevel().getValue());
value = getString(R.string.value_integer_percent, sds.getBatteryLevel().getValue());
} else {
value = SensorUtils.getStateAsString(
sds.hasBatteryLevel() ? sds.getBatteryLevel().getState() : Sensor.SensorState.NONE, this);
@@ -24,6 +24,7 @@ import com.google.android.apps.mytracks.services.sensors.ant.AntUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.BluetoothDeviceUtils;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
@@ -130,8 +131,7 @@ public class SettingsActivity extends PreferenceActivity {
// Hook up switching of displayed list entries between metric and imperial
// units
CheckBoxPreference metricUnitsPreference =
(CheckBoxPreference) findPreference(
getString(R.string.metric_units_key));
(CheckBoxPreference) findPreference(PreferencesUtils.getMetricUnitsKey(this));
metricUnitsPreference.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
@Override
@@ -201,7 +201,9 @@ public class SettingsActivity extends PreferenceActivity {
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(SettingsActivity.this, RestoreChooserActivity.class));
Intent intent = IntentUtils.newIntent(
SettingsActivity.this, RestoreChooserActivity.class);
startActivity(intent);
}
});
default:
@@ -361,22 +363,21 @@ public class SettingsActivity extends PreferenceActivity {
: R.string.settings_reset_summary);
// Add actions to the backup preferences
backupNowPreference.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(SettingsActivity.this, BackupActivity.class));
return true;
}
});
restoreNowPreference.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showDialog(DIALOG_CONFIRM_RESTORE_ID);
return true;
}
});
backupNowPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = IntentUtils.newIntent(SettingsActivity.this, BackupActivity.class);
startActivity(intent);
return true;
}
});
restoreNowPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showDialog(DIALOG_CONFIRM_RESTORE_ID);
return true;
}
});
}
@Override
@@ -627,8 +628,8 @@ public class SettingsActivity extends PreferenceActivity {
Toast.LENGTH_SHORT).show();
// Restart the settings activity so all changes are loaded.
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Intent intent = getIntent()
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
@@ -641,9 +642,7 @@ public class SettingsActivity extends PreferenceActivity {
* If the units are not metric convert the value before displaying.
*/
private void viewTrackColorModeSettings(EditTextPreference preference, int id) {
CheckBoxPreference metricUnitsPreference = (CheckBoxPreference) findPreference(
getString(R.string.metric_units_key));
if(metricUnitsPreference.isChecked()) {
if (PreferencesUtils.isMetricUnits(this)) {
return;
}
// Convert miles/h to km/h
@@ -663,10 +662,10 @@ public class SettingsActivity extends PreferenceActivity {
* If the units are not metric convert the value before saving.
*/
private void validateTrackColorModeSettings(String newValue, int id) {
CheckBoxPreference metricUnitsPreference = (CheckBoxPreference) findPreference(
getString(R.string.metric_units_key));
String metricspeed;
if(!metricUnitsPreference.isChecked()) {
if (PreferencesUtils.isMetricUnits(this)) {
metricspeed = newValue;
} else {
// Convert miles/h to km/h
try {
metricspeed = String.valueOf(
@@ -674,8 +673,6 @@ public class SettingsActivity extends PreferenceActivity {
} catch (NumberFormatException e) {
metricspeed = "0";
}
} else {
metricspeed = newValue;
}
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
Editor editor = prefs.edit();
@@ -1,270 +0,0 @@
/*
* Copyright 2009 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.stats.TripStatistics;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.util.Log;
import android.widget.TextView;
import java.text.NumberFormat;
/**
* Various utility functions for views that display statistics information.
*
* @deprecated use {@link StatsUtils}.
*
* @author Sandor Dornbush
*/
public class StatsUtilities {
private final Activity activity;
private static final NumberFormat LAT_LONG_FORMAT = NumberFormat.getNumberInstance();
private static final NumberFormat ALTITUDE_FORMAT = NumberFormat.getIntegerInstance();
private static final NumberFormat SPEED_FORMAT = NumberFormat.getNumberInstance();
private static final NumberFormat GRADE_FORMAT = NumberFormat.getPercentInstance();
static {
LAT_LONG_FORMAT.setMaximumFractionDigits(5);
LAT_LONG_FORMAT.setMinimumFractionDigits(5);
SPEED_FORMAT.setMaximumFractionDigits(2);
SPEED_FORMAT.setMinimumFractionDigits(2);
GRADE_FORMAT.setMaximumFractionDigits(1);
GRADE_FORMAT.setMinimumFractionDigits(1);
}
/**
* True if distances should be displayed in metric units (from shared
* preferences).
*/
private boolean metricUnits = true;
/**
* True - report speed
* False - report pace
*/
private boolean reportSpeed = true;
public StatsUtilities(Activity a) {
this.activity = a;
}
public boolean isMetricUnits() {
return metricUnits;
}
public void setMetricUnits(boolean metricUnits) {
this.metricUnits = metricUnits;
}
public boolean isReportSpeed() {
return reportSpeed;
}
public void setReportSpeed(boolean reportSpeed) {
this.reportSpeed = reportSpeed;
}
public void setUnknown(int id) {
((TextView) activity.findViewById(id)).setText(R.string.value_unknown);
}
public void setText(int id, double d, NumberFormat format) {
if (!Double.isNaN(d) && !Double.isInfinite(d)) {
setText(id, format.format(d));
} else {
setUnknown(id);
}
}
public void setText(int id, String s) {
int lengthLimit = 8;
String displayString = s.length() > lengthLimit
? s.substring(0, lengthLimit - 3) + "..."
: s;
((TextView) activity.findViewById(id)).setText(displayString);
}
public void setLatLong(int id, double d) {
TextView msgTextView = (TextView) activity.findViewById(id);
msgTextView.setText(LAT_LONG_FORMAT.format(d));
}
public void setAltitude(int id, double d) {
setText(id, (metricUnits ? d : (d * UnitConversions.M_TO_FT)),
ALTITUDE_FORMAT);
}
public void setDistance(int id, double d) {
setText(id, (metricUnits ? d : (d * UnitConversions.KM_TO_MI)),
SPEED_FORMAT);
}
public void setSpeed(int id, double d) {
if (d == 0) {
setUnknown(id);
return;
}
double speed = metricUnits ? d : d * UnitConversions.KM_TO_MI;
if (reportSpeed) {
setText(id, speed, SPEED_FORMAT);
} else {
// Format as milliseconds per unit
long pace = (long) (3600000.0 / speed);
setTime(id, pace);
}
}
public void setAltitudeUnits(int unitLabelId) {
TextView unitTextView = (TextView) activity.findViewById(unitLabelId);
unitTextView.setText(metricUnits ? R.string.unit_meter : R.string.unit_feet);
}
public void setDistanceUnits(int unitLabelId) {
TextView unitTextView = (TextView) activity.findViewById(unitLabelId);
unitTextView.setText(metricUnits ? R.string.unit_kilometer : R.string.unit_mile);
}
public void setSpeedUnits(int unitLabelId, int unitLabelBottomId) {
TextView unitTextView = (TextView) activity.findViewById(unitLabelId);
unitTextView.setText(reportSpeed
? (metricUnits ? R.string.unit_kilometer : R.string.unit_mile)
: R.string.unit_minute);
unitTextView = (TextView) activity.findViewById(unitLabelBottomId);
unitTextView.setText(reportSpeed
? R.string.unit_hour
: (metricUnits ? R.string.unit_kilometer : R.string.unit_mile));
}
public void setTime(int id, long l) {
setText(id, StringUtils.formatElapsedTime(l));
}
public void setGrade(int id, double d) {
setText(id, d, GRADE_FORMAT);
}
/**
* Updates the unit fields.
*/
public void updateUnits() {
setSpeedUnits(R.id.speed_unit_label_top, R.id.speed_unit_label_bottom);
updateWaypointUnits();
}
/**
* Updates the units fields used by waypoints.
*/
public void updateWaypointUnits() {
setSpeedUnits(R.id.average_moving_speed_unit_label_top,
R.id.average_moving_speed_unit_label_bottom);
setSpeedUnits(R.id.average_speed_unit_label_top,
R.id.average_speed_unit_label_bottom);
setDistanceUnits(R.id.total_distance_unit_label);
setSpeedUnits(R.id.max_speed_unit_label_top,
R.id.max_speed_unit_label_bottom);
setAltitudeUnits(R.id.elevation_unit_label);
setAltitudeUnits(R.id.elevation_gain_unit_label);
setAltitudeUnits(R.id.min_elevation_unit_label);
setAltitudeUnits(R.id.max_elevation_unit_label);
}
/**
* Sets all fields to "-" (unknown).
*/
public void setAllToUnknown() {
// "Instant" values:
setUnknown(R.id.elevation_register);
setUnknown(R.id.latitude_register);
setUnknown(R.id.longitude_register);
setUnknown(R.id.speed_register);
// Values from provider:
setUnknown(R.id.total_time_register);
setUnknown(R.id.moving_time_register);
setUnknown(R.id.total_distance_register);
setUnknown(R.id.average_speed_register);
setUnknown(R.id.average_moving_speed_register);
setUnknown(R.id.max_speed_register);
setUnknown(R.id.min_elevation_register);
setUnknown(R.id.max_elevation_register);
setUnknown(R.id.elevation_gain_register);
setUnknown(R.id.min_grade_register);
setUnknown(R.id.max_grade_register);
}
public void setAllStats(long movingTime, double totalDistance,
double averageSpeed, double averageMovingSpeed, double maxSpeed,
double minElevation, double maxElevation, double elevationGain,
double minGrade, double maxGrade) {
setTime(R.id.moving_time_register, movingTime);
setDistance(R.id.total_distance_register, totalDistance * UnitConversions.M_TO_KM);
setSpeed(R.id.average_speed_register, averageSpeed * UnitConversions.MS_TO_KMH);
setSpeed(R.id.average_moving_speed_register, averageMovingSpeed * UnitConversions.MS_TO_KMH);
setSpeed(R.id.max_speed_register, maxSpeed * UnitConversions.MS_TO_KMH);
setAltitude(R.id.min_elevation_register, minElevation);
setAltitude(R.id.max_elevation_register, maxElevation);
setAltitude(R.id.elevation_gain_register, elevationGain);
setGrade(R.id.min_grade_register, minGrade);
setGrade(R.id.max_grade_register, maxGrade);
}
public void setAllStats(TripStatistics stats) {
setTime(R.id.moving_time_register, stats.getMovingTime());
setDistance(R.id.total_distance_register, stats.getTotalDistance() * UnitConversions.M_TO_KM);
setSpeed(R.id.average_speed_register, stats.getAverageSpeed() * UnitConversions.MS_TO_KMH);
setSpeed(R.id.average_moving_speed_register,
stats.getAverageMovingSpeed() * UnitConversions.MS_TO_KMH);
setSpeed(R.id.max_speed_register, stats.getMaxSpeed() * UnitConversions.MS_TO_KMH);
setAltitude(R.id.min_elevation_register, stats.getMinElevation());
setAltitude(R.id.max_elevation_register, stats.getMaxElevation());
setAltitude(R.id.elevation_gain_register, stats.getTotalElevationGain());
setGrade(R.id.min_grade_register, stats.getMinGrade());
setGrade(R.id.max_grade_register, stats.getMaxGrade());
setTime(R.id.total_time_register, stats.getTotalTime());
}
public void setSpeedLabel(int id, int speedString, int paceString) {
Log.w(Constants.TAG, "Setting view " + id +
" to " + reportSpeed +
" speed: " + speedString +
" pace: " + paceString);
TextView tv = ((TextView) activity.findViewById(id));
if (tv != null) {
tv.setText(reportSpeed ? speedString : paceString);
} else {
Log.w(Constants.TAG, "Could not find id: " + id);
}
}
public void setSpeedLabels() {
setSpeedLabel(R.id.average_speed_label,
R.string.stat_average_speed,
R.string.stat_average_pace);
setSpeedLabel(R.id.average_moving_speed_label,
R.string.stat_average_moving_speed,
R.string.stat_average_moving_pace);
setSpeedLabel(R.id.max_speed_label,
R.string.stat_max_speed,
R.string.stat_fastest_pace);
}
}
@@ -16,10 +16,6 @@
package com.google.android.apps.mytracks;
import static com.google.android.apps.mytracks.Constants.CHART_TAB_TAG;
import static com.google.android.apps.mytracks.Constants.MAP_TAB_TAG;
import static com.google.android.apps.mytracks.Constants.STATS_TAB_TAG;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.Waypoint;
@@ -29,15 +25,18 @@ import com.google.android.apps.mytracks.fragments.ChartSettingsDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.InstallEarthDialogFragment;
import com.google.android.apps.mytracks.fragments.MapFragment;
import com.google.android.apps.mytracks.fragments.MarkerAddDialogFragment;
import com.google.android.apps.mytracks.fragments.StatsFragment;
import com.google.android.apps.mytracks.fragments.StatsSettingsDialogFragment;
import com.google.android.apps.mytracks.fragments.StatsSettingsDialogFragment.OnStatsSettingsChangedListener;
import com.google.android.apps.mytracks.io.file.SaveActivity;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sendtogoogle.UploadServiceChooserActivity;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
@@ -50,9 +49,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -60,7 +56,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.Toast;
import java.util.List;
@@ -70,7 +65,8 @@ import java.util.List;
* @author Leif Hendrik Wilden
* @author Rodrigo Damazio
*/
public class TrackDetailActivity extends FragmentActivity {
public class TrackDetailActivity extends AbstractMyTracksActivity
implements OnStatsSettingsChangedListener {
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_MARKER_ID = "marker_id";
@@ -101,15 +97,15 @@ public class TrackDetailActivity extends FragmentActivity {
* class. Anonymous inner class will get garbage collected.
*/
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener =
new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
// Note that key can be null
if (PreferencesUtils.getRecordingTrackIdKey(TrackDetailActivity.this).equals(key)) {
updateMenu();
}
}
};
new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
// Note that key can be null
if (PreferencesUtils.getRecordingTrackIdKey(TrackDetailActivity.this).equals(key)) {
updateMenu();
}
}
};
/**
* We are not displaying driving directions. Just an arbitrary track that is
@@ -133,9 +129,7 @@ public class TrackDetailActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().hideTitle(this);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.track_detail);
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
@@ -143,21 +137,20 @@ public class TrackDetailActivity extends FragmentActivity {
trackDataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
mapViewContainer = getLayoutInflater().inflate(R.layout.mytracks_layout, null);
mapViewContainer = getLayoutInflater().inflate(R.layout.map, null);
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabManager = new TabManager(this, tabHost, R.id.realtabcontent);
TabSpec mapTabSpec = tabHost.newTabSpec(MAP_TAB_TAG).setIndicator(
getString(R.string.track_detail_map_tab),
getResources().getDrawable(android.R.drawable.ic_menu_mapmode));
TabSpec mapTabSpec = tabHost.newTabSpec(MapFragment.MAP_FRAGMENT_TAG).setIndicator(
getString(R.string.track_detail_map_tab), getResources().getDrawable(R.drawable.tab_map));
tabManager.addTab(mapTabSpec, MapFragment.class, null);
TabSpec chartTabSpec = tabHost.newTabSpec(CHART_TAB_TAG).setIndicator(
TabSpec chartTabSpec = tabHost.newTabSpec(ChartFragment.CHART_FRAGMENT_TAG).setIndicator(
getString(R.string.track_detail_chart_tab),
getResources().getDrawable(R.drawable.menu_elevation));
getResources().getDrawable(R.drawable.tab_chart));
tabManager.addTab(chartTabSpec, ChartFragment.class, null);
TabSpec statsTabSpec = tabHost.newTabSpec(STATS_TAB_TAG).setIndicator(
TabSpec statsTabSpec = tabHost.newTabSpec(StatsFragment.STATS_FRAGMENT_TAG).setIndicator(
getString(R.string.track_detail_stats_tab),
getResources().getDrawable(R.drawable.ic_menu_statistics));
getResources().getDrawable(R.drawable.tab_stats));
tabManager.addTab(statsTabSpec, StatsFragment.class, null);
if (savedInstanceState != null) {
tabHost.setCurrentTabByTag(savedInstanceState.getString(CURRENT_TAG_KEY));
@@ -165,13 +158,13 @@ public class TrackDetailActivity extends FragmentActivity {
handleIntent(getIntent());
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
handleIntent(intent);
}
}
@Override
protected void onStart() {
super.onStart();
@@ -240,39 +233,51 @@ public class TrackDetailActivity extends FragmentActivity {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
String currentTabTag = tabHost.getCurrentTabTag();
menu.findItem(R.id.track_detail_chart_settings).setVisible(CHART_TAB_TAG.equals(currentTabTag));
menu.findItem(R.id.track_detail_my_location).setVisible(MAP_TAB_TAG.equals(currentTabTag));
// Set map or satellite mode
MapFragment mapFragment = (MapFragment) getSupportFragmentManager()
.findFragmentByTag(MAP_TAB_TAG);
boolean isSatelliteMode = mapFragment != null ? mapFragment.isSatelliteView() : false;
menu.findItem(R.id.track_detail_satellite_mode).setVisible(MAP_TAB_TAG.equals(currentTabTag))
.setTitle(isSatelliteMode ? R.string.menu_map_mode : R.string.menu_satellite_mode);
menu.findItem(R.id.track_detail_chart_settings).setVisible(
ChartFragment.CHART_FRAGMENT_TAG.equals(currentTabTag));
menu.findItem(R.id.track_detail_stats_settings).setVisible(
StatsFragment.STATS_FRAGMENT_TAG.equals(currentTabTag));
MenuItem satelliteMode = menu.findItem(R.id.track_detail_satellite_mode)
.setVisible(MapFragment.MAP_FRAGMENT_TAG.equals(currentTabTag));
if (satelliteMode.isVisible()) {
MapFragment mapFragment = (MapFragment) getSupportFragmentManager()
.findFragmentByTag(MapFragment.MAP_FRAGMENT_TAG);
/*
* The current tag is mapFragment, thus safe to call its methods like
* isSatelliteView.
*/
boolean isSatelliteMode = mapFragment != null ? mapFragment.isSatelliteView() : false;
menu.findItem(R.id.track_detail_satellite_mode).setTitle(
isSatelliteMode ? R.string.menu_map_mode : R.string.menu_satellite_mode);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
protected void onHomeSelected() {
Intent intent = IntentUtils.newIntent(this, TrackListActivity.class);
startActivity(intent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
MapFragment mapFragment;
Intent intent;
switch (item.getItemId()) {
case android.R.id.home:
startTrackListActivity();
return true;
case R.id.track_detail_stop_recording:
updateMenuItems(false);
TrackRecordingServiceConnectionUtils.stop(this, trackRecordingServiceConnection);
return true;
case R.id.track_detail_insert_marker:
startActivity(new Intent(this, MarkerEditActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
MarkerAddDialogFragment.newInstance(trackId)
.show(getSupportFragmentManager(), MarkerAddDialogFragment.MARKER_ADD_DIALOG_TAG);
return true;
case R.id.track_detail_play:
if (isEarthInstalled()) {
AnalyticsUtils.sendPageViews(this, "/action/play");
intent = new Intent(this, SaveActivity.class)
intent = IntentUtils.newIntent(this, SaveActivity.class)
.putExtra(SaveActivity.EXTRA_TRACK_ID, trackId)
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.KML)
.putExtra(SaveActivity.EXTRA_PLAY_TRACK, true);
@@ -282,13 +287,13 @@ public class TrackDetailActivity extends FragmentActivity {
getSupportFragmentManager(), InstallEarthDialogFragment.INSTALL_EARTH_DIALOG_TAG);
}
return true;
case R.id.track_detail_share_map:
intent = new Intent(this, UploadServiceChooserActivity.class)
case R.id.track_detail_share_map_url:
intent = IntentUtils.newIntent(this, UploadServiceChooserActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, false, false));
startActivity(intent);
return true;
case R.id.track_detail_share_fusion_table:
intent = new Intent(this, UploadServiceChooserActivity.class)
case R.id.track_detail_share_fusion_table_url:
intent = IntentUtils.newIntent(this, UploadServiceChooserActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, false, true, false));
startActivity(intent);
return true;
@@ -305,13 +310,12 @@ public class TrackDetailActivity extends FragmentActivity {
startSaveActivity(TrackFileFormat.TCX, true);
return true;
case R.id.track_detail_markers:
intent = new Intent(this, MarkerListActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
intent = IntentUtils.newIntent(this, MarkerListActivity.class)
.putExtra(MarkerListActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
return true;
case R.id.track_detail_send_google:
intent = new Intent(this, UploadServiceChooserActivity.class)
intent = IntentUtils.newIntent(this, UploadServiceChooserActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, true, true));
startActivity(intent);
return true;
@@ -328,40 +332,43 @@ public class TrackDetailActivity extends FragmentActivity {
startSaveActivity(TrackFileFormat.TCX, false);
return true;
case R.id.track_detail_edit:
startActivity(new Intent(this, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId));
intent = IntentUtils.newIntent(this, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
return true;
case R.id.track_detail_delete:
DeleteOneTrackDialogFragment.newInstance(trackId).show(
getSupportFragmentManager(), DeleteOneTrackDialogFragment.DELETE_ONE_TRACK_DIALOG_TAG);
return true;
case R.id.track_detail_my_location:
mapFragment = (MapFragment) getSupportFragmentManager().findFragmentByTag(MAP_TAB_TAG);
if (mapFragment != null) {
mapFragment.showMyLocation();
}
return true;
case R.id.track_detail_satellite_mode:
mapFragment = (MapFragment) getSupportFragmentManager().findFragmentByTag(MAP_TAB_TAG);
mapFragment = (MapFragment) getSupportFragmentManager()
.findFragmentByTag(MapFragment.MAP_FRAGMENT_TAG);
if (mapFragment != null) {
mapFragment.setSatelliteView(!mapFragment.isSatelliteView());
}
return true;
case R.id.track_detail_sensor_state:
intent = IntentUtils.newIntent(this, SensorStateActivity.class);
startActivity(intent);
return true;
case R.id.track_detail_chart_settings:
new ChartSettingsDialogFragment().show(
getSupportFragmentManager(), ChartSettingsDialogFragment.CHART_SETTINGS_DIALOG_TAG);
return true;
case R.id.track_detail_sensor_state:
startActivity(new Intent(this, SensorStateActivity.class));
case R.id.track_detail_stats_settings:
new StatsSettingsDialogFragment().show(
getSupportFragmentManager(), StatsSettingsDialogFragment.STATS_SETTINGS_DIALOG_TAG);
return true;
case R.id.track_detail_settings:
startActivity(new Intent(this, SettingsActivity.class));
intent = IntentUtils.newIntent(this, SettingsActivity.class);
startActivity(intent);
return true;
case R.id.track_detail_help:
startActivity(new Intent(this, HelpActivity.class));
intent = IntentUtils.newIntent(this, HelpActivity.class);
startActivity(intent);
return true;
default:
return false;
return super.onOptionsItemSelected(item);
}
}
@@ -369,25 +376,8 @@ public class TrackDetailActivity extends FragmentActivity {
public boolean onTrackballEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (TrackRecordingServiceConnectionUtils.isRecording(this, trackRecordingServiceConnection)) {
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
.getServiceIfBound();
if (trackRecordingService == null) {
Log.e(TAG, "The track recording service is null");
return true;
}
boolean success = false;
try {
long waypointId = trackRecordingService.insertWaypoint(
WaypointCreationRequest.DEFAULT_STATISTICS);
if (waypointId != -1L) {
success = true;
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to insert waypoint", e);
}
Toast.makeText(this,
success ? R.string.marker_edit_add_success : R.string.marker_edit_add_error,
success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
TrackRecordingServiceConnectionUtils.addMarker(
this, trackRecordingServiceConnection, WaypointCreationRequest.DEFAULT_STATISTICS);
return true;
}
}
@@ -401,6 +391,13 @@ public class TrackDetailActivity extends FragmentActivity {
return mapViewContainer;
}
@Override
public void onStatsSettingsChanged() {
StatsFragment statsFragment = (StatsFragment) getSupportFragmentManager()
.findFragmentByTag(StatsFragment.STATS_FRAGMENT_TAG);
statsFragment.updateUi();
}
/**
* Handles the data in the intent.
*/
@@ -410,14 +407,16 @@ public class TrackDetailActivity extends FragmentActivity {
if (markerId != -1L) {
Waypoint waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(markerId);
if (waypoint == null) {
startTrackListActivity();
Intent newIntent = IntentUtils.newIntent(this, TrackListActivity.class);
startActivity(newIntent);
finish();
return;
}
trackId = waypoint.getTrackId();
}
if (trackId == -1L) {
startTrackListActivity();
Intent newIntent = IntentUtils.newIntent(this, TrackListActivity.class);
startActivity(newIntent);
finish();
return;
}
@@ -425,9 +424,9 @@ public class TrackDetailActivity extends FragmentActivity {
if (markerId != -1L) {
MapFragment mapFragmet = (MapFragment) getSupportFragmentManager()
.findFragmentByTag(MAP_TAB_TAG);
.findFragmentByTag(MapFragment.MAP_FRAGMENT_TAG);
if (mapFragmet != null) {
tabHost.setCurrentTabByTag(MAP_TAB_TAG);
tabHost.setCurrentTabByTag(MapFragment.MAP_FRAGMENT_TAG);
mapFragmet.showMarker(trackId, markerId);
} else {
Log.e(TAG, "MapFragment is null");
@@ -474,14 +473,6 @@ public class TrackDetailActivity extends FragmentActivity {
}
}
/**
* Starts the {@link TrackListActivity}.
*/
private void startTrackListActivity() {
startActivity(new Intent(this, TrackListActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
}
/**
* Starts the {@link SaveActivity} to save a track.
*
@@ -489,7 +480,7 @@ public class TrackDetailActivity extends FragmentActivity {
* @param shareTrack true to share the track after saving
*/
private void startSaveActivity(TrackFileFormat trackFileFormat, boolean shareTrack) {
Intent intent = new Intent(this, SaveActivity.class)
Intent intent = IntentUtils.newIntent(this, SaveActivity.class)
.putExtra(SaveActivity.EXTRA_TRACK_ID, trackId)
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) trackFileFormat)
.putExtra(SaveActivity.EXTRA_SHARE_TRACK, shareTrack);
@@ -18,16 +18,11 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
@@ -39,10 +34,10 @@ import android.widget.EditText;
*
* @author Leif Hendrik Wilden
*/
public class TrackEditActivity extends Activity implements OnClickListener {
public class TrackEditActivity extends AbstractMyTracksActivity {
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_SHOW_CANCEL = "show_cancel";
public static final String EXTRA_NEW_TRACK = "new_track";
private static final String TAG = TrackEditActivity.class.getSimpleName();
@@ -57,8 +52,6 @@ public class TrackEditActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
ApiAdapterFactory.getApiAdapter().configureActionBarHomeAsUp(this);
setContentView(R.layout.track_edit);
trackId = getIntent().getLongExtra(EXTRA_TRACK_ID, -1L);
@@ -89,36 +82,30 @@ public class TrackEditActivity extends Activity implements OnClickListener {
description.setText(track.getDescription());
Button save = (Button) findViewById(R.id.track_edit_save);
save.setOnClickListener(this);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
track.setName(name.getText().toString());
track.setCategory(activityType.getText().toString());
track.setDescription(description.getText().toString());
myTracksProviderUtils.updateTrack(track);
finish();
}
});
Button cancel = (Button) findViewById(R.id.track_edit_cancel);
if (getIntent().getBooleanExtra(EXTRA_SHOW_CANCEL, true)) {
setTitle(R.string.menu_edit);
cancel.setOnClickListener(this);
cancel.setVisibility(View.VISIBLE);
} else {
if (getIntent().getBooleanExtra(EXTRA_NEW_TRACK, false)) {
setTitle(R.string.track_edit_new_track_title);
cancel.setVisibility(View.GONE);
} else {
setTitle(R.string.menu_edit);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
cancel.setVisibility(View.VISIBLE);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != android.R.id.home) {
return false;
}
finish();
return true;
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.track_edit_save) {
track.setName(name.getText().toString());
track.setCategory(activityType.getText().toString());
track.setDescription(description.getText().toString());
myTracksProviderUtils.updateTrack(track);
}
finish();
}
}
@@ -17,14 +17,18 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.fragments.CheckUnitsDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteAllTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.EulaDialogFragment;
import com.google.android.apps.mytracks.fragments.WelcomeDialogFragment;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.EulaUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
@@ -56,7 +60,6 @@ import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
/**
@@ -93,10 +96,11 @@ public class TrackListActivity extends FragmentActivity {
try {
recordingTrackId = service.startNewTrack();
startNewRecording = false;
startTrackDetailActivity(recordingTrackId);
Intent intent = IntentUtils.newIntent(TrackListActivity.this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, recordingTrackId);
startActivity(intent);
Toast.makeText(
TrackListActivity.this, R.string.track_list_record_success, Toast.LENGTH_SHORT).show();
Log.d(TAG, "Started a new recording");
} catch (Exception e) {
Toast.makeText(TrackListActivity.this, R.string.track_list_record_error, Toast.LENGTH_LONG)
.show();
@@ -113,9 +117,11 @@ public class TrackListActivity extends FragmentActivity {
sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
boolean updateList = false;
// Note that key can be null
if (getString(R.string.metric_units_key).equals(key)) {
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
if (PreferencesUtils.getMetricUnitsKey(TrackListActivity.this).equals(key)) {
metricUnits = PreferencesUtils.isMetricUnits(TrackListActivity.this);
updateList = true;
}
if (PreferencesUtils.getRecordingTrackIdKey(TrackListActivity.this).equals(key)) {
recordingTrackId = PreferencesUtils.getRecordingTrackId(TrackListActivity.this);
@@ -124,8 +130,11 @@ public class TrackListActivity extends FragmentActivity {
trackRecordingServiceConnection.startAndBind();
}
updateMenu();
updateList = true;
}
if (updateList) {
resourceCursorAdapter.notifyDataSetChanged();
}
resourceCursorAdapter.notifyDataSetChanged();
}
};
@@ -133,7 +142,7 @@ public class TrackListActivity extends FragmentActivity {
private ContextualActionModeCallback contextualActionModeCallback =
new ContextualActionModeCallback() {
@Override
public boolean onClick(int itemId, long id) {
public boolean onClick(int itemId, int position, long id) {
return handleContextItem(itemId, id);
}
};
@@ -150,8 +159,8 @@ public class TrackListActivity extends FragmentActivity {
private MenuItem recordTrackMenuItem;
private MenuItem stopRecordingMenuItem;
private MenuItem searchMenuItem;
private MenuItem importAllMenuItem;
private MenuItem exportAllMenuItem;
private MenuItem importMenuItem;
private MenuItem saveAllMenuItem;
private MenuItem deleteAllMenuItem;
@Override
@@ -167,7 +176,7 @@ public class TrackListActivity extends FragmentActivity {
SharedPreferences sharedPreferences = getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
metricUnits = sharedPreferences.getBoolean(getString(R.string.metric_units_key), true);
metricUnits = PreferencesUtils.isMetricUnits(this);
recordingTrackId = PreferencesUtils.getRecordingTrackId(this);
ImageButton recordImageButton = (ImageButton) findViewById(R.id.track_list_record_button);
@@ -184,11 +193,13 @@ public class TrackListActivity extends FragmentActivity {
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startTrackDetailActivity(id);
Intent intent = IntentUtils.newIntent(TrackListActivity.this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, id);
startActivity(intent);
}
});
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.track_list_item, null, 0) {
@Override
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) {
@Override
public void bindView(View view, Context context, Cursor cursor) {
int idIndex = cursor.getColumnIndex(TracksColumns._ID);
int nameIndex = cursor.getColumnIndex(TracksColumns.NAME);
@@ -199,37 +210,32 @@ public class TrackListActivity extends FragmentActivity {
int descriptionIndex = cursor.getColumnIndex(TracksColumns.DESCRIPTION);
boolean isRecording = cursor.getLong(idIndex) == recordingTrackId;
TextView name = (TextView) view.findViewById(R.id.track_list_item_name);
name.setText(cursor.getString(nameIndex));
name.setCompoundDrawablesWithIntrinsicBounds(
isRecording ? R.drawable.menu_record_track : R.drawable.track, 0, 0, 0);
TextView category = (TextView) view.findViewById(R.id.track_list_item_category);
category.setText(cursor.getString(categoryIndex));
TextView time = (TextView) view.findViewById(R.id.track_list_item_time);
time.setText(StringUtils.formatElapsedTime(cursor.getLong(timeIndex)));
time.setVisibility(isRecording ? View.GONE : View.VISIBLE);
TextView distance = (TextView) view.findViewById(R.id.track_list_item_distance);
distance.setText(StringUtils.formatDistance(
TrackListActivity.this, cursor.getDouble(distanceIndex), metricUnits));
distance.setVisibility(isRecording ? View.GONE : View.VISIBLE);
TextView start = (TextView) view.findViewById(R.id.track_list_item_start);
start.setText(
StringUtils.formatDateTime(TrackListActivity.this, cursor.getLong(startIndex)));
start.setVisibility(start.getText().equals(name.getText()) ? View.GONE : View.VISIBLE);
TextView description = (TextView) view.findViewById(R.id.track_list_item_description);
description.setText(cursor.getString(descriptionIndex));
description.setVisibility(description.getText().length() == 0 ? View.GONE : View.VISIBLE);
String name = cursor.getString(nameIndex);
int iconId = isRecording ? R.drawable.menu_record_track : R.drawable.track;
String category = cursor.getString(categoryIndex);
String totalTime = isRecording
? null : StringUtils.formatElapsedTime(cursor.getLong(timeIndex));
String totalDistance = isRecording ? null : StringUtils.formatDistance(
TrackListActivity.this, cursor.getDouble(distanceIndex), metricUnits);
String startTime =
StringUtils.formatDateTime(TrackListActivity.this, cursor.getLong(startIndex));
if (startTime.equals(name)) {
startTime = null;
}
String description = cursor.getString(descriptionIndex);
ListItemUtils.setListItem(view,
name,
iconId,
category,
totalTime,
totalDistance,
startTime,
description);
}
};
listView.setAdapter(resourceCursorAdapter);
ApiAdapterFactory.getApiAdapter().configureListViewContextualMenu(
this, listView, R.menu.track_list_context_menu, R.id.track_list_item_name,
this, listView, R.menu.list_context_menu, R.id.list_item_name,
contextualActionModeCallback);
getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
@@ -254,15 +260,48 @@ public class TrackListActivity extends FragmentActivity {
}
});
showStartupDialogs();
}
/**
* Shows start up dialogs.
*/
public void showStartupDialogs() {
if (!EulaUtils.getEulaValue(this)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(EulaDialogFragment.EULA_DIALOG_TAG);
if (fragment == null) {
EulaDialogFragment.newInstance(false).show(
getSupportFragmentManager(), EulaDialogFragment.EULA_DIALOG_TAG);
EulaDialogFragment.newInstance(false)
.show(getSupportFragmentManager(), EulaDialogFragment.EULA_DIALOG_TAG);
}
} else if (PreferencesUtils.isShowWelcomeDialog(this)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(WelcomeDialogFragment.WELCOME_DIALOG_TAG);
if (fragment == null) {
new WelcomeDialogFragment().show(
getSupportFragmentManager(), WelcomeDialogFragment.WELCOME_DIALOG_TAG);
}
} else if (PreferencesUtils.isShowCheckUnitsDialog(this)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(CheckUnitsDialogFragment.CHECK_UNITS_DIALOG_TAG);
if (fragment == null) {
new CheckUnitsDialogFragment().show(
getSupportFragmentManager(), CheckUnitsDialogFragment.CHECK_UNITS_DIALOG_TAG);
}
} else {
enableEmptyView();
}
}
/**
* Enables the content of the empty view.
*/
private void enableEmptyView() {
View emptyMessage = findViewById(R.id.track_list_empty_message);
emptyMessage.setVisibility(View.VISIBLE);
View recordButton = findViewById(R.id.track_list_record_button);
recordButton.setVisibility(View.VISIBLE);
}
@Override
protected void onResume() {
@@ -280,20 +319,20 @@ public class TrackListActivity extends FragmentActivity {
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.track_list, menu);
String fileTypes[] = getResources().getStringArray(R.array.file_types);
menu.findItem(R.id.track_list_export_gpx)
.setTitle(getString(R.string.menu_export_all_format, fileTypes[0]));
menu.findItem(R.id.track_list_export_kml)
.setTitle(getString(R.string.menu_export_all_format, fileTypes[1]));
menu.findItem(R.id.track_list_export_csv)
.setTitle(getString(R.string.menu_export_all_format, fileTypes[2]));
menu.findItem(R.id.track_list_export_tcx)
.setTitle(getString(R.string.menu_export_all_format, fileTypes[3]));
menu.findItem(R.id.track_list_save_all_gpx)
.setTitle(getString(R.string.menu_save_format, fileTypes[0]));
menu.findItem(R.id.track_list_save_all_kml)
.setTitle(getString(R.string.menu_save_format, fileTypes[1]));
menu.findItem(R.id.track_list_save_all_csv)
.setTitle(getString(R.string.menu_save_format, fileTypes[2]));
menu.findItem(R.id.track_list_save_all_tcx)
.setTitle(getString(R.string.menu_save_format, fileTypes[3]));
recordTrackMenuItem = menu.findItem(R.id.track_list_record_track);
stopRecordingMenuItem = menu.findItem(R.id.track_list_stop_recording);
searchMenuItem = menu.findItem(R.id.track_list_search);
importAllMenuItem = menu.findItem(R.id.track_list_import_all);
exportAllMenuItem = menu.findItem(R.id.track_list_export_all);
importMenuItem = menu.findItem(R.id.track_list_import);
saveAllMenuItem = menu.findItem(R.id.track_list_save_all);
deleteAllMenuItem = menu.findItem(R.id.track_list_delete_all);
ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem);
@@ -321,11 +360,11 @@ public class TrackListActivity extends FragmentActivity {
if (stopRecordingMenuItem != null) {
stopRecordingMenuItem.setVisible(isRecording);
}
if (importAllMenuItem != null) {
importAllMenuItem.setVisible(!isRecording);
if (importMenuItem != null) {
importMenuItem.setVisible(!isRecording);
}
if (exportAllMenuItem != null) {
exportAllMenuItem.setVisible(!isRecording);
if (saveAllMenuItem != null) {
saveAllMenuItem.setVisible(!isRecording);
}
if (deleteAllMenuItem != null) {
deleteAllMenuItem.setVisible(!isRecording);
@@ -334,6 +373,7 @@ public class TrackListActivity extends FragmentActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
case R.id.track_list_record_track:
updateMenuItems(true);
@@ -345,38 +385,46 @@ public class TrackListActivity extends FragmentActivity {
return true;
case R.id.track_list_search:
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
case R.id.track_list_import_all:
startActivity(
new Intent(this, ImportActivity.class).putExtra(ImportActivity.EXTRA_IMPORT_ALL, true));
case R.id.track_list_import:
intent = IntentUtils.newIntent(this, ImportActivity.class)
.putExtra(ImportActivity.EXTRA_IMPORT_ALL, true);
startActivity(intent);
return true;
case R.id.track_list_export_gpx:
startActivity(new Intent(this, ExportActivity.class).putExtra(
ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.GPX));
case R.id.track_list_save_all_gpx:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.GPX);
startActivity(intent);
return true;
case R.id.track_list_export_kml:
startActivity(new Intent(this, ExportActivity.class).putExtra(
ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.KML));
case R.id.track_list_save_all_kml:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.KML);
startActivity(intent);
return true;
case R.id.track_list_export_csv:
startActivity(new Intent(this, ExportActivity.class).putExtra(
ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.CSV));
case R.id.track_list_save_all_csv:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.CSV);
startActivity(intent);
return true;
case R.id.track_list_export_tcx:
startActivity(new Intent(this, ExportActivity.class).putExtra(
ExportActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.TCX));
case R.id.track_list_save_all_tcx:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.TCX);
startActivity(intent);
return true;
case R.id.track_list_delete_all:
new DeleteAllTrackDialogFragment().show(
getSupportFragmentManager(), DeleteAllTrackDialogFragment.DELETE_ALL_TRACK_DIALOG_TAG);
return true;
case R.id.track_list_aggregated_statistics:
startActivity(new Intent(this, AggregatedStatsActivity.class));
intent = IntentUtils.newIntent(this, AggregatedStatsActivity.class);
startActivity(intent);
return true;
case R.id.track_list_settings:
startActivity(new Intent(this, SettingsActivity.class));
intent = IntentUtils.newIntent(this, SettingsActivity.class);
startActivity(intent);
return true;
case R.id.track_list_help:
startActivity(new Intent(this, HelpActivity.class));
intent = IntentUtils.newIntent(this, HelpActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
@@ -386,7 +434,7 @@ public class TrackListActivity extends FragmentActivity {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.track_list_context_menu, menu);
getMenuInflater().inflate(R.menu.list_context_menu, menu);
}
@Override
@@ -396,21 +444,28 @@ public class TrackListActivity extends FragmentActivity {
}
return super.onContextItemSelected(item);
}
/**
* Handles a context item selection.
*
*
* @param itemId the menu item id
* @param trackId the track id
* @return true if handled.
*/
private boolean handleContextItem(int itemId, long trackId) {
Intent intent;
switch (itemId) {
case R.id.track_list_context_menu_edit:
startActivity(new Intent(this, TrackEditActivity.class).putExtra(
TrackEditActivity.EXTRA_TRACK_ID, trackId));
case R.id.list_context_menu_show_on_map:
intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
return true;
case R.id.track_list_context_menu_delete:
case R.id.list_context_menu_edit:
intent = IntentUtils.newIntent(this, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
return true;
case R.id.list_context_menu_delete:
DeleteOneTrackDialogFragment.newInstance(trackId).show(
getSupportFragmentManager(), DeleteOneTrackDialogFragment.DELETE_ONE_TRACK_DIALOG_TAG);
return true;
@@ -418,18 +473,6 @@ public class TrackListActivity extends FragmentActivity {
return false;
}
}
/**
* Starts {@link TrackDetailActivity}.
*
* @param trackId the track id.
*/
private void startTrackDetailActivity(long trackId) {
Intent intent = new Intent(TrackListActivity.this, TrackDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
}
/**
* Starts a new recording.
@@ -60,8 +60,6 @@ public class TrackDataHub {
// Preference keys
private final String MIN_REQUIRED_ACCURACY_KEY;
private final String METRIC_UNITS_KEY;
private final String SPEED_REPORTING_KEY;
// Overridable constants
private final int targetNumPoints;
@@ -171,7 +169,7 @@ public class TrackDataHub {
// Cached preference values
private int minRequiredAccuracy;
private boolean useMetricUnits;
private boolean metricUnits;
private boolean reportSpeed;
// Cached sensor readings
@@ -222,8 +220,6 @@ public class TrackDataHub {
this.locationFactory = new DoubleBufferedLocationFactory();
MIN_REQUIRED_ACCURACY_KEY = context.getString(R.string.min_required_accuracy_key);
METRIC_UNITS_KEY = context.getString(R.string.metric_units_key);
SPEED_REPORTING_KEY = context.getString(R.string.report_speed_key);
resetState();
}
@@ -299,8 +295,8 @@ public class TrackDataHub {
private void loadSharedPreferences() {
selectedTrackId = PreferencesUtils.getSelectedTrackId(context);
useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true);
reportSpeed = preferences.getBoolean(SPEED_REPORTING_KEY, true);
metricUnits = PreferencesUtils.isMetricUnits(context);
reportSpeed = PreferencesUtils.isReportSpeed(context);
minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY,
DEFAULT_MIN_REQUIRED_ACCURACY);
}
@@ -495,7 +491,7 @@ public class TrackDataHub {
Set<TrackDataListener> listenerSet = Collections.singleton(listener);
if (registration.isInterestedIn(ListenerDataType.DISPLAY_PREFERENCES)) {
reloadAll |= listener.onUnitsChanged(useMetricUnits);
reloadAll |= listener.onUnitsChanged(metricUnits);
reloadAll |= listener.onReportSpeedChanged(reportSpeed);
}
@@ -577,7 +573,7 @@ public class TrackDataHub {
// Ignore the return values here, we're already sending the full data set anyway
for (TrackDataListener listener :
getListenersFor(ListenerDataType.DISPLAY_PREFERENCES)) {
listener.onUnitsChanged(useMetricUnits);
listener.onUnitsChanged(metricUnits);
listener.onReportSpeedChanged(reportSpeed);
}
@@ -616,11 +612,11 @@ public class TrackDataHub {
if (MIN_REQUIRED_ACCURACY_KEY.equals(key)) {
minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY,
DEFAULT_MIN_REQUIRED_ACCURACY);
} else if (METRIC_UNITS_KEY.equals(key)) {
useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true);
} else if (PreferencesUtils.getMetricUnitsKey(context).equals(key)) {
metricUnits = PreferencesUtils.isMetricUnits(context);
notifyUnitsChanged();
} else if (SPEED_REPORTING_KEY.equals(key)) {
reportSpeed = preferences.getBoolean(SPEED_REPORTING_KEY, true);
} else if (PreferencesUtils.getReportSpeedKey(context).equals(key)) {
reportSpeed = PreferencesUtils.isReportSpeed(context);
notifySpeedReportingChanged();
} else if (PreferencesUtils.getSelectedTrackIdKey(context).equals(key)) {
loadTrack(PreferencesUtils.getSelectedTrackId(context));
@@ -659,7 +655,7 @@ public class TrackDataHub {
Set<TrackDataListener> displayListeners = getListenersFor(ListenerDataType.DISPLAY_PREFERENCES);
for (TrackDataListener listener : displayListeners) {
if (listener.onUnitsChanged(useMetricUnits)) {
if (listener.onUnitsChanged(metricUnits)) {
synchronized (dataListeners) {
reloadDataForListener(listener);
}
@@ -42,7 +42,6 @@ public class AboutDialogFragment extends DialogFragment {
TextView aboutVersion = (TextView) view.findViewById(R.id.about_version);
aboutVersion.setText(SystemUtils.getMyTracksVersion(getActivity()));
return new AlertDialog.Builder(getActivity())
.setCancelable(true)
.setNegativeButton(R.string.about_license, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@@ -42,7 +42,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ZoomControls;
import java.util.ArrayList;
@@ -56,6 +55,8 @@ import java.util.EnumSet;
*/
public class ChartFragment extends Fragment implements TrackDataListener {
public static final String CHART_FRAGMENT_TAG = "chartFragment";
// Android reports 128 when the speed is invalid
private static final int INVALID_SPEED = 128;
private final DoubleBuffer elevationBuffer = new DoubleBuffer(
@@ -77,7 +78,6 @@ public class ChartFragment extends Fragment implements TrackDataListener {
// UI elements
private ChartView chartView;
private LinearLayout busyPane;
private ZoomControls zoomControls;
/**
@@ -91,7 +91,6 @@ public class ChartFragment extends Fragment implements TrackDataListener {
return;
}
busyPane.setVisibility(View.GONE);
zoomControls.setIsZoomInEnabled(chartView.canZoomIn());
zoomControls.setIsZoomOutEnabled(chartView.canZoomOut());
chartView.setShowPointer(isRecording());
@@ -113,9 +112,8 @@ public class ChartFragment extends Fragment implements TrackDataListener {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mytracks_charts, container, false);
busyPane = (LinearLayout) view.findViewById(R.id.elevation_busypane);
zoomControls = (ZoomControls) view.findViewById(R.id.elevation_zoom);
View view = inflater.inflate(R.layout.chart, container, false);
zoomControls = (ZoomControls) view.findViewById(R.id.chart_zoom_controls);
zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -134,9 +132,10 @@ public class ChartFragment extends Fragment implements TrackDataListener {
@Override
public void onStart() {
super.onStart();
ViewGroup layout = (ViewGroup) getActivity().findViewById(R.id.elevation_chart);
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
ViewGroup layout = (ViewGroup) getActivity().findViewById(R.id.chart_view_layout);
@SuppressWarnings("deprecation")
LayoutParams layoutParams = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
layout.addView(chartView, layoutParams);
}
@@ -156,7 +155,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
@Override
public void onStop() {
super.onStop();
ViewGroup layout = (ViewGroup) getActivity().findViewById(R.id.elevation_chart);
ViewGroup layout = (ViewGroup) getActivity().findViewById(R.id.chart_view_layout);
layout.removeView(chartView);
}
@@ -229,12 +228,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
@Override
public void onSelectedTrackChanged(Track track, boolean isRecording) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
busyPane.setVisibility(View.VISIBLE);
}
});
// We don't care.
}
@Override
@@ -16,8 +16,6 @@
package com.google.android.apps.mytracks.fragments;
import static com.google.android.apps.mytracks.Constants.CHART_TAB_TAG;
import com.google.android.apps.mytracks.ChartView;
import com.google.android.maps.mytracks.R;
@@ -42,7 +40,7 @@ public class ChartSettingsDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final ChartFragment chartFragment = (ChartFragment) getActivity()
.getSupportFragmentManager().findFragmentByTag(CHART_TAB_TAG);
.getSupportFragmentManager().findFragmentByTag(ChartFragment.CHART_FRAGMENT_TAG);
View view = getActivity().getLayoutInflater().inflate(R.layout.chart_settings, null);
final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.chart_settings_x);
radioGroup.check(chartFragment.getMode() == ChartView.Mode.BY_DISTANCE
@@ -63,10 +61,9 @@ public class ChartSettingsDialogFragment extends DialogFragment {
checkBoxes[i].setChecked(chartFragment.isChartValueSeriesEnabled(i));
}
checkBoxes[ChartView.SPEED_SERIES].setText(chartFragment.isReportSpeed()
? R.string.stat_speed : R.string.stat_pace);
? R.string.stats_speed : R.string.stats_pace);
return new AlertDialog.Builder(getActivity())
.setCancelable(true)
.setNegativeButton(R.string.generic_cancel, null)
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
@@ -16,22 +16,21 @@
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.CheckUnitsUtils;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import java.util.Locale;
/**
* A DialogFragment to check preferred units.
*
*
* @author Jimmy Shih
*/
public class CheckUnitsDialogFragment extends DialogFragment {
@@ -39,31 +38,38 @@ public class CheckUnitsDialogFragment extends DialogFragment {
public static final String CHECK_UNITS_DIALOG_TAG = "checkUnitsDialog";
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
public void onCancel(DialogInterface arg0) {
onDone();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Locale defaultLocale = Locale.getDefault();
boolean defaultMetric = !defaultLocale.equals(Locale.US) && !defaultLocale.equals(Locale.UK);
PreferencesUtils.setMetricUnits(getActivity(), defaultMetric);
final String metric = getString(R.string.preferred_units_metric);
final String imperial = getString(R.string.preferred_units_imperial);
final CharSequence[] items = defaultMetric ? new CharSequence[] { metric, imperial }
: new CharSequence[] { imperial, metric };
return new AlertDialog.Builder(getActivity())
.setCancelable(true)
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
CheckUnitsUtils.setCheckUnitsValue(getActivity());
}
})
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CheckUnitsUtils.setCheckUnitsValue(getActivity());
int position = ((AlertDialog) dialog).getListView().getSelectedItemPosition();
SharedPreferences sharedPreferences = getActivity()
.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(sharedPreferences.edit()
.putBoolean(getString(R.string.metric_units_key), position == 0));
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
PreferencesUtils.setMetricUnits(getActivity(), items[position].equals(metric));
onDone();
}
})
.setSingleChoiceItems(new CharSequence[] { getString(R.string.preferred_units_metric),
getString(R.string.preferred_units_imperial) }, 0, null)
.setTitle(R.string.preferred_units_title)
.create();
.setSingleChoiceItems(items, 0, null)
.setTitle(R.string.preferred_units_title).create();
}
/**
* Tasks to perform when done.
*/
private void onDone() {
PreferencesUtils.setShowCheckUnitsDialog(getActivity());
TrackListActivity trackListActivity = (TrackListActivity) getActivity();
trackListActivity.showStartupDialogs();
}
}
@@ -20,6 +20,7 @@ import com.google.android.apps.mytracks.MarkerListActivity;
import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import android.app.Dialog;
@@ -37,10 +38,12 @@ public class DeleteOneMarkerDialogFragment extends DialogFragment {
public static final String DELETE_ONE_MARKER_DIALOG_TAG = "deleteOneMarkerDialog";
private static final String KEY_MARKER_ID = "markerId";
private static final String KEY_TRACK_ID = "trackId";
public static DeleteOneMarkerDialogFragment newInstance(long markerId) {
public static DeleteOneMarkerDialogFragment newInstance(long markerId, long trackId) {
Bundle bundle = new Bundle();
bundle.putLong(KEY_MARKER_ID, markerId);
bundle.putLong(KEY_TRACK_ID, trackId);
DeleteOneMarkerDialogFragment deleteOneMarkerDialogFragment = new DeleteOneMarkerDialogFragment();
deleteOneMarkerDialogFragment.setArguments(bundle);
@@ -55,8 +58,11 @@ public class DeleteOneMarkerDialogFragment extends DialogFragment {
public void onClick(DialogInterface dialog, int which) {
MyTracksProviderUtils.Factory.get(getActivity()).deleteWaypoint(
getArguments().getLong(KEY_MARKER_ID), new DescriptionGeneratorImpl(getActivity()));
startActivity(new Intent(getActivity(), MarkerListActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
Intent intent = IntentUtils.newIntent(getActivity(), MarkerListActivity.class)
.putExtra(MarkerListActivity.EXTRA_TRACK_ID, getArguments().getLong(KEY_TRACK_ID));
startActivity(intent);
// Close the activity since its content can change after delete.
getActivity().finish();
}
});
}
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import android.app.Dialog;
@@ -54,8 +55,10 @@ public class DeleteOneTrackDialogFragment extends DialogFragment {
public void onClick(DialogInterface dialog, int which) {
MyTracksProviderUtils.Factory.get(getActivity())
.deleteTrack(getArguments().getLong(KEY_TRACK_ID));
startActivity(new Intent(getActivity(), TrackListActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
Intent intent = IntentUtils.newIntent(getActivity(), TrackListActivity.class);
startActivity(intent);
// Close the activity since its content can change after delete.
getActivity().finish();
}
});
}
@@ -16,6 +16,7 @@
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.EulaUtils;
import com.google.android.maps.mytracks.R;
@@ -49,11 +50,17 @@ public class EulaDialogFragment extends DialogFragment {
return eulaDialogFragment;
}
@Override
public void onCancel(DialogInterface arg0) {
if (!getArguments().getBoolean(KEY_HAS_ACCEPTED)) {
exitApp();
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
boolean hasAccepted = getArguments().getBoolean(KEY_HAS_ACCEPTED);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setCancelable(true)
.setMessage(EulaUtils.getEulaMessage(getActivity()))
.setTitle(R.string.eula_title);
@@ -63,24 +70,25 @@ public class EulaDialogFragment extends DialogFragment {
builder.setNegativeButton(R.string.eula_decline, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getActivity().finish();
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
getActivity().finish();
exitApp();
}
})
.setPositiveButton(R.string.eula_accept, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
EulaUtils.setEulaValue(getActivity());
new WelcomeDialogFragment().show(
getActivity().getSupportFragmentManager(), WelcomeDialogFragment.WELCOME_DIALOG_TAG);
TrackListActivity trackListActivity = (TrackListActivity) getActivity();
trackListActivity.showStartupDialogs();
}
});
}
return builder.create();
}
/**
* Exits the application.
*/
private void exitApp() {
getActivity().finish();
}
}
@@ -39,13 +39,13 @@ public class InstallEarthDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setCancelable(true)
.setMessage(R.string.track_detail_install_earth_message)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent().setData(Uri.parse(SaveActivity.GOOGLE_EARTH_MARKET_URL)));
Intent intent = new Intent().setData(Uri.parse(SaveActivity.GOOGLE_EARTH_MARKET_URL));
startActivity(intent);
}
})
.create();
@@ -43,8 +43,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
@@ -59,6 +58,8 @@ import java.util.EnumSet;
public class MapFragment extends Fragment
implements View.OnTouchListener, View.OnClickListener, TrackDataListener {
public static final String MAP_FRAGMENT_TAG = "mapFragment";
private static final String KEY_CURRENT_LOCATION = "currentLocation";
private static final String KEY_KEEP_MY_LOCATION_VISIBLE = "keepMyLocationVisible";
@@ -85,11 +86,9 @@ public class MapFragment extends Fragment
// UI elements
private View mapViewContainer;
private MapOverlay mapOverlay;
private RelativeLayout screen;
private MapView mapView;
private LinearLayout messagePane;
private TextView messageText;
private LinearLayout busyPane;
private ImageButton myLocationImageButton;
private TextView messageTextView;
@Override
public View onCreateView(
@@ -98,15 +97,19 @@ public class MapFragment extends Fragment
mapOverlay = new MapOverlay(getActivity());
screen = (RelativeLayout) mapViewContainer.findViewById(R.id.screen);
mapView = (MapView) mapViewContainer.findViewById(R.id.map);
mapView = (MapView) mapViewContainer.findViewById(R.id.map_view);
mapView.requestFocus();
mapView.setOnTouchListener(this);
mapView.setBuiltInZoomControls(true);
mapView.getOverlays().add(mapOverlay);
messagePane = (LinearLayout) mapViewContainer.findViewById(R.id.messagepane);
messageText = (TextView) mapViewContainer.findViewById(R.id.messagetext);
busyPane = (LinearLayout) mapViewContainer.findViewById(R.id.busypane);
myLocationImageButton = (ImageButton) mapViewContainer.findViewById(R.id.map_my_location);
myLocationImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showMyLocation();
}
});
messageTextView = (TextView) mapViewContainer.findViewById(R.id.map_message);
return mapViewContainer;
}
@@ -156,7 +159,7 @@ public class MapFragment extends Fragment
/**
* Shows my location.
*/
public void showMyLocation() {
private void showMyLocation() {
updateTrackDataHub();
keepMyLocationVisible = true;
zoomToMyLocation = true;
@@ -238,8 +241,9 @@ public class MapFragment extends Fragment
@Override
public void onClick(View v) {
if (v == messagePane) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
if (v == messageTextView) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
}
@@ -269,21 +273,20 @@ public class MapFragment extends Fragment
@Override
public void run() {
if (messageId != -1) {
messageText.setText(messageId);
messagePane.setVisibility(View.VISIBLE);
messageTextView.setText(messageId);
messageTextView.setVisibility(View.VISIBLE);
if (isGpsDisabled) {
Toast.makeText(getActivity(), R.string.gps_not_found, Toast.LENGTH_LONG).show();
// Click to show the location source settings
messagePane.setOnClickListener(MapFragment.this);
messageTextView.setOnClickListener(MapFragment.this);
} else {
messagePane.setOnClickListener(null);
messageTextView.setOnClickListener(null);
}
} else {
messagePane.setVisibility(View.GONE);
messageTextView.setVisibility(View.GONE);
}
screen.requestLayout();
}
});
}
@@ -309,9 +312,7 @@ public class MapFragment extends Fragment
boolean hasTrack = track != null;
mapOverlay.setTrackDrawingEnabled(hasTrack);
if (hasTrack) {
busyPane.setVisibility(View.VISIBLE);
if (hasTrack) {
synchronized (this) {
/*
* Synchronize to prevent race condition in changing markerTrackId
@@ -321,7 +322,6 @@ public class MapFragment extends Fragment
updateMap(track);
}
mapOverlay.setShowEndMarker(!isRecording);
busyPane.setVisibility(View.GONE);
}
mapView.invalidate();
}
@@ -0,0 +1,122 @@
/*
* Copyright 2012 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.fragments;
import com.google.android.apps.mytracks.MarkerEditActivity;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
/**
* A DialogFragment to add a marker.
*
* @author Jimmy Shih
*/
public class MarkerAddDialogFragment extends DialogFragment {
public static final String MARKER_ADD_DIALOG_TAG = "markerAddDialog";
private static final String KEY_TRACK_ID = "trackId";
private TrackRecordingServiceConnection trackRecordingServiceConnection;
private RadioGroup radioGroup;
private Button moreOptions;
/**
* Creates a new instance of {@link MarkerAddDialogFragment}.
*
* @param trackId the track id
*/
public static MarkerAddDialogFragment newInstance(long trackId) {
Bundle bundle = new Bundle();
bundle.putLong(KEY_TRACK_ID, trackId);
MarkerAddDialogFragment markerAddDialogFragment = new MarkerAddDialogFragment();
markerAddDialogFragment.setArguments(bundle);
return markerAddDialogFragment;
}
@Override
public void onCreate(Bundle arg0) {
super.onCreate(arg0);
trackRecordingServiceConnection = new TrackRecordingServiceConnection(getActivity(), null);
}
@Override
public void onResume() {
super.onResume();
TrackRecordingServiceConnectionUtils.resume(getActivity(), trackRecordingServiceConnection);
}
@Override
public void onDestroy() {
super.onDestroy();
trackRecordingServiceConnection.unbind();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.marker_add, null);
radioGroup = (RadioGroup) view.findViewById(R.id.marker_add_type);
moreOptions = (Button) view.findViewById(R.id.marker_add_more_options);
moreOptions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean statisticsMarker = radioGroup.getCheckedRadioButtonId()
== R.id.marker_add_statistics;
Intent intent = IntentUtils.newIntent(getActivity(), MarkerEditActivity.class);
intent.putExtra(MarkerEditActivity.EXTRA_TRACK_ID, getArguments().getLong(KEY_TRACK_ID));
intent.putExtra(MarkerEditActivity.EXTRA_STATISTICS_MARKER, statisticsMarker);
startActivity(intent);
dismiss();
}
});
boolean pickStatisticsMarker = PreferencesUtils.getBoolean(
getActivity(), R.string.pick_statistics_marker_key, true);
radioGroup.check(pickStatisticsMarker ? R.id.marker_add_statistics : R.id.marker_add_waypoint);
return new AlertDialog.Builder(getActivity())
.setNegativeButton(R.string.generic_cancel, null)
.setPositiveButton(R.string.generic_add, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean statisticsMarker = radioGroup.getCheckedRadioButtonId()
== R.id.marker_add_statistics;
PreferencesUtils.setBoolean(
getActivity(), R.string.pick_statistics_marker_key, statisticsMarker);
TrackRecordingServiceConnectionUtils.addMarker(getActivity(),
trackRecordingServiceConnection,
statisticsMarker ? WaypointCreationRequest.DEFAULT_STATISTICS
: WaypointCreationRequest.DEFAULT_WAYPOINT);
}
})
.setTitle(R.string.menu_insert_marker)
.setView(view)
.create();
}
}
@@ -17,14 +17,14 @@
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.MyTracksApplication;
import com.google.android.apps.mytracks.StatsUtilities;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
import com.google.android.apps.mytracks.content.TrackDataListener;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.maps.mytracks.R;
import android.location.Location;
@@ -34,7 +34,6 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import java.util.EnumSet;
@@ -46,20 +45,24 @@ import java.util.EnumSet;
*/
public class StatsFragment extends Fragment implements TrackDataListener {
public static final String STATS_FRAGMENT_TAG = "statsFragment";
private static final String TAG = StatsFragment.class.getSimpleName();
private StatsUtilities statsUtilities;
private TrackDataHub trackDataHub;
private UiUpdateThread uiUpdateThread;
// The start time of the current track.
private long startTime = -1L;
private Location lastLocation = null;
private TripStatistics lastTripStatistics = null;
// A runnable to update the total time field.
private final Runnable updateTotalTime = new Runnable() {
public void run() {
if (isRecording()) {
statsUtilities.setTime(R.id.total_time_register, System.currentTimeMillis() - startTime);
StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() - startTime);
}
}
};
@@ -68,7 +71,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
* A thread that updates the total time field every second.
*/
private class UiUpdateThread extends Thread {
@Override
public void run() {
Log.d(TAG, "UI update thread started");
@@ -85,12 +87,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
statsUtilities = new StatsUtilities(getActivity());
}
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -100,10 +96,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ScrollView scrollView = (ScrollView) getActivity().findViewById(R.id.scrolly);
scrollView.setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_INSET);
updateLabels();
setLocationUnknown();
updateUi();
}
@Override
@@ -128,7 +121,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
setLocationUnknown();
lastLocation = null;
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
}
});
}
@@ -140,11 +134,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (location != null) {
setLocation(location);
} else {
setLocationUnknown();
}
lastLocation = location;
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
}
});
}
@@ -172,16 +163,18 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void run() {
if (track == null || track.getStatistics() == null) {
statsUtilities.setAllToUnknown();
lastLocation = null;
lastTripStatistics = null;
updateUi();
return;
}
lastTripStatistics = track.getStatistics();
startTime = track.getStatistics().getStartTime();
if (!isRecording()) {
statsUtilities.setTime(R.id.total_time_register, track.getStatistics().getTotalTime());
setLocationUnknown();
lastLocation = null;
}
statsUtilities.setAllStats(track.getStatistics());
updateUi();
}
});
}
@@ -227,30 +220,22 @@ public class StatsFragment extends Fragment implements TrackDataListener {
}
@Override
public boolean onUnitsChanged(boolean metric) {
if (statsUtilities.isMetricUnits() == metric) {
return false;
}
statsUtilities.setMetricUnits(metric);
public boolean onUnitsChanged(final boolean metric) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateLabels();
updateUi();
}
});
return true;
}
@Override
public boolean onReportSpeedChanged(boolean speed) {
if (statsUtilities.isReportSpeed() == speed) {
return false;
}
statsUtilities.setReportSpeed(speed);
public boolean onReportSpeedChanged(final boolean speed) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateLabels();
updateUi();
}
});
return true;
@@ -285,35 +270,9 @@ public class StatsFragment extends Fragment implements TrackDataListener {
private synchronized boolean isRecording() {
return trackDataHub != null && trackDataHub.isRecordingSelected();
}
/**
* Updates the labels.
*/
private void updateLabels() {
statsUtilities.updateUnits();
statsUtilities.setSpeedLabel(R.id.speed_label, R.string.stat_speed, R.string.stat_pace);
statsUtilities.setSpeedLabels();
}
/**
* Sets the current location.
*
* @param location the current location
*/
private void setLocation(Location location) {
statsUtilities.setAltitude(R.id.elevation_register, location.getAltitude());
statsUtilities.setLatLong(R.id.latitude_register, location.getLatitude());
statsUtilities.setLatLong(R.id.longitude_register, location.getLongitude());
statsUtilities.setSpeed(R.id.speed_register, location.getSpeed() * UnitConversions.MS_TO_KMH);
}
/**
* Sets the current location to unknown.
*/
private void setLocationUnknown() {
statsUtilities.setUnknown(R.id.elevation_register);
statsUtilities.setUnknown(R.id.latitude_register);
statsUtilities.setUnknown(R.id.longitude_register);
statsUtilities.setUnknown(R.id.speed_register);
public void updateUi() {
StatsUtils.setTripStatisticsValues(getActivity(), lastTripStatistics);
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
}
}
@@ -0,0 +1,96 @@
/*
* Copyright 2012 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.fragments;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RadioGroup;
/**
* A DialogFragment to show stats settings.
*
* @author Jimmy Shih
*/
public class StatsSettingsDialogFragment extends DialogFragment {
public static final String STATS_SETTINGS_DIALOG_TAG = "statsSettingsDialog";
public interface OnStatsSettingsChangedListener {
public void onStatsSettingsChanged();
}
private OnStatsSettingsChangedListener listener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnStatsSettingsChangedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnArticleSelectedListener");
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.stats_settings, null);
final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.stats_settings_time);
boolean totalTime = PreferencesUtils.getBoolean(
getActivity(), R.string.stats_show_total_time_key, true);
radioGroup.check(totalTime ? R.id.stats_settings_total_time : R.id.stats_settings_moving_time);
final CheckBox elevation = (CheckBox) view.findViewById(R.id.stats_settings_elevation);
final CheckBox grade = (CheckBox) view.findViewById(R.id.stats_settings_grade);
final CheckBox coordinate = (CheckBox) view.findViewById(R.id.stats_settings_coordinate);
elevation.setChecked(
PreferencesUtils.getBoolean(getActivity(), R.string.stats_show_elevation_key, false));
grade.setChecked(
PreferencesUtils.getBoolean(getActivity(), R.string.stats_show_grade_key, false));
coordinate.setChecked(
PreferencesUtils.getBoolean(getActivity(), R.string.stats_show_coordinate_key, false));
return new AlertDialog.Builder(getActivity()).setNegativeButton(R.string.generic_cancel, null)
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
PreferencesUtils.setBoolean(getActivity(), R.string.stats_show_total_time_key,
radioGroup.getCheckedRadioButtonId() == R.id.stats_settings_total_time);
PreferencesUtils.setBoolean(
getActivity(), R.string.stats_show_elevation_key, elevation.isChecked());
PreferencesUtils.setBoolean(
getActivity(), R.string.stats_show_grade_key, grade.isChecked());
PreferencesUtils.setBoolean(
getActivity(), R.string.stats_show_coordinate_key, coordinate.isChecked());
listener.onStatsSettingsChanged();
}
})
.setTitle(R.string.menu_stats_settings)
.setView(view)
.create();
}
}
@@ -16,6 +16,8 @@
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
@@ -23,7 +25,6 @@ import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
/**
* A DialogFrament to show the welcome info.
@@ -34,30 +35,28 @@ public class WelcomeDialogFragment extends DialogFragment {
public static final String WELCOME_DIALOG_TAG = "welcomeDialog";
@Override
public void onCancel(DialogInterface arg0) {
onDone();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.welcome, null);
return new AlertDialog.Builder(getActivity())
.setCancelable(true)
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
checkUnits();
}
})
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
checkUnits();
onDone();
}
})
.setTitle(R.string.welcome_title)
.setView(view)
.setMessage(R.string.welcome_message)
.create();
}
private void checkUnits() {
new CheckUnitsDialogFragment().show(
getActivity().getSupportFragmentManager(), CheckUnitsDialogFragment.CHECK_UNITS_DIALOG_TAG);
private void onDone() {
PreferencesUtils.setShowWelcome(getActivity());
TrackListActivity trackListActivity = (TrackListActivity) getActivity();
trackListActivity.showStartupDialogs();
}
}
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.TrackListActivity;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -93,8 +94,8 @@ public class RestoreActivity extends Activity {
public void onAsyncTaskCompleted(boolean success, int messageId) {
removeDialog(DIALOG_PROGRESS_ID);
Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
startActivity(new Intent(this, TrackListActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
Intent intent = IntentUtils.newIntent(this, TrackListActivity.class);
startActivity(intent);
}
/**
@@ -17,6 +17,7 @@
package com.google.android.apps.mytracks.io.backup;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -76,8 +77,9 @@ public class RestoreChooserActivity extends Activity {
}
if (backupDates.length == 1) {
startActivity(new Intent(this, RestoreActivity.class)
.putExtra(RestoreActivity.EXTRA_DATE, backupDates[0].getTime()));
Intent intent = IntentUtils.newIntent(this, RestoreActivity.class)
.putExtra(RestoreActivity.EXTRA_DATE, backupDates[0].getTime());
startActivity(intent);
finish();
return;
}
@@ -100,8 +102,10 @@ public class RestoreChooserActivity extends Activity {
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(RestoreChooserActivity.this, RestoreActivity.class).putExtra(
RestoreActivity.EXTRA_DATE, backupDates[which].getTime()));
Intent intent = IntentUtils.newIntent(
RestoreChooserActivity.this, RestoreActivity.class)
.putExtra(RestoreActivity.EXTRA_DATE, backupDates[which].getTime());
startActivity(intent);
finish();
}
})
@@ -19,6 +19,7 @@ import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import android.content.Intent;
@@ -43,7 +44,7 @@ public class SendDocsActivity extends AbstractSendActivity {
@Override
protected void startNextActivity(boolean success, boolean isCancel) {
sendRequest.setDocsSuccess(success);
Intent intent = new Intent(this, UploadResultActivity.class)
Intent intent = IntentUtils.newIntent(this, UploadResultActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
finish();
@@ -21,6 +21,7 @@ import com.google.android.apps.mytracks.io.gdata.docs.DocumentsClient;
import com.google.android.apps.mytracks.io.gdata.docs.SpreadsheetsClient;
import com.google.android.apps.mytracks.io.gdata.docs.SpreadsheetsClient.WorksheetEntry;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.ResourceUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
@@ -33,7 +34,6 @@ import com.google.wireless.gdata.parser.ParseException;
import com.google.wireless.gdata2.client.AuthenticationException;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import java.io.BufferedReader;
@@ -270,10 +270,7 @@ public class SendDocsUtils {
Track track, String spreadsheetId, String worksheetId, String authToken, Context context)
throws IOException {
String worksheetUri = String.format(GET_WORKSHEET_URI, spreadsheetId, worksheetId);
SharedPreferences prefs = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
boolean metricUnits = prefs.getBoolean(context.getString(R.string.metric_units_key), true);
boolean metricUnits = PreferencesUtils.isMetricUnits(context);
addRow(worksheetUri, getRowContent(track, metricUnits, context), authToken);
}
@@ -102,7 +102,7 @@ public class CsvTrackWriter implements TrackFormatWriter {
@Override
public void writeBeginWaypoints() {
writeCommaSeparatedLine(context.getString(R.string.generic_name),
context.getString(R.string.marker_edit_marker_type_hint),
context.getString(R.string.marker_edit_waypoint_marker_type_hint),
context.getString(R.string.generic_description),
context.getString(R.string.description_location_latitude),
context.getString(R.string.description_location_longitude),
@@ -20,6 +20,7 @@ import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
@@ -45,10 +46,9 @@ public class SendFusionTablesActivity extends AbstractSendActivity {
@Override
protected void startNextActivity(boolean success, boolean isCancel) {
sendRequest.setFusionTablesSuccess(success);
Class<?> next = getNextClass(sendRequest, isCancel);
Intent intent = new Intent(this, next).putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
Intent intent = IntentUtils.newIntent(this, next)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
finish();
}
@@ -14,6 +14,7 @@ import com.google.android.apps.mytracks.stats.DoubleBuffer;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
@@ -32,7 +33,6 @@ import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.location.Location;
import android.util.Log;
@@ -205,9 +205,7 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask {
private boolean uploadAllTrackPoints(Track track) {
Cursor locationsCursor = null;
try {
SharedPreferences prefs = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
boolean metricUnits = prefs.getBoolean(context.getString(R.string.metric_units_key), true);
boolean metricUnits = PreferencesUtils.isMetricUnits(context);
locationsCursor = myTracksProviderUtils.getLocationsCursor(trackId, 0, -1, false);
if (locationsCursor == null) {
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.maps;
import com.google.android.apps.mytracks.io.gdata.maps.MapsMapMetadata;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
@@ -67,11 +68,11 @@ public class ChooseMapActivity extends Activity {
}
MapsMapMetadata mapData = getItem(position).getMapData();
TextView title = (TextView) convertView.findViewById(R.id.choose_map_list_item_title);
TextView title = (TextView) convertView.findViewById(R.id.choose_map_item_title);
title.setText(mapData.getTitle());
TextView description = (TextView) convertView.findViewById(
R.id.choose_map_list_item_description);
R.id.choose_map_item_description);
String descriptionText = mapData.getDescription();
if (descriptionText == null || descriptionText.equals("")) {
description.setVisibility(View.GONE);
@@ -81,7 +82,7 @@ public class ChooseMapActivity extends Activity {
}
TextView searchStatus = (TextView) convertView.findViewById(
R.id.choose_map_list_item_search_status);
R.id.choose_map_item_search_status);
searchStatus.setTextColor(mapData.getSearchable() ? Color.RED : Color.GREEN);
searchStatus.setText(mapData.getSearchable() ? R.string.maps_list_public_label
: R.string.maps_list_unlisted_label);
@@ -209,7 +210,7 @@ public class ChooseMapActivity extends Activity {
*/
private void startNextActivity(String mapId) {
sendRequest.setMapId(mapId);
Intent intent = new Intent(this, SendMapsActivity.class)
Intent intent = IntentUtils.newIntent(this, SendMapsActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
finish();
@@ -21,6 +21,7 @@ import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
@@ -47,10 +48,9 @@ public class SendMapsActivity extends AbstractSendActivity {
@Override
protected void startNextActivity(boolean success, boolean isCancel) {
sendRequest.setMapsSuccess(success);
Class<?> next = getNextClass(sendRequest, isCancel);
Intent intent = new Intent(this, next).putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
Intent intent = IntentUtils.newIntent(this, next)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
finish();
}
@@ -31,6 +31,7 @@ import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.stats.DoubleBuffer;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.common.gdata.AndroidXmlParserFactory;
import com.google.android.maps.mytracks.R;
@@ -257,9 +258,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
boolean uploadAllTrackPoints(Track track) {
Cursor locationsCursor = null;
try {
SharedPreferences prefs = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
boolean metricUnits = prefs.getBoolean(context.getString(R.string.metric_units_key), true);
boolean metricUnits = PreferencesUtils.isMetricUnits(context);
locationsCursor = myTracksProviderUtils.getLocationsCursor(trackId, 0, -1, false);
if (locationsCursor == null) {
@@ -25,6 +25,7 @@ import com.google.android.apps.mytracks.io.gdata.maps.MapsConstants;
import com.google.android.apps.mytracks.io.maps.ChooseMapActivity;
import com.google.android.apps.mytracks.io.maps.SendMapsActivity;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import android.accounts.Account;
@@ -294,7 +295,7 @@ public class AccountChooserActivity extends Activity {
} else {
next = UploadResultActivity.class;
}
Intent intent = new Intent(this, next)
Intent intent = IntentUtils.newIntent(this, next)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
finish();
@@ -182,11 +182,11 @@ public class UploadResultActivity extends Activity {
SharedPreferences prefs = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
boolean shareUrlOnly = prefs.getBoolean(getString(R.string.share_url_only_key), false);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType(TEXT_PLAIN_TYPE);
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_track_subject));
intent.putExtra(Intent.EXTRA_TEXT,
shareUrlOnly ? url : getString(R.string.share_track_url_body_format, url));
Intent intent = new Intent(Intent.ACTION_SEND)
.setType(TEXT_PLAIN_TYPE)
.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_track_subject))
.putExtra(Intent.EXTRA_TEXT,
shareUrlOnly ? url : getString(R.string.share_track_url_body_format, url));
startActivity(Intent.createChooser(intent, getString(R.string.share_track_picker_title)));
}
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
@@ -237,7 +238,7 @@ public class UploadServiceChooserActivity extends Activity {
sendRequest.setSendFusionTables(sendFusionTables());
sendRequest.setSendDocs(sendDocs());
sendRequest.setNewMap(!existingMapRadioButton.isChecked());
Intent intent = new Intent(this, AccountChooserActivity.class)
Intent intent = IntentUtils.newIntent(this, AccountChooserActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
finish();
@@ -38,7 +38,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
private final String autoResumeTrackCurrentRetryKey;
private final String autoResumeTrackTimeoutKey;
private final String maxRecordingDistanceKey;
private final String metricUnitsKey;
private final String minRecordingDistanceKey;
private final String minRecordingIntervalKey;
private final String minRequiredAccuracyKey;
@@ -63,8 +62,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
service.getString(R.string.auto_resume_track_timeout_key);
maxRecordingDistanceKey =
service.getString(R.string.max_recording_distance_key);
metricUnitsKey =
service.getString(R.string.metric_units_key);
minRecordingDistanceKey =
service.getString(R.string.min_recording_distance_key);
minRecordingIntervalKey =
@@ -160,9 +157,8 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
service.setSplitFrequency(
sharedPreferences.getInt(splitFrequencyKey, 0));
}
if (key == null || key.equals(metricUnitsKey)) {
service.setMetricUnits(
sharedPreferences.getBoolean(metricUnitsKey, true));
if (key == null || key.equals(PreferencesUtils.getMetricUnitsKey(service))) {
service.setMetricUnits(PreferencesUtils.isMetricUnits(service));
}
}
@@ -38,6 +38,7 @@ import com.google.android.apps.mytracks.services.tasks.SplitTask;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
@@ -485,13 +486,11 @@ public class TrackRecordingService extends Service {
private void showNotification() {
if (isRecording) {
Notification notification = new Notification(
R.drawable.arrow_320, null /* tickerText */,
System.currentTimeMillis());
Intent intent = new Intent(this, TrackDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
R.drawable.my_tracks_notification_icon, null, System.currentTimeMillis());
Intent intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, recordingTrackId);
PendingIntent contentIntent = PendingIntent.getActivity(
this, 0 /* requestCode */, intent, 0 /* flags */);
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, getString(R.string.my_tracks_app_name),
getString(R.string.track_record_notification), contentIntent);
notification.flags += Notification.FLAG_NO_CLEAR;
@@ -934,15 +933,15 @@ public class TrackRecordingService extends Service {
"Unable to insert waypoint marker while not recording!");
}
if (request == null) {
request = WaypointCreationRequest.DEFAULT_MARKER;
request = WaypointCreationRequest.DEFAULT_WAYPOINT;
}
Waypoint wpt = new Waypoint();
switch (request.getType()) {
case MARKER:
buildMarker(wpt, request);
case WAYPOINT:
buildWaypointMarker(wpt, request);
break;
case STATISTICS:
buildStatisticsMarker(wpt);
buildStatisticsMarker(wpt, request);
break;
}
wpt.setTrackId(recordingTrackId);
@@ -964,18 +963,22 @@ public class TrackRecordingService extends Service {
return Long.parseLong(uri.getLastPathSegment());
}
private void buildMarker(Waypoint wpt, WaypointCreationRequest request) {
private void buildWaypointMarker(Waypoint wpt, WaypointCreationRequest request) {
wpt.setType(Waypoint.TYPE_WAYPOINT);
if (request.getIconUrl() == null) {
wpt.setIcon(getString(R.string.marker_waypoint_icon_url));
} else {
wpt.setIcon(request.getIconUrl());
}
if (request.getName() == null) {
wpt.setName(getString(R.string.marker_edit_type_waypoint));
String name;
if (request.getName() != null) {
name = request.getName();
} else {
wpt.setName(request.getName());
int nextMarkerNumber = providerUtils.getNextMarkerNumber(recordingTrackId, false);
name = nextMarkerNumber == -1 ? getString(R.string.marker_type_waypoint)
: getString(R.string.marker_waypoint_name_format, nextMarkerNumber);
}
wpt.setName(name);
if (request.getCategory() != null) {
wpt.setCategory(request.getCategory());
}
@@ -988,9 +991,10 @@ public class TrackRecordingService extends Service {
* Build a statistics marker.
* A statistics marker holds the stats for the* last segment up to this marker.
*
* @param waypoint The waypoint which will be populated with stats data.
* @param waypoint The waypoint which will be populated with stats data
* @param request The waypoint creation request
*/
private void buildStatisticsMarker(Waypoint waypoint) {
private void buildStatisticsMarker(Waypoint waypoint, WaypointCreationRequest request) {
DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(this);
// Set stop and total time in the stats data
@@ -1003,7 +1007,15 @@ public class TrackRecordingService extends Service {
// Set the rest of the waypoint data
waypoint.setType(Waypoint.TYPE_STATISTICS);
waypoint.setName(getString(R.string.marker_edit_type_statistics));
String name;
if (request.getName() != null) {
name = request.getName();
} else {
int nextMarkerNumber = providerUtils.getNextMarkerNumber(recordingTrackId, true);
name = nextMarkerNumber == -1 ? getString(R.string.marker_type_statistics)
: getString(R.string.marker_statistics_name_format, nextMarkerNumber);
}
waypoint.setName(name);
waypoint.setStatistics(waypointStatsBuilder.getStatistics());
waypoint.setDescription(descriptionGenerator.generateWaypointDescription(waypoint));
waypoint.setIcon(getString(R.string.marker_statistics_icon_url));
@@ -21,13 +21,13 @@ import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
import android.content.Context;
import android.content.SharedPreferences;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.telephony.PhoneStateListener;
@@ -150,15 +150,8 @@ public class StatusAnnouncerTask implements PeriodicTask {
*/
// @VisibleForTesting
protected String getAnnouncement(TripStatistics stats) {
boolean metricUnits = true;
boolean reportSpeed = true;
SharedPreferences preferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
if (preferences != null) {
metricUnits = preferences.getBoolean(context.getString(R.string.metric_units_key), true);
reportSpeed = preferences.getBoolean(context.getString(R.string.report_speed_key), true);
}
boolean metricUnits = PreferencesUtils.isMetricUnits(context);
boolean reportSpeed = PreferencesUtils.isReportSpeed(context);
double d = stats.getTotalDistance() * UnitConversions.M_TO_KM;
double s = stats.getAverageMovingSpeed() * UnitConversions.MS_TO_KMH;
@@ -28,10 +28,13 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import java.util.List;
/**
* API level 11 specific implementation of the {@link ApiAdapter}.
*
@@ -59,7 +62,7 @@ public class Api11Adapter extends Api10Adapter {
@Override
public boolean onItemLongClick(
AdapterView<?> parent, View view, int position, final long id) {
AdapterView<?> parent, View view, final int position, final long id) {
if (actionMode != null) {
return false;
}
@@ -83,7 +86,8 @@ public class Api11Adapter extends Api10Adapter {
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return contextualActionModeCallback.onClick(item.getItemId(), id);
mode.finish();
return contextualActionModeCallback.onClick(item.getItemId(), position, id);
}
});
TextView textView = (TextView) view.findViewById(actionModeTitleId);
@@ -97,15 +101,45 @@ public class Api11Adapter extends Api10Adapter {
};
@Override
public void configureSearchWidget(Activity activity, MenuItem menuItem) {
public void configureSearchWidget(Activity activity, final MenuItem menuItem) {
SearchManager searchManager = (SearchManager) activity.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity.getComponentName()));
searchView.setQueryRefinementEnabled(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
menuItem.collapseActionView();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int position) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
menuItem.collapseActionView();
return false;
}
});
}
@Override
public boolean handleSearchMenuSelection(Activity activity) {
// Returns false to allow the platform to expand the search widget.
return false;
}
}
@Override
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items) {
arrayAdapter.addAll(items);
}
}
@@ -33,11 +33,13 @@ import android.content.SharedPreferences.Editor;
import android.util.Log;
import android.view.MenuItem;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
/**
* API level 7 specific implementation of the {@link ApiAdapter}.
@@ -131,7 +133,14 @@ public class Api7Adapter implements ApiAdapter {
activity.onSearchRequested();
return true;
}
@Override
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items) {
for (T item : items) {
arrayAdapter.add(item);
}
}
@Override
public boolean handleSearchKey(MenuItem menuItem) {
// Return false and allow the framework to handle the search key.
@@ -26,9 +26,11 @@ import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.IOException;
import java.util.List;
/**
* A set of methods that may be implemented differently depending on the Android
@@ -160,6 +162,16 @@ public interface ApiAdapter {
*/
public boolean handleSearchMenuSelection(Activity activity);
/**
* Adds all items to an array adapter.
*
* Due to changes in API level 11.
*s
* @param arrayAdapter the array adapter
* @param items list of items
*/
public <T> void addAllToArrayAdapter(ArrayAdapter<T> arrayAdapter, List<T> items);
/**
* Handles the search key press. Returns true if handled.
*
@@ -16,13 +16,11 @@
package com.google.android.apps.mytracks.util;
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;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Vector;
@@ -47,18 +45,11 @@ public class ChartURLGenerator {
* @param track The track for this chart
* @param context The current appplication context
*/
public static String getChartUrl(Vector<Double> distances,
Vector<Double> elevations, Track track, Context context) {
SharedPreferences preferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
boolean metricUnits = true;
if (preferences != null) {
metricUnits = preferences.getBoolean(
context.getString(R.string.metric_units_key), true);
}
return getChartUrl(distances, elevations, track,
context.getString(R.string.stat_elevation), metricUnits);
public static String getChartUrl(
Vector<Double> distances, Vector<Double> elevations, Track track, Context context) {
boolean metricUnits = PreferencesUtils.isMetricUnits(context);
return getChartUrl(
distances, elevations, track, context.getString(R.string.stats_elevation), metricUnits);
}
/**
@@ -1,47 +0,0 @@
/*
* Copyright 2012 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 android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
* Utilities for checking units.
*
* @author Jimmy Shih
*/
public class CheckUnitsUtils {
private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits";
private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked";
private CheckUnitsUtils() {}
public static boolean getCheckUnitsValue(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
return sharedPreferences.getBoolean(CHECK_UNITS_PREFERENCE_KEY, false);
}
public static void setCheckUnitsValue(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2012 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 android.content.Context;
import android.content.Intent;
/**
* Utilities for creating intents.
*
* @author Jimmy Shih
*/
public class IntentUtils {
private IntentUtils() {}
/**
* Creates an intent with {@link Intent#FLAG_ACTIVITY_CLEAR_TOP} and
* {@link Intent#FLAG_ACTIVITY_NEW_TASK}.
*
* @param context the context
* @param cls the class
*/
public static final Intent newIntent(Context context, Class<?> cls) {
return new Intent(context, cls).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
@@ -0,0 +1,87 @@
/*
* Copyright 2012 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.maps.mytracks.R;
import android.view.View;
import android.widget.TextView;
/**
* Utilities to display a list item.
*
* @author Jimmy Shih
*/
public class ListItemUtils {
private ListItemUtils() {}
/**
* Sets a list item.
*
* @param view the list item view
* @param name the name value
* @param iconId the icon id
* @param category the category value
* @param totalTime the total time value
* @param totalDistance the total distance value
* @param startTime the start time value
* @param description the description value
*/
public static void setListItem(View view,
String name,
int iconId,
String category,
String totalTime,
String totalDistance,
String startTime,
String description) {
TextView nameTextView = (TextView) view.findViewById(R.id.list_item_name);
nameTextView.setText(name);
nameTextView.setCompoundDrawablesWithIntrinsicBounds(iconId, 0, 0, 0);
TextView categoryTextView = (TextView) view.findViewById(R.id.list_item_category);
setTextView(categoryTextView, category);
TextView totalTimeTextView = (TextView) view.findViewById(R.id.list_item_total_time);
setTextView(totalTimeTextView, totalTime);
TextView totalDistanceTextView = (TextView) view.findViewById(R.id.list_item_total_distance);
setTextView(totalDistanceTextView, totalDistance);
TextView startTimeTextView = (TextView) view.findViewById(R.id.list_item_start_time);
setTextView(startTimeTextView, startTime);
TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description);
setTextView(descriptionTextView, description);
}
/**
* Sets a text view.
*
* @param textView the text view
* @param value the value for the text view
*/
private static void setTextView(TextView textView, String value) {
if (value == null || value.length() == 0) {
textView.setVisibility(View.GONE);
} else {
textView.setVisibility(View.VISIBLE);
textView.setText(value);
}
}
}
@@ -32,6 +32,34 @@ public class PreferencesUtils {
private PreferencesUtils() {}
/**
* Gets the metric units key.
*
* @param context the context
*/
public static String getMetricUnitsKey(Context context) {
return getKey(context, R.string.metric_units_key);
}
/**
* Returns the metric units value.
*
* @param context the context
*/
public static boolean isMetricUnits(Context context) {
return getBoolean(context, R.string.metric_units_key, true);
}
/**
* Sets the metric units value.
*
* @param context the context
* @param value the value
*/
public static void setMetricUnits(Context context, boolean value) {
setBoolean(context, R.string.metric_units_key, value);
}
/**
* Gets the recording track id key.
*
@@ -60,6 +88,34 @@ public class PreferencesUtils {
setLong(context, R.string.recording_track_id_key, trackId);
}
/**
* Gets the report speed key.
*
* @param context the context
*/
public static String getReportSpeedKey(Context context) {
return getKey(context, R.string.report_speed_key);
}
/**
* Returns the report speed value.
*
* @param context the context
*/
public static boolean isReportSpeed(Context context) {
return getBoolean(context, R.string.report_speed_key, true);
}
/**
* Sets the report speed value.
*
* @param context the context
* @param value the value
*/
public static void setReportSpeed(Context context, boolean value) {
setBoolean(context, R.string.report_speed_key, value);
}
/**
* Gets the selected track id key.
*
@@ -88,6 +144,42 @@ public class PreferencesUtils {
setLong(context, R.string.selected_track_id_key, trackId);
}
/**
* Returns the show check units dialog value.
*
* @param context the context
*/
public static boolean isShowCheckUnitsDialog(Context context) {
return getBoolean(context, R.string.show_check_units_dialog_key, true);
}
/**
* Sets the show check units dialog value to false.
*
* @param context the context
*/
public static void setShowCheckUnitsDialog(Context context) {
setBoolean(context, R.string.show_check_units_dialog_key, false);
}
/**
* Returns the show welcomes dialog value.
*
* @param context the context
*/
public static boolean isShowWelcomeDialog(Context context) {
return getBoolean(context, R.string.show_welcome_dialog_key, true);
}
/**
* Sets the show welcome dialog value to false.
*
* @param context the context
*/
public static void setShowWelcome(Context context) {
setBoolean(context, R.string.show_welcome_dialog_key, false);
}
/**
* Gets a preference key
*
@@ -98,6 +190,34 @@ public class PreferencesUtils {
return context.getString(keyId);
}
/**
* Gets a boolean preference value.
*
* @param context the context
* @param keyId the key id
* @param defaultValue the default value
*/
public static boolean getBoolean(Context context, int keyId, boolean defaultValue) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getBoolean(getKey(context, keyId), defaultValue);
}
/**
* Sets a boolean preference value.
*
* @param context the context
* @param keyId the key id
* @param value the value
*/
public static void setBoolean(Context context, int keyId, boolean value) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
editor.putBoolean(getKey(context, keyId), value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
}
/**
* Gets a long preference value.
*
@@ -16,9 +16,12 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.location.Location;
import android.view.View;
import android.widget.TextView;
/**
@@ -30,6 +33,161 @@ public class StatsUtils {
private StatsUtils() {}
/**
* Sets the location values.
*
* @param activity the activity
* @param location the location
* @param showAll true to show all the fields, false to show only the
* elevation field
*/
public static void setLocationValues(Activity activity, Location location, boolean showAll) {
boolean metricUnits = PreferencesUtils.getBoolean(activity, R.string.metric_units_key, true);
boolean reportSpeed = PreferencesUtils.getBoolean(activity, R.string.report_speed_key, true);
// Set elevation
boolean showElevation = PreferencesUtils.getBoolean(
activity, R.string.stats_show_elevation_key, false);
if (showElevation) {
double altitude = location == null ? Double.NaN : location.getAltitude();
setElevationValue(activity, R.id.stats_elevation_value, altitude, metricUnits);
}
if (!showAll) {
return;
}
// Set speed/pace
setSpeedLabel(
activity, R.id.stats_speed_label, R.string.stats_speed, R.string.stats_pace, reportSpeed);
double speed = location == null ? Double.NaN : location.getSpeed();
setSpeedValue(activity, R.id.stats_speed_value, speed, metricUnits, reportSpeed);
// Set coordinate
boolean showCoordinate = PreferencesUtils.getBoolean(
activity, R.string.stats_show_coordinate_key, false);
View coordinateLabelTableRow = activity.findViewById(R.id.stats_coordinate_label_table_row);
View coordinateValueTableRow = activity.findViewById(R.id.stats_coordinate_value_table_row);
coordinateLabelTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
coordinateValueTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
if (showCoordinate) {
double latitude = location == null ? Double.NaN : location.getLatitude();
double longitude = location == null ? Double.NaN : location.getLongitude();
setCoordinateValue(activity, R.id.stats_latitude_value, latitude);
setCoordinateValue(activity, R.id.stats_longitude_value, longitude);
}
}
/**
* Sets the total time value.
*
* @param activity the activity
* @param totalTime the total time
*/
public static void setTotalTimeValue(Activity activity, long totalTime) {
setTimeValue(activity, R.id.stats_total_time_value, totalTime);
}
/**
* Sets the trip statistics values.
*
* @param activity the activity
* @param tripStatistics the trip statistics
*/
public static void setTripStatisticsValues(Activity activity, TripStatistics tripStatistics) {
boolean metricUnits = PreferencesUtils.getBoolean(activity, R.string.metric_units_key, true);
boolean reportSpeed = PreferencesUtils.getBoolean(activity, R.string.report_speed_key, true);
boolean showTotalTime = PreferencesUtils.getBoolean(
activity, R.string.stats_show_total_time_key, true);
// Set total distance
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
setDistanceValue(activity, R.id.stats_total_distance_value, totalDistance, metricUnits);
// Set total time/moving time
setTimeLabel(activity, R.id.stats_total_time_label, R.string.stats_total_time,
R.string.stats_moving_time, showTotalTime);
long totalTime;
if (tripStatistics == null) {
totalTime = -1L;
} else {
totalTime = showTotalTime ? tripStatistics.getTotalTime() : tripStatistics.getMovingTime();
}
setTimeValue(activity, R.id.stats_total_time_value, totalTime);
// Set average speed/moving average speed
if (showTotalTime) {
setSpeedLabel(activity, R.id.stats_average_speed_label, R.string.stats_average_speed,
R.string.stats_average_pace, reportSpeed);
} else {
setSpeedLabel(activity, R.id.stats_average_speed_label, R.string.stats_average_moving_speed,
R.string.stats_average_moving_pace, reportSpeed);
}
double averageSpeed;
if (tripStatistics == null) {
averageSpeed = Double.NaN;
} else {
averageSpeed = showTotalTime ? tripStatistics.getAverageSpeed()
: tripStatistics.getAverageMovingSpeed();
}
setSpeedValue(activity, R.id.stats_average_speed_value, averageSpeed, metricUnits, reportSpeed);
// Set max speed
setSpeedLabel(activity, R.id.stats_max_speed_label, R.string.stats_max_speed,
R.string.stats_fastest_pace, reportSpeed);
double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
setSpeedValue(activity, R.id.stats_max_speed_value, maxSpeed, metricUnits, reportSpeed);
// Set elevation
boolean showElevation = PreferencesUtils.getBoolean(
activity, R.string.stats_show_elevation_key, false);
View elevationLabelTableRow1 = activity.findViewById(R.id.stats_elevation_label_table_row1);
View elevationValueTableRow1 = activity.findViewById(R.id.stats_elevation_value_table_row1);
View elevationLabelTableRow2 = activity.findViewById(R.id.stats_elevation_label_table_row2);
View elevationValueTableRow2 = activity.findViewById(R.id.stats_elevation_value_table_row2);
elevationLabelTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationValueTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationLabelTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationValueTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE);
if (showElevation) {
double elevationGain = tripStatistics == null ? Double.NaN
: tripStatistics.getTotalElevationGain();
double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
setElevationValue(activity, R.id.stats_elevation_gain_value, elevationGain, metricUnits);
setElevationValue(activity, R.id.stats_min_elevation_value, minElevation, metricUnits);
setElevationValue(activity, R.id.stats_max_elevation_value, maxElevation, metricUnits);
}
// Set grade
boolean showGrade = PreferencesUtils.getBoolean(activity, R.string.stats_show_grade_key, false);
View gradeLabelTableRow = activity.findViewById(R.id.stats_grade_label_table_row);
View gradeValueTableRow = activity.findViewById(R.id.stats_grade_value_table_row);
gradeLabelTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
gradeValueTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
if (showGrade) {
double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade();
double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade();
setGradeValue(activity, R.id.stats_min_grade_value, minGrade);
setGradeValue(activity, R.id.stats_max_grade_value, maxGrade);
}
}
/**
* Sets a time label.
*
* @param activity the activity
* @param id the time label resource id
* @param totalTimeId the total time string id
* @param movingTimeId the moving time string id
* @param totalTime true to use total time
*/
private static void setTimeLabel(Activity activity, int id, int totalTimeId, int movingTimeId,
boolean totalTime) {
TextView textView = (TextView) activity.findViewById(id);
textView.setText(totalTime ? totalTimeId : movingTimeId);
}
/**
* Sets a speed label.
*
@@ -39,7 +197,7 @@ public class StatsUtils {
* @param paceId the pace string id
* @param reportSpeed true to report speed
*/
public static void setSpeedLabel(
private static void setSpeedLabel(
Activity activity, int id, int speedId, int paceId, boolean reportSpeed) {
TextView textView = (TextView) activity.findViewById(id);
textView.setText(reportSpeed ? speedId : paceId);
@@ -51,30 +209,34 @@ public class StatsUtils {
* @param activity the activity
* @param id the speed value resource id
* @param speed the speed in meters per second
* @param reportSpeed true to report speed
* @param metricUnits true to display in metric units
* @param reportSpeed true to report speed
*/
public static void setSpeedValue(
Activity activity, int id, double speed, boolean reportSpeed, boolean metricUnits) {
private static void setSpeedValue(
Activity activity, int id, double speed, boolean metricUnits, boolean reportSpeed) {
TextView textView = (TextView) activity.findViewById(id);
speed *= UnitConversions.MS_TO_KMH;
String value;
if (metricUnits) {
if (reportSpeed) {
value = activity.getString(R.string.value_float_kilometer_hour, speed);
} else {
// convert from hours to minutes
double pace = speed == 0 ? 0.0 : 60.0 / speed;
value = activity.getString(R.string.value_float_minute_kilometer, pace);
}
if (Double.isNaN(speed) || Double.isInfinite(speed)) {
value = activity.getString(R.string.value_unknown);
} else {
speed *= UnitConversions.KM_TO_MI;
if (reportSpeed) {
value = activity.getString(R.string.value_float_mile_hour, speed);
speed *= UnitConversions.MS_TO_KMH;
if (metricUnits) {
if (reportSpeed) {
value = activity.getString(R.string.value_float_kilometer_hour, speed);
} else {
// convert from hours to minutes
double pace = speed == 0 ? 0.0 : 60.0 / speed;
value = activity.getString(R.string.value_float_minute_kilometer, pace);
}
} else {
// convert from hours to minutes
double pace = speed == 0 ? 0.0 : 60.0 / speed;
value = activity.getString(R.string.value_float_minute_mile, pace);
speed *= UnitConversions.KM_TO_MI;
if (reportSpeed) {
value = activity.getString(R.string.value_float_mile_hour, speed);
} else {
// convert from hours to minutes
double pace = speed == 0 ? 0.0 : 60.0 / speed;
value = activity.getString(R.string.value_float_minute_mile, pace);
}
}
}
textView.setText(value);
@@ -88,16 +250,20 @@ public class StatsUtils {
* @param distance the distance in meters
* @param metricUnits true to display in metric units
*/
public static void setDistanceValue(
private static void setDistanceValue(
Activity activity, int id, double distance, boolean metricUnits) {
TextView textView = (TextView) activity.findViewById(id);
distance *= UnitConversions.M_TO_KM;
String value;
if (metricUnits) {
value = activity.getString(R.string.value_float_kilometer, distance);
if (Double.isNaN(distance) || Double.isInfinite(distance)) {
value = activity.getString(R.string.value_unknown);
} else {
distance *= UnitConversions.KM_TO_MI;
value = activity.getString(R.string.value_float_mile, distance);
distance *= UnitConversions.M_TO_KM;
if (metricUnits) {
value = activity.getString(R.string.value_float_kilometer, distance);
} else {
distance *= UnitConversions.KM_TO_MI;
value = activity.getString(R.string.value_float_mile, distance);
}
}
textView.setText(value);
}
@@ -109,31 +275,33 @@ public class StatsUtils {
* @param id the time value resource id
* @param time the time
*/
public static void setTimeValue(Activity activity, int id, long time) {
private static void setTimeValue(Activity activity, int id, long time) {
TextView textView = (TextView) activity.findViewById(id);
textView.setText(StringUtils.formatElapsedTime(time));
String value = time == -1L ? activity.getString(R.string.value_unknown)
: StringUtils.formatElapsedTime(time);
textView.setText(value);
}
/**
* Sets an altitude value.
* Sets an elevation value.
*
* @param activity the activity
* @param id the altitude value resource id
* @param altitude the altitude in meters
* @param id the elevation value resource id
* @param elevation the elevation in meters
* @param metricUnits true to display in metric units
*/
public static void setAltitudeValue(
Activity activity, int id, double altitude, boolean metricUnits) {
private static void setElevationValue(
Activity activity, int id, double elevation, boolean metricUnits) {
TextView textView = (TextView) activity.findViewById(id);
String value;
if (Double.isNaN(altitude) || Double.isInfinite(altitude)) {
if (Double.isNaN(elevation) || Double.isInfinite(elevation)) {
value = activity.getString(R.string.value_unknown);
} else {
if (metricUnits) {
value = activity.getString(R.string.value_float_meter, altitude);
value = activity.getString(R.string.value_float_meter, elevation);
} else {
altitude *= UnitConversions.M_TO_FT;
value = activity.getString(R.string.value_float_feet, altitude);
elevation *= UnitConversions.M_TO_FT;
value = activity.getString(R.string.value_float_feet, elevation);
}
}
textView.setText(value);
@@ -146,7 +314,7 @@ public class StatsUtils {
* @param id the grade value resource id
* @param grade the grade in fraction between 0 and 1
*/
public static void setGradeValue(Activity activity, int id, double grade) {
private static void setGradeValue(Activity activity, int id, double grade) {
TextView textView = (TextView) activity.findViewById(id);
String value;
if (Double.isNaN(grade) || Double.isInfinite(grade)) {
@@ -156,4 +324,23 @@ public class StatsUtils {
}
textView.setText(value);
}
/**
* Sets a coordinate value.
*
* @param activity the activity
* @param id the coordinate value resource id
* @param coordinate the coordinate in degrees
*/
private static void setCoordinateValue(Activity activity, int id, double coordinate) {
TextView textView = (TextView) activity.findViewById(id);
String value;
if (Double.isNaN(coordinate) || Double.isInfinite(coordinate)) {
value = activity.getString(R.string.value_unknown);
} else {
value = activity.getString(
R.string.value_coordinate_degree, Location.convert(coordinate, Location.FORMAT_DEGREES));
}
textView.setText(value);
}
}
@@ -157,19 +157,6 @@ public class StringUtils {
}
}
}
/**
* Formats the elapsed time and distance.
*
* @param context the context
* @param elapsedTime the elapsed time in milliseconds
* @param distance the distance in meters
* @param metric true to use metric. False to use imperial
*/
public static String formatTimeDistance(
Context context, long elapsedTime, double distance, boolean metric) {
return formatElapsedTime(elapsedTime) + " " + formatDistance(context, distance, metric);
}
/**
* Formats the given text as a XML CDATA element. This includes adding the
@@ -17,9 +17,11 @@
package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.TrackEditActivity;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.maps.mytracks.R;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
@@ -28,6 +30,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import java.util.List;
@@ -106,9 +109,9 @@ public class TrackRecordingServiceConnectionUtils {
long recordingTrackId = PreferencesUtils.getRecordingTrackId(context);
trackRecordingService.endCurrentTrack();
if (recordingTrackId != -1L) {
Intent intent = new Intent(context, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_SHOW_CANCEL, false)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, recordingTrackId);
Intent intent = IntentUtils.newIntent(context, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, recordingTrackId)
.putExtra(TrackEditActivity.EXTRA_NEW_TRACK, true);
context.startActivity(intent);
}
} catch (Exception e) {
@@ -122,7 +125,7 @@ public class TrackRecordingServiceConnectionUtils {
/**
* Resumes the track recording service connection.
*
*
* @param context the context
* @param trackRecordingServiceConnection the track recording service
* connection
@@ -134,4 +137,29 @@ public class TrackRecordingServiceConnectionUtils {
PreferencesUtils.setRecordingTrackId(context, -1L);
}
}
/**
* Adds a marker.
*/
public static void addMarker(Context context,
TrackRecordingServiceConnection trackRecordingServiceConnection,
WaypointCreationRequest waypointCreationRequest) {
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
.getServiceIfBound();
if (trackRecordingService == null) {
Log.d(TAG, "Unable to add marker, no track recording service");
} else {
try {
if (trackRecordingService.insertWaypoint(waypointCreationRequest) != -1L) {
Toast.makeText(context, R.string.marker_add_success, Toast.LENGTH_SHORT).show();
return;
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to add marker", e);
} catch (IllegalStateException e) {
Log.e(TAG, "Unable to add marker.", e);
}
}
Toast.makeText(context, R.string.marker_add_error, Toast.LENGTH_LONG).show();
}
}
@@ -20,11 +20,13 @@ import static com.google.android.apps.mytracks.Constants.SETTINGS_NAME;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.TrackListActivity;
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.services.ControlRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -69,7 +71,7 @@ public class TrackWidgetProvider
private Context context;
private String unknown;
private TrackObserver trackObserver;
private boolean isMetric;
private boolean metricUnits;
private boolean reportSpeed;
private long selectedTrackId;
private SharedPreferences sharedPreferences;
@@ -146,10 +148,12 @@ public class TrackWidgetProvider
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.track_widget);
// Make all of the stats open the mytracks activity.
Intent intent = new Intent(context, TrackDetailActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Intent intent;
if (track != null) {
intent.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, track.getId());
intent = IntentUtils.newIntent(context, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, track.getId());
} else {
intent = IntentUtils.newIntent(context, TrackListActivity.class);
}
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.appwidget_track_statistics, pendingIntent);
@@ -174,11 +178,11 @@ public class TrackWidgetProvider
if (TRACK_STARTED_ACTION.equals(action)) {
// If a new track is started by this appwidget or elsewhere,
// toggle the button to active and have it disable the track if pressed.
setButtonIntent(views, R.string.track_action_end, R.drawable.appwidget_button_enabled);
setButtonIntent(views, R.string.track_action_end, R.drawable.app_widget_button_enabled);
} else {
// If a track is stopped by this appwidget or elsewhere,
// toggle the button to inactive and have it start a new track if pressed.
setButtonIntent(views, R.string.track_action_start, R.drawable.appwidget_button_disabled);
setButtonIntent(views, R.string.track_action_start, R.drawable.app_widget_button_disabled);
}
}
@@ -190,8 +194,8 @@ public class TrackWidgetProvider
* @param icon The resource id of the icon to show for the button
*/
private void setButtonIntent(RemoteViews views, int action, int icon) {
Intent intent = new Intent(context, ControlRecordingService.class);
intent.setAction(context.getString(action));
Intent intent = new Intent(context, ControlRecordingService.class)
.setAction(context.getString(action));
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.appwidget_button, pendingIntent);
@@ -214,10 +218,10 @@ public class TrackWidgetProvider
}
TripStatistics stats = track.getStatistics();
String distance = StringUtils.formatDistance(context, stats.getTotalDistance(), isMetric);
String distance = StringUtils.formatDistance(context, stats.getTotalDistance(), metricUnits);
String time = StringUtils.formatElapsedTime(stats.getMovingTime());
String speed = StringUtils.formatSpeed(
context, stats.getAverageMovingSpeed(), isMetric, reportSpeed);
context, stats.getAverageMovingSpeed(), metricUnits, reportSpeed);
views.setTextViewText(R.id.appwidget_distance_text, distance);
views.setTextViewText(R.id.appwidget_time_text, time);
@@ -226,14 +230,12 @@ public class TrackWidgetProvider
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
String metricUnitsKey = context.getString(R.string.metric_units_key);
if (key == null || key.equals(metricUnitsKey)) {
isMetric = prefs.getBoolean(metricUnitsKey, true);
if (key == null || key.equals(PreferencesUtils.getMetricUnitsKey(context))) {
metricUnits = PreferencesUtils.isMetricUnits(context);
}
String reportSpeedKey = context.getString(R.string.report_speed_key);
if (key == null || key.equals(reportSpeedKey)) {
reportSpeed = prefs.getBoolean(reportSpeedKey, true);
if (key == null || key.equals(PreferencesUtils.getReportSpeedKey(context))) {
reportSpeed = PreferencesUtils.isReportSpeed(context);
}
if (key == null || key.equals(PreferencesUtils.getSelectedTrackIdKey(context))) {