forked from upstream-mirrors/OpenTracks
Merge heads
This commit is contained in:
@@ -7,7 +7,7 @@ Android Support Package:
|
|||||||
android-support-v4.jar (version 13)
|
android-support-v4.jar (version 13)
|
||||||
|
|
||||||
Ant+:
|
Ant+:
|
||||||
antlib.jar - see http://www.thisisant.com/pages/developer-zone/android-api
|
antlib.jar - from Android_ANT_SDK_20120625.zip
|
||||||
|
|
||||||
Google APIs Client Library for Java:
|
Google APIs Client Library for Java:
|
||||||
google-api-client-1.12.0-beta.jar
|
google-api-client-1.12.0-beta.jar
|
||||||
|
|||||||
Binary file not shown.
@@ -384,9 +384,9 @@ limitations under the License.
|
|||||||
<string name="description_average_moving_pace"
|
<string name="description_average_moving_pace"
|
||||||
translation_description="Average moving pace description.
|
translation_description="Average moving pace description.
|
||||||
|
|
||||||
%1$.2f pace in minutes per kilometer
|
%1$s pace in minutes per kilometer
|
||||||
%2$.1f pace in minutes per mile">
|
%2$s pace in minutes per mile">
|
||||||
Average moving pace: %1$.2f min/km (%2$.1f min/mi)
|
Average moving pace: %1$s min/km (%2$s min/mi)
|
||||||
</string>
|
</string>
|
||||||
<string name="description_average_moving_speed"
|
<string name="description_average_moving_speed"
|
||||||
translation_description="Average moving speed description.
|
translation_description="Average moving speed description.
|
||||||
@@ -398,9 +398,9 @@ limitations under the License.
|
|||||||
<string name="description_average_pace"
|
<string name="description_average_pace"
|
||||||
translation_description="Average pace description.
|
translation_description="Average pace description.
|
||||||
|
|
||||||
%1$.2f pace in minutes per kilometer
|
%1$s pace in minutes per kilometer
|
||||||
%2$.1f pace in minutes per mile">
|
%2$s pace in minutes per mile">
|
||||||
Average pace: %1$.2f min/km (%2$.1f min/mi)
|
Average pace: %1$s min/km (%2$s min/mi)
|
||||||
</string>
|
</string>
|
||||||
<string name="description_average_speed"
|
<string name="description_average_speed"
|
||||||
translation_description="Average speed description.
|
translation_description="Average speed description.
|
||||||
@@ -427,9 +427,9 @@ limitations under the License.
|
|||||||
<string name="description_fastest_pace"
|
<string name="description_fastest_pace"
|
||||||
translation_description="Fastest pace description.
|
translation_description="Fastest pace description.
|
||||||
|
|
||||||
%1$.2f pace in minutes per kilometer
|
%1$s pace in minutes per kilometer
|
||||||
%2$.1f pace in minutes per mile">
|
%2$s pace in minutes per mile">
|
||||||
Fastest pace: %1$.2f min/km (%2$.1f min/mi)
|
Fastest pace: %1$s min/km (%2$s min/mi)
|
||||||
</string>
|
</string>
|
||||||
<string name="description_location_accuracy"
|
<string name="description_location_accuracy"
|
||||||
translation_description="Label for location accuracy in meters.">
|
translation_description="Label for location accuracy in meters.">
|
||||||
@@ -497,12 +497,12 @@ limitations under the License.
|
|||||||
Moving time: %1$s
|
Moving time: %1$s
|
||||||
</string>
|
</string>
|
||||||
<string name="description_pace_imperial"
|
<string name="description_pace_imperial"
|
||||||
translation_description="Pace in imperial units, hours per mile.">
|
translation_description="Pace in imperial units, minutes per mile.">
|
||||||
Pace (hr/mi)
|
Pace (min/mi)
|
||||||
</string>
|
</string>
|
||||||
<string name="description_pace_metric"
|
<string name="description_pace_metric"
|
||||||
translation_description="Pace in metric units, hours per kilometer.">
|
translation_description="Pace in metric units, minutes per kilometer.">
|
||||||
Pace (hr/km)
|
Pace (min/km)
|
||||||
</string>
|
</string>
|
||||||
<string name="description_recorded_time"
|
<string name="description_recorded_time"
|
||||||
translation_description="Recorded time description.
|
translation_description="Recorded time description.
|
||||||
@@ -1974,7 +1974,7 @@ limitations under the License.
|
|||||||
</string>
|
</string>
|
||||||
<string name="settings_stats_rate_title"
|
<string name="settings_stats_rate_title"
|
||||||
translation_description="In the 'Stats' settings, the option to change the preferred rate,
|
translation_description="In the 'Stats' settings, the option to change the preferred rate,
|
||||||
either speed (mi/hr) or pace (hr/mi).
|
either speed (mi/hr) or pace (min/mi).
|
||||||
|
|
||||||
Character limit: ~23 (1 line)">
|
Character limit: ~23 (1 line)">
|
||||||
Preferred rate
|
Preferred rate
|
||||||
@@ -2131,7 +2131,7 @@ limitations under the License.
|
|||||||
Moving time
|
Moving time
|
||||||
</string>
|
</string>
|
||||||
<string name="stats_pace"
|
<string name="stats_pace"
|
||||||
translation_description="In the 'Stats' page, the pace like hours per mile.
|
translation_description="In the 'Stats' page, the pace like minutes per mile.
|
||||||
|
|
||||||
Character limit: ~23 (1 line)">
|
Character limit: ~23 (1 line)">
|
||||||
Pace
|
Pace
|
||||||
|
|||||||
@@ -653,13 +653,14 @@ public class ChartView extends View {
|
|||||||
canvas.drawLine(x, y, x + effectiveWidth, y, axisPaint);
|
canvas.drawLine(x, y, x + effectiveWidth, y, axisPaint);
|
||||||
String label = getXAxisLabel();
|
String label = getXAxisLabel();
|
||||||
Rect rect = getRect(axisPaint, label);
|
Rect rect = getRect(axisPaint, label);
|
||||||
canvas.drawText(label, x + effectiveWidth + spacer, y + ((int) rect.height() / 2), axisPaint);
|
int yOffset = (int) rect.height() / 2;
|
||||||
|
canvas.drawText(label, x + effectiveWidth + spacer, y + yOffset, axisPaint);
|
||||||
|
|
||||||
double interval = getXAxisInterval();
|
double interval = getXAxisInterval();
|
||||||
ArrayList<Double> markerPositions = getXAxisMarkerPositions(interval);
|
ArrayList<Double> markerPositions = getXAxisMarkerPositions(interval);
|
||||||
NumberFormat numberFormat = interval < 1 ? X_FRACTION_FORMAT : X_NUMBER_FORMAT;
|
NumberFormat numberFormat = interval < 1 ? X_FRACTION_FORMAT : X_NUMBER_FORMAT;
|
||||||
for (int i = 0; i < markerPositions.size(); i++) {
|
for (int i = 0; i < markerPositions.size(); i++) {
|
||||||
drawXAxisMarker(canvas, markerPositions.get(i), numberFormat);
|
drawXAxisMarker(canvas, markerPositions.get(i), numberFormat, spacer + yOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,12 +683,14 @@ public class ChartView extends View {
|
|||||||
* @param canvas
|
* @param canvas
|
||||||
* @param value value
|
* @param value value
|
||||||
* @param numberFormat the number format
|
* @param numberFormat the number format
|
||||||
|
* @param spacing the spacing between x axis and marker
|
||||||
*/
|
*/
|
||||||
private void drawXAxisMarker(Canvas canvas, double value, NumberFormat numberFormat) {
|
private void drawXAxisMarker(
|
||||||
|
Canvas canvas, double value, NumberFormat numberFormat, int spacing) {
|
||||||
String marker = chartByDistance ? numberFormat.format(value)
|
String marker = chartByDistance ? numberFormat.format(value)
|
||||||
: StringUtils.formatElapsedTime((long) value);
|
: StringUtils.formatElapsedTime((long) value);
|
||||||
Rect rect = getRect(xAxisMarkerPaint, marker);
|
Rect rect = getRect(xAxisMarkerPaint, marker);
|
||||||
canvas.drawText(marker, getX(value), topBorder + effectiveHeight + spacer + rect.height(),
|
canvas.drawText(marker, getX(value), topBorder + effectiveHeight + spacing + rect.height(),
|
||||||
xAxisMarkerPaint);
|
xAxisMarkerPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,8 +909,11 @@ public class ChartView extends View {
|
|||||||
leftBorder = (int) (density * BORDER + markerLength);
|
leftBorder = (int) (density * BORDER + markerLength);
|
||||||
int[] titleDimensions = getTitleDimenions();
|
int[] titleDimensions = getTitleDimenions();
|
||||||
topBorder = (int) (density * BORDER + titleDimensions[0] * (titleDimensions[1] + spacer));
|
topBorder = (int) (density * BORDER + titleDimensions[0] * (titleDimensions[1] + spacer));
|
||||||
bottomBorder = (int) (density * BORDER + getRect(xAxisMarkerPaint, "1").height() + spacer);
|
Rect xAxisLabelRect = getRect(axisPaint, getXAxisLabel());
|
||||||
rightBorder = (int) (density * BORDER + getRect(axisPaint, getXAxisLabel()).width() + spacer);
|
// border + x axis marker + spacer + .5 x axis label
|
||||||
|
bottomBorder = (int) (density * BORDER + getRect(xAxisMarkerPaint, "1").height() + spacer
|
||||||
|
+ (int) (xAxisLabelRect.height() / 2));
|
||||||
|
rightBorder = (int) (density * BORDER + xAxisLabelRect.width() + spacer);
|
||||||
updateEffectiveDimensions();
|
updateEffectiveDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,12 @@ import com.google.android.maps.mytracks.R;
|
|||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An activity that displays information about sensors.
|
* An activity that displays information about sensors.
|
||||||
*
|
*
|
||||||
@@ -43,12 +41,14 @@ import java.util.TimerTask;
|
|||||||
public class SensorStateActivity extends AbstractMyTracksActivity {
|
public class SensorStateActivity extends AbstractMyTracksActivity {
|
||||||
|
|
||||||
private static final String TAG = SensorStateActivity.class.getName();
|
private static final String TAG = SensorStateActivity.class.getName();
|
||||||
private static final long REFRESH_PERIOD_MS = 250;
|
private static final long ONE_SECOND = 1000;
|
||||||
|
|
||||||
/**
|
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||||
* A Runnable to update the UI.
|
private Handler handler;
|
||||||
*/
|
private SensorManager tempSensorManager;
|
||||||
private final Runnable updateRunnable = new Runnable() {
|
|
||||||
|
private final Runnable updateUiRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
|
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
|
||||||
.getServiceIfBound();
|
.getServiceIfBound();
|
||||||
@@ -69,30 +69,15 @@ public class SensorStateActivity extends AbstractMyTracksActivity {
|
|||||||
stopTempSensorManager();
|
stopTempSensorManager();
|
||||||
updateFromSystemSensorManager();
|
updateFromSystemSensorManager();
|
||||||
}
|
}
|
||||||
|
handler.postDelayed(this, ONE_SECOND);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* A TimeTask to update the UI.
|
|
||||||
*/
|
|
||||||
private class UpdateTimerTask extends TimerTask {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (isVisible) {
|
|
||||||
runOnUiThread(updateRunnable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
|
||||||
private boolean isVisible = false;
|
|
||||||
private Timer timer = null;
|
|
||||||
private SensorManager tempSensorManager = null;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
|
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
|
||||||
|
handler = new Handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -104,18 +89,13 @@ public class SensorStateActivity extends AbstractMyTracksActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
isVisible = true;
|
handler.post(updateUiRunnable);
|
||||||
timer = new Timer();
|
|
||||||
timer.schedule(new UpdateTimerTask(), 0, REFRESH_PERIOD_MS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
isVisible = false;
|
handler.removeCallbacks(updateUiRunnable);
|
||||||
timer.cancel();
|
|
||||||
timer.purge();
|
|
||||||
timer = null;
|
|
||||||
stopTempSensorManager();
|
stopTempSensorManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -367,7 +367,8 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
|
|||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
|
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
|
||||||
return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, null,
|
return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, null,
|
||||||
null, TracksColumns.SHAREDWITHME + " ASC, " + TracksColumns.STARTTIME + " DESC");
|
null, "IFNULL(" + TracksColumns.SHAREDWITHME + ",0) ASC, " + TracksColumns.STARTTIME
|
||||||
|
+ " DESC");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+24
-32
@@ -24,7 +24,6 @@ import com.google.android.maps.mytracks.R;
|
|||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Pair;
|
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
@@ -117,25 +116,24 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
|
|||||||
writeTime(stats.getMovingTime(), builder, R.string.description_moving_time, lineBreak);
|
writeTime(stats.getMovingTime(), builder, R.string.description_moving_time, lineBreak);
|
||||||
|
|
||||||
// Average speed
|
// Average speed
|
||||||
Pair<Double, Double> averageSpeed = writeSpeed(
|
writeSpeed(stats.getAverageSpeed(), builder, R.string.description_average_speed, lineBreak);
|
||||||
stats.getAverageSpeed(), builder, R.string.description_average_speed, lineBreak);
|
|
||||||
|
|
||||||
// Average moving speed
|
// Average moving speed
|
||||||
Pair<Double, Double> averageMovingSpeed = writeSpeed(stats.getAverageMovingSpeed(), builder,
|
writeSpeed(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_speed,
|
||||||
R.string.description_average_moving_speed, lineBreak);
|
lineBreak);
|
||||||
|
|
||||||
// Max speed
|
// Max speed
|
||||||
Pair<Double, Double> maxSpeed = writeSpeed(
|
writeSpeed(stats.getMaxSpeed(), builder, R.string.description_max_speed, lineBreak);
|
||||||
stats.getMaxSpeed(), builder, R.string.description_max_speed, lineBreak);
|
|
||||||
|
|
||||||
// Average pace
|
// Average pace
|
||||||
writePace(averageSpeed, builder, R.string.description_average_pace, lineBreak);
|
writePace(stats.getAverageSpeed(), builder, R.string.description_average_pace, lineBreak);
|
||||||
|
|
||||||
// Average moving pace
|
// Average moving pace
|
||||||
writePace(averageMovingSpeed, builder, R.string.description_average_moving_pace, lineBreak);
|
writePace(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_pace,
|
||||||
|
lineBreak);
|
||||||
|
|
||||||
// Fastest pace
|
// Fastest pace
|
||||||
writePace(maxSpeed, builder, R.string.description_fastest_pace, lineBreak);
|
writePace(stats.getMaxSpeed(), builder, R.string.description_fastest_pace, lineBreak);
|
||||||
|
|
||||||
// Max elevation
|
// Max elevation
|
||||||
writeElevation(stats.getMaxElevation(), builder, R.string.description_max_elevation, lineBreak);
|
writeElevation(stats.getMaxElevation(), builder, R.string.description_max_elevation, lineBreak);
|
||||||
@@ -199,34 +197,38 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
|
|||||||
* @param builder StringBuilder to append speed
|
* @param builder StringBuilder to append speed
|
||||||
* @param resId resource id of speed string
|
* @param resId resource id of speed string
|
||||||
* @param lineBreak line break string
|
* @param lineBreak line break string
|
||||||
* @return a pair of speed, first in kilometers per hour, second in miles per
|
|
||||||
* hour.
|
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Pair<Double, Double> writeSpeed(
|
void writeSpeed(
|
||||||
double speed, StringBuilder builder, int resId, String lineBreak) {
|
double speed, StringBuilder builder, int resId, String lineBreak) {
|
||||||
double speedInKmHr = speed * UnitConversions.MS_TO_KMH;
|
double speedInKmHr = speed * UnitConversions.MS_TO_KMH;
|
||||||
double speedInMiHr = speedInKmHr * UnitConversions.KM_TO_MI;
|
double speedInMiHr = speedInKmHr * UnitConversions.KM_TO_MI;
|
||||||
builder.append(context.getString(resId, speedInKmHr, speedInMiHr));
|
builder.append(context.getString(resId, speedInKmHr, speedInMiHr));
|
||||||
builder.append(lineBreak);
|
builder.append(lineBreak);
|
||||||
return Pair.create(speedInKmHr, speedInMiHr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes pace.
|
* Writes pace.
|
||||||
*
|
*
|
||||||
* @param speed a pair of speed, first in kilometers per hour, second in miles
|
* @param speed speed in meters per second
|
||||||
* per hour
|
|
||||||
* @param builder StringBuilder to append pace
|
* @param builder StringBuilder to append pace
|
||||||
* @param resId resource id of pace string
|
* @param resId resource id of pace string
|
||||||
* @param lineBreak line break string
|
* @param lineBreak line break string
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void writePace(
|
void writePace(double speed, StringBuilder builder, int resId, String lineBreak) {
|
||||||
Pair<Double, Double> speed, StringBuilder builder, int resId, String lineBreak) {
|
String[] paceInMetrics = StringUtils.getSpeedParts(context, speed, true, false);
|
||||||
double paceInMinKm = getPace(speed.first);
|
String[] paceInImperial = StringUtils.getSpeedParts(context, speed, false, false);
|
||||||
double paceInMinMi = getPace(speed.second);
|
|
||||||
builder.append(context.getString(resId, paceInMinKm, paceInMinMi));
|
if (paceInMetrics[0] == null) {
|
||||||
|
paceInMetrics[0] = context.getString(R.string.value_unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paceInImperial[0] == null) {
|
||||||
|
paceInImperial[0] = context.getString(R.string.value_unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(context.getString(resId, paceInMetrics[0], paceInImperial[0]));
|
||||||
builder.append(lineBreak);
|
builder.append(lineBreak);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,14 +264,4 @@ public class DescriptionGeneratorImpl implements DescriptionGenerator {
|
|||||||
builder.append(context.getString(resId, gradeInPercent));
|
builder.append(context.getString(resId, gradeInPercent));
|
||||||
builder.append(lineBreak);
|
builder.append(lineBreak);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets pace (in minutes) from speed.
|
|
||||||
*
|
|
||||||
* @param speed speed in hours
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
double getPace(double speed) {
|
|
||||||
return speed == 0 ? 0.0 : 60.0 / speed; // convert from hours to minutes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,9 +134,10 @@ public class TrackDataHub implements DataSourceListener {
|
|||||||
started = false;
|
started = false;
|
||||||
|
|
||||||
dataSourceManager.unregisterAllListeners();
|
dataSourceManager.unregisterAllListeners();
|
||||||
handlerThread.getLooper().quit();
|
if (handlerThread != null) {
|
||||||
|
handlerThread.getLooper().quit();
|
||||||
handlerThread = null;
|
handlerThread = null;
|
||||||
|
}
|
||||||
handler = null;
|
handler = null;
|
||||||
dataSource = null;
|
dataSource = null;
|
||||||
dataSourceManager = null;
|
dataSourceManager = null;
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ import android.content.DialogInterface;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.util.Linkify;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -89,8 +93,12 @@ public class EulaDialogFragment extends DialogFragment {
|
|||||||
fragmentActivity = getActivity();
|
fragmentActivity = getActivity();
|
||||||
|
|
||||||
boolean hasAccepted = getArguments().getBoolean(KEY_HAS_ACCEPTED);
|
boolean hasAccepted = getArguments().getBoolean(KEY_HAS_ACCEPTED);
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(fragmentActivity).setMessage(
|
|
||||||
getEulaText()).setTitle(R.string.eula_title);
|
SpannableString message = new SpannableString(getEulaText());
|
||||||
|
Linkify.addLinks(message, Linkify.WEB_URLS);
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(fragmentActivity).setMessage(message)
|
||||||
|
.setTitle(R.string.eula_title);
|
||||||
|
|
||||||
if (hasAccepted) {
|
if (hasAccepted) {
|
||||||
builder.setPositiveButton(R.string.generic_ok, null);
|
builder.setPositiveButton(R.string.generic_ok, null);
|
||||||
@@ -117,10 +125,17 @@ public class EulaDialogFragment extends DialogFragment {
|
|||||||
caller.onEulaDone();
|
caller.onEulaDone();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
TextView textView = (TextView) getDialog().findViewById(android.R.id.message);
|
||||||
|
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancel(DialogInterface arg0) {
|
public void onCancel(DialogInterface arg0) {
|
||||||
caller.onEulaDone();
|
caller.onEulaDone();
|
||||||
|
|||||||
+12
-9
@@ -237,7 +237,8 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask {
|
|||||||
|
|
||||||
int count = cursor.getCount();
|
int count = cursor.getCount();
|
||||||
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
||||||
Location lastLocation = null;
|
Location lastValidLocation = null;
|
||||||
|
boolean sentStartMarker = false;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
cursor.moveToPosition(i);
|
cursor.moveToPosition(i);
|
||||||
@@ -245,14 +246,15 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask {
|
|||||||
Location location = myTracksProviderUtils.createTrackPoint(cursor);
|
Location location = myTracksProviderUtils.createTrackPoint(cursor);
|
||||||
locations.add(location);
|
locations.add(location);
|
||||||
|
|
||||||
if (i == 0) {
|
if (LocationUtils.isValidLocation(location)) {
|
||||||
// Create a start marker
|
lastValidLocation = location;
|
||||||
String name = context.getString(R.string.marker_label_start, track.getName());
|
|
||||||
createNewPoint(fusiontables, tableId, name, "", location, MARKER_TYPE_START);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LocationUtils.isValidLocation(location)) {
|
if (!sentStartMarker && lastValidLocation != null) {
|
||||||
lastLocation = location;
|
// Create a start marker
|
||||||
|
String name = context.getString(R.string.marker_label_start, track.getName());
|
||||||
|
createNewPoint(fusiontables, tableId, name, "", lastValidLocation, MARKER_TYPE_START);
|
||||||
|
sentStartMarker = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload periodically
|
// Upload periodically
|
||||||
@@ -274,11 +276,12 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an end marker
|
// Create an end marker
|
||||||
if (lastLocation != null) {
|
if (lastValidLocation != null) {
|
||||||
String name = context.getString(R.string.marker_label_end, track.getName());
|
String name = context.getString(R.string.marker_label_end, track.getName());
|
||||||
DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context);
|
DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context);
|
||||||
String description = descriptionGenerator.generateTrackDescription(track, null, null, true);
|
String description = descriptionGenerator.generateTrackDescription(track, null, null, true);
|
||||||
createNewPoint(fusiontables, tableId, name, description, lastLocation, MARKER_TYPE_END);
|
createNewPoint(
|
||||||
|
fusiontables, tableId, name, description, lastValidLocation, MARKER_TYPE_END);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -244,7 +244,8 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
|
|||||||
|
|
||||||
int count = cursor.getCount();
|
int count = cursor.getCount();
|
||||||
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
||||||
Location lastLocation = null;
|
Location lastValidLocation = null;
|
||||||
|
boolean sentStartMarker = false;
|
||||||
|
|
||||||
// For chart server, limit the number of elevation readings to 250.
|
// For chart server, limit the number of elevation readings to 250.
|
||||||
int elevationSamplingFrequency = Math.max(1, (int) (count / 250.0));
|
int elevationSamplingFrequency = Math.max(1, (int) (count / 250.0));
|
||||||
@@ -261,13 +262,18 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
|
|||||||
Location location = myTracksProviderUtils.createTrackPoint(cursor);
|
Location location = myTracksProviderUtils.createTrackPoint(cursor);
|
||||||
locations.add(location);
|
locations.add(location);
|
||||||
|
|
||||||
if (i == 0) {
|
if (LocationUtils.isValidLocation(location)) {
|
||||||
|
lastValidLocation = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sentStartMarker && lastValidLocation != null) {
|
||||||
// Create a start marker
|
// Create a start marker
|
||||||
if (!uploadMarker(context.getString(R.string.marker_label_start, track.getName()), "",
|
if (!uploadMarker(context.getString(R.string.marker_label_start, track.getName()), "",
|
||||||
START_ICON_URL, location)) {
|
START_ICON_URL, lastValidLocation)) {
|
||||||
Log.d(TAG, "Unable to create a start marker");
|
Log.d(TAG, "Unable to create a start marker");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
sentStartMarker = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tripStatisticsUpdater.addLocation(location, minRecordingDistance);
|
tripStatisticsUpdater.addLocation(location, minRecordingDistance);
|
||||||
@@ -275,9 +281,6 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
|
|||||||
distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance());
|
distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance());
|
||||||
elevations.add(tripStatisticsUpdater.getSmoothedElevation());
|
elevations.add(tripStatisticsUpdater.getSmoothedElevation());
|
||||||
}
|
}
|
||||||
if (LocationUtils.isValidLocation(location)) {
|
|
||||||
lastLocation = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload periodically
|
// Upload periodically
|
||||||
int readCount = i + 1;
|
int readCount = i + 1;
|
||||||
@@ -298,14 +301,14 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an end marker
|
// Create an end marker
|
||||||
if (lastLocation != null) {
|
if (lastValidLocation != null) {
|
||||||
distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance());
|
distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance());
|
||||||
elevations.add(tripStatisticsUpdater.getSmoothedElevation());
|
elevations.add(tripStatisticsUpdater.getSmoothedElevation());
|
||||||
DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context);
|
DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context);
|
||||||
track.setDescription(
|
track.setDescription(
|
||||||
descriptionGenerator.generateTrackDescription(track, distances, elevations, true));
|
descriptionGenerator.generateTrackDescription(track, distances, elevations, true));
|
||||||
if (!uploadMarker(context.getString(R.string.marker_label_end, track.getName()),
|
if (!uploadMarker(context.getString(R.string.marker_label_end, track.getName()),
|
||||||
track.getDescription(), END_ICON_URL, lastLocation)) {
|
track.getDescription(), END_ICON_URL, lastValidLocation)) {
|
||||||
Log.d(TAG, "Unable to create an end marker");
|
Log.d(TAG, "Unable to create an end marker");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,8 +133,9 @@ public class TrackRecordingService extends Service {
|
|||||||
private Location lastLocation;
|
private Location lastLocation;
|
||||||
private boolean currentSegmentHasLocation;
|
private boolean currentSegmentHasLocation;
|
||||||
|
|
||||||
// Timer to periodically invoke checkLocationListener
|
// TimerTask to register location listener
|
||||||
private final Timer timer = new Timer();
|
private TimerTask timerTask;
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
// Handler for the timer to post a runnable to the main thread
|
// Handler for the timer to post a runnable to the main thread
|
||||||
private final Handler handler = new Handler();
|
private final Handler handler = new Handler();
|
||||||
@@ -247,15 +248,6 @@ public class TrackRecordingService extends Service {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private TimerTask checkLocationListener = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (isRecording() && !isPaused()) {
|
|
||||||
registerLocationListener();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final ConnectionCallbacks activityRecognitionCallbacks = new ConnectionCallbacks() {
|
private final ConnectionCallbacks activityRecognitionCallbacks = new ConnectionCallbacks() {
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected() {}
|
public void onDisconnected() {}
|
||||||
@@ -301,10 +293,19 @@ public class TrackRecordingService extends Service {
|
|||||||
// onSharedPreferenceChanged might not set recordingTrackId.
|
// onSharedPreferenceChanged might not set recordingTrackId.
|
||||||
recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
||||||
|
|
||||||
// Require announcementExecutor and splitExecutor to be created.
|
// Require voiceExecutor and splitExecutor to be created.
|
||||||
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
|
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
|
||||||
|
|
||||||
timer.schedule(checkLocationListener, 0, ONE_MINUTE);
|
timerTask = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (isRecording() && !isPaused()) {
|
||||||
|
registerLocationListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timer = new Timer("TrackRecordingServiceTimer");
|
||||||
|
timer.schedule(timerTask, 0, ONE_MINUTE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to restart the previous recording track in case the service has been
|
* Try to restart the previous recording track in case the service has been
|
||||||
@@ -357,10 +358,15 @@ public class TrackRecordingService extends Service {
|
|||||||
showNotification(false);
|
showNotification(false);
|
||||||
|
|
||||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||||
checkLocationListener.cancel();
|
if (timerTask != null) {
|
||||||
checkLocationListener = null;
|
timerTask.cancel();
|
||||||
timer.cancel();
|
timerTask = null;
|
||||||
timer.purge();
|
}
|
||||||
|
if (timer != null) {
|
||||||
|
timer.cancel();
|
||||||
|
timer.purge();
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
unregisterLocationListener();
|
unregisterLocationListener();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -39,30 +39,8 @@ public abstract class SensorManager {
|
|||||||
private SensorState sensorState = SensorState.NONE;
|
private SensorState sensorState = SensorState.NONE;
|
||||||
private long sensorStateTimestamp = System.currentTimeMillis();
|
private long sensorStateTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
/**
|
private TimerTask timerTask;
|
||||||
* A time task to check sensor connection.
|
private Timer timer;
|
||||||
*/
|
|
||||||
private TimerTask checkSensorConnectionTimeTask = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
switch (getSensorState()) {
|
|
||||||
case CONNECTING:
|
|
||||||
if (System.currentTimeMillis() - sensorStateTimestamp > MAX_SENSOR_STATE_AGE) {
|
|
||||||
Log.i(TAG, "Retry setUpChannel");
|
|
||||||
setUpChannel();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NONE:
|
|
||||||
case DISCONNECTED:
|
|
||||||
setUpChannel();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final Timer timer = new Timer();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the sensor is enabled.
|
* Returns true if the sensor is enabled.
|
||||||
@@ -89,14 +67,43 @@ public abstract class SensorManager {
|
|||||||
*/
|
*/
|
||||||
public void startSensor() {
|
public void startSensor() {
|
||||||
setUpChannel();
|
setUpChannel();
|
||||||
timer.schedule(checkSensorConnectionTimeTask, RETRY_PERIOD, RETRY_PERIOD);
|
timerTask = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
switch (getSensorState()) {
|
||||||
|
case CONNECTING:
|
||||||
|
if (System.currentTimeMillis() - sensorStateTimestamp > MAX_SENSOR_STATE_AGE) {
|
||||||
|
Log.i(TAG, "Retry setUpChannel");
|
||||||
|
setUpChannel();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NONE:
|
||||||
|
case DISCONNECTED:
|
||||||
|
setUpChannel();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// CONNECTED or SENDING
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timer = new Timer("SensorManagerTimer");
|
||||||
|
timer.schedule(timerTask, RETRY_PERIOD, RETRY_PERIOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the sensor.
|
* Stops the sensor.
|
||||||
*/
|
*/
|
||||||
public void stopSensor() {
|
public void stopSensor() {
|
||||||
timer.cancel();
|
if (timerTask != null) {
|
||||||
|
timerTask.cancel();
|
||||||
|
timerTask = null;
|
||||||
|
}
|
||||||
|
if (timer != null) {
|
||||||
|
timer.cancel();
|
||||||
|
timer.purge();
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
tearDownChannel();
|
tearDownChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-30
@@ -33,10 +33,7 @@ public class TimerTaskExecutor {
|
|||||||
private final PeriodicTask periodicTask;
|
private final PeriodicTask periodicTask;
|
||||||
private final TrackRecordingService trackRecordingService;
|
private final TrackRecordingService trackRecordingService;
|
||||||
|
|
||||||
/**
|
private TimerTask timerTask;
|
||||||
* A timer to schedule the announcements. This is non-null if the task is in
|
|
||||||
* started (scheduled) state.
|
|
||||||
*/
|
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
|
||||||
public TimerTaskExecutor(PeriodicTask periodicTask, TrackRecordingService trackRecordingService) {
|
public TimerTaskExecutor(PeriodicTask periodicTask, TrackRecordingService trackRecordingService) {
|
||||||
@@ -50,6 +47,10 @@ public class TimerTaskExecutor {
|
|||||||
* @param interval the interval in milliseconds
|
* @param interval the interval in milliseconds
|
||||||
*/
|
*/
|
||||||
public void scheduleTask(long interval) {
|
public void scheduleTask(long interval) {
|
||||||
|
if (interval <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!trackRecordingService.isRecording() || trackRecordingService.isPaused()) {
|
if (!trackRecordingService.isRecording() || trackRecordingService.isPaused()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -59,43 +60,32 @@ public class TimerTaskExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer != null) {
|
shutdown();
|
||||||
timer.cancel();
|
periodicTask.start();
|
||||||
timer.purge();
|
timerTask = new TimerTask() {
|
||||||
} else {
|
@Override
|
||||||
// First start, or we were previously shut down.
|
public void run() {
|
||||||
periodicTask.start();
|
periodicTask.run(trackRecordingService);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
timer = new Timer();
|
timer = new Timer("TimerTaskExecutorTimer");
|
||||||
if (interval <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long next = System.currentTimeMillis() + interval - (tripStatistics.getTotalTime() % interval);
|
long next = System.currentTimeMillis() + interval - (tripStatistics.getTotalTime() % interval);
|
||||||
timer.scheduleAtFixedRate(new PeriodicTimerTask(), new Date(next), interval);
|
timer.scheduleAtFixedRate(timerTask, new Date(next), interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts down.
|
* Shuts down.
|
||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
|
if (timerTask != null) {
|
||||||
|
timerTask.cancel();
|
||||||
|
timerTask = null;
|
||||||
|
}
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
timer.purge();
|
timer.purge();
|
||||||
timer = null;
|
timer = null;
|
||||||
periodicTask.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The timer task to announce the trip status.
|
|
||||||
*/
|
|
||||||
private class PeriodicTimerTask extends TimerTask {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
periodicTask.run(trackRecordingService);
|
|
||||||
}
|
}
|
||||||
|
periodicTask.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,19 +213,18 @@ public class StringUtils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
speed *= UnitConversions.MS_TO_KMH;
|
speed *= UnitConversions.MS_TO_KMH;
|
||||||
if (metricUnits) {
|
if (!metricUnits) {
|
||||||
if (!reportSpeed) {
|
|
||||||
// convert from hours to minutes
|
|
||||||
speed = speed == 0 ? 0.0 : 60.0 / speed;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
speed *= UnitConversions.KM_TO_MI;
|
speed *= UnitConversions.KM_TO_MI;
|
||||||
if (!reportSpeed) {
|
|
||||||
// convert from hours to minutes
|
|
||||||
speed = speed == 0 ? 0.0 : 60.0 / speed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result[0] = String.format("%.2f", speed);
|
if (reportSpeed) {
|
||||||
|
result[0] = String.format("%.2f", speed);
|
||||||
|
} else {
|
||||||
|
// convert from hours to minutes
|
||||||
|
double pace = speed == 0 ? 0.0 : 60.0 / speed;
|
||||||
|
int minutes = (int) pace;
|
||||||
|
int seconds = (int) Math.round((pace - minutes) * 60.0);
|
||||||
|
result[0] = String.format("%d:%02d", minutes, seconds);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-23
@@ -68,9 +68,9 @@ public class DescriptionGeneratorImplTest extends AndroidTestCase {
|
|||||||
+ "Average speed: 120.00 km/h (74.6 mi/h)<br>"
|
+ "Average speed: 120.00 km/h (74.6 mi/h)<br>"
|
||||||
+ "Average moving speed: 240.00 km/h (149.1 mi/h)<br>"
|
+ "Average moving speed: 240.00 km/h (149.1 mi/h)<br>"
|
||||||
+ "Max speed: 360.00 km/h (223.7 mi/h)<br>"
|
+ "Max speed: 360.00 km/h (223.7 mi/h)<br>"
|
||||||
+ "Average pace: 0.50 min/km (0.8 min/mi)<br>"
|
+ "Average pace: 0:30 min/km (0:48 min/mi)<br>"
|
||||||
+ "Average moving pace: 0.25 min/km (0.4 min/mi)<br>"
|
+ "Average moving pace: 0:15 min/km (0:24 min/mi)<br>"
|
||||||
+ "Fastest pace: 0.17 min/km (0.3 min/mi)<br>"
|
+ "Fastest pace: 0:10 min/km (0:16 min/mi)<br>"
|
||||||
+ "Max elevation: 550 m (1804 ft)<br>"
|
+ "Max elevation: 550 m (1804 ft)<br>"
|
||||||
+ "Min elevation: -500 m (-1640 ft)<br>"
|
+ "Min elevation: -500 m (-1640 ft)<br>"
|
||||||
+ "Elevation gain: 6000 m (19685 ft)<br>"
|
+ "Elevation gain: 6000 m (19685 ft)<br>"
|
||||||
@@ -103,9 +103,9 @@ public class DescriptionGeneratorImplTest extends AndroidTestCase {
|
|||||||
+ "Average speed: 120.00 km/h (74.6 mi/h)\n"
|
+ "Average speed: 120.00 km/h (74.6 mi/h)\n"
|
||||||
+ "Average moving speed: 240.00 km/h (149.1 mi/h)\n"
|
+ "Average moving speed: 240.00 km/h (149.1 mi/h)\n"
|
||||||
+ "Max speed: 360.00 km/h (223.7 mi/h)\n"
|
+ "Max speed: 360.00 km/h (223.7 mi/h)\n"
|
||||||
+ "Average pace: 0.50 min/km (0.8 min/mi)\n"
|
+ "Average pace: 0:30 min/km (0:48 min/mi)\n"
|
||||||
+ "Average moving pace: 0.25 min/km (0.4 min/mi)\n"
|
+ "Average moving pace: 0:15 min/km (0:24 min/mi)\n"
|
||||||
+ "Fastest pace: 0.17 min/km (0.3 min/mi)\n"
|
+ "Fastest pace: 0:10 min/km (0:16 min/mi)\n"
|
||||||
+ "Max elevation: 550 m (1804 ft)\n"
|
+ "Max elevation: 550 m (1804 ft)\n"
|
||||||
+ "Min elevation: -500 m (-1640 ft)\n"
|
+ "Min elevation: -500 m (-1640 ft)\n"
|
||||||
+ "Elevation gain: 6000 m (19685 ft)\n"
|
+ "Elevation gain: 6000 m (19685 ft)\n"
|
||||||
@@ -162,9 +162,8 @@ public class DescriptionGeneratorImplTest extends AndroidTestCase {
|
|||||||
*/
|
*/
|
||||||
public void testWritePace() {
|
public void testWritePace() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
descriptionGenerator.writePace(
|
descriptionGenerator.writePace(1.1, builder, R.string.description_average_pace, "\n");
|
||||||
new Pair<Double, Double>(1.1, 2.2), builder, R.string.description_average_pace, "\n");
|
assertEquals("Average pace: 15:09 min/km (24:23 min/mi)\n", builder.toString());
|
||||||
assertEquals("Average pace: 54.55 min/km (27.3 min/mi)\n", builder.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,18 +196,4 @@ public class DescriptionGeneratorImplTest extends AndroidTestCase {
|
|||||||
Double.POSITIVE_INFINITY, builder, R.string.description_max_grade, "<br>");
|
Double.POSITIVE_INFINITY, builder, R.string.description_max_grade, "<br>");
|
||||||
assertEquals("Max grade: 0 %<br>", builder.toString());
|
assertEquals("Max grade: 0 %<br>", builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link DescriptionGeneratorImpl#getPace(double)}.
|
|
||||||
*/
|
|
||||||
public void testGetPace() {
|
|
||||||
assertEquals(12.0, descriptionGenerator.getPace(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link DescriptionGeneratorImpl#getPace(double)} with zero speed.
|
|
||||||
*/
|
|
||||||
public void testGetPace_zero() {
|
|
||||||
assertEquals(0.0, descriptionGenerator.getPace(0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user