forked from upstream-mirrors/OpenTracks
Added cycling speed sensor.
Fixed speed and cadence computation. Fixed that a sensor change in settings resulted in a disconnect for all connected sensors.
This commit is contained in:
+26
-13
@@ -14,21 +14,21 @@ public class SensorDataCyclingTest {
|
|||||||
@Test
|
@Test
|
||||||
public void compute_cadence() {
|
public void compute_cadence() {
|
||||||
// given
|
// given
|
||||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence(1, 1024); // 1s
|
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024); // 1s
|
||||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence(2, 2048); // 2s
|
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 2048); // 2s
|
||||||
|
|
||||||
// when
|
// when
|
||||||
current.compute(previous);
|
current.compute(previous);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Assert.assertEquals(57.2519, current.getCadence_rpm(), 0.01);
|
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compute_cadence_sameCount() {
|
public void compute_cadence_sameCount() {
|
||||||
// given
|
// given
|
||||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence(1, 1024);
|
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024);
|
||||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence(1, 2048);
|
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 2048);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
current.compute(previous);
|
current.compute(previous);
|
||||||
@@ -41,8 +41,8 @@ public class SensorDataCyclingTest {
|
|||||||
@Test
|
@Test
|
||||||
public void compute_cadence_sameTime() {
|
public void compute_cadence_sameTime() {
|
||||||
// given
|
// given
|
||||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence(1, 1024);
|
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024);
|
||||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence(2, 1024);
|
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 1024);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
current.compute(previous);
|
current.compute(previous);
|
||||||
@@ -54,26 +54,39 @@ public class SensorDataCyclingTest {
|
|||||||
@Test
|
@Test
|
||||||
public void compute_cadence_rollOverTime() {
|
public void compute_cadence_rollOverTime() {
|
||||||
// given
|
// given
|
||||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence(1, UintUtils.UINT16_MAX - 1024);
|
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, UintUtils.UINT16_MAX - 1024);
|
||||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence(2, 0);
|
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
current.compute(previous);
|
current.compute(previous);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Assert.assertEquals(57.2519, current.getCadence_rpm(), 0.01);
|
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compute_cadence_rollOverCount() {
|
public void compute_cadence_rollOverCount() {
|
||||||
// given
|
// given
|
||||||
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence(UintUtils.UINT32_MAX - 1, 1024);
|
SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024);
|
||||||
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence(0, 2048);
|
SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 0, 2048);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
current.compute(previous);
|
current.compute(previous);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Assert.assertEquals(57.2519, current.getCadence_rpm(), 0.01);
|
Assert.assertEquals(60, current.getCadence_rpm(), 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compute_speed_rollOverCount() {
|
||||||
|
// given
|
||||||
|
SensorDataCycling.Speed previous = new SensorDataCycling.Speed("sensorAddress", "sensorName", UintUtils.UINT16_MAX - 1, 1024);
|
||||||
|
SensorDataCycling.Speed current = new SensorDataCycling.Speed("sensorAddress", "sensorName", 0, 2048);
|
||||||
|
|
||||||
|
// when
|
||||||
|
current.compute(previous, 2000);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Assert.assertEquals(2, current.getSpeed_mps(), 0.01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.util.UintUtils;
|
import de.dennisguse.opentracks.util.UintUtils;
|
||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
@@ -43,13 +42,6 @@ public final class SensorDataCycling {
|
|||||||
this(speed.getSensorAddress(), speed.getSensorName(), speed.getWheelRevolutionsCount(), speed.getWheelRevolutionsTime());
|
this(speed.getSensorAddress(), speed.getSensorName(), speed.getWheelRevolutionsCount(), speed.getWheelRevolutionsTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public Cadence(long crankRevolutionsCount, int crankRevolutionsTime) {
|
|
||||||
super("sensorAddress", "sensorName");
|
|
||||||
this.crankRevolutionsCount = crankRevolutionsCount;
|
|
||||||
this.crankRevolutionsTime = crankRevolutionsTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasData() {
|
public boolean hasData() {
|
||||||
return crankRevolutionsCount != INVALID_VALUE_INT && crankRevolutionsTime != INVALID_VALUE_INT;
|
return crankRevolutionsCount != INVALID_VALUE_INT && crankRevolutionsTime != INVALID_VALUE_INT;
|
||||||
}
|
}
|
||||||
@@ -72,8 +64,7 @@ public final class SensorDataCycling {
|
|||||||
|
|
||||||
public void compute(Cadence previous) {
|
public void compute(Cadence previous) {
|
||||||
if (hasData() && previous != null && previous.hasData()) {
|
if (hasData() && previous != null && previous.hasData()) {
|
||||||
Log.e(TAG, previous.getCrankRevolutionsTime() + " " + previous.getCrankRevolutionsCount() + " - " + this.getCrankRevolutionsTime() + " " + getCrankRevolutionsCount()); //TODO REMOVE
|
long timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024 * UnitConversions.S_TO_MS;
|
||||||
long timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) * 1024 / UnitConversions.S_TO_MS;
|
|
||||||
if (timeDiff_ms <= 0) {
|
if (timeDiff_ms <= 0) {
|
||||||
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
||||||
cadence_rpm = INVALID_VALUE_FLOAT;
|
cadence_rpm = INVALID_VALUE_FLOAT;
|
||||||
@@ -100,12 +91,11 @@ public final class SensorDataCycling {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Speed computation; needs wheel diameter / circumference
|
|
||||||
public static class Speed extends SensorData {
|
public static class Speed extends SensorData {
|
||||||
|
|
||||||
private int wheelRevolutionsCount; // UINT16
|
private int wheelRevolutionsCount; // UINT16
|
||||||
private int wheelRevolutionsTime; // UINT16; 1/1024s
|
private int wheelRevolutionsTime; // UINT16; 1/1024s
|
||||||
private float speed_ms = INVALID_VALUE_FLOAT;
|
private float speed_mps = INVALID_VALUE_FLOAT;
|
||||||
|
|
||||||
public Speed(String sensorAddress, String sensorName, int wheelRevolutionsCount, int wheelRevolutionsTime) {
|
public Speed(String sensorAddress, String sensorName, int wheelRevolutionsCount, int wheelRevolutionsTime) {
|
||||||
super(sensorAddress, sensorName);
|
super(sensorAddress, sensorName);
|
||||||
@@ -125,23 +115,24 @@ public final class SensorDataCycling {
|
|||||||
return wheelRevolutionsTime;
|
return wheelRevolutionsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSpeed() {
|
public boolean hasSpeed_mps() {
|
||||||
return !Float.isNaN(speed_ms);
|
return !Float.isNaN(speed_mps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getSpeed_ms() {
|
public float getSpeed_mps() {
|
||||||
return speed_ms;
|
return speed_mps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void compute(Speed previous) {
|
public void compute(Speed previous, int wheel_circumference_mm) {
|
||||||
if (hasData() && previous != null && previous.hasData()) {
|
if (hasData() && previous != null && previous.hasData()) {
|
||||||
long timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) * 1024 / UnitConversions.S_TO_MS;
|
long timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024 * UnitConversions.S_TO_MS;
|
||||||
if (timeDiff_ms <= 0) {
|
if (timeDiff_ms <= 0) {
|
||||||
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
||||||
speed_ms = INVALID_VALUE_FLOAT;
|
speed_mps = INVALID_VALUE_FLOAT;
|
||||||
} else {
|
} else {
|
||||||
long crankDiff = UintUtils.diff(wheelRevolutionsCount, previous.wheelRevolutionsCount, UintUtils.UINT32_MAX);
|
long wheelDiff = UintUtils.diff(wheelRevolutionsCount, previous.wheelRevolutionsCount, UintUtils.UINT16_MAX);
|
||||||
speed_ms = crankDiff / (float) timeDiff_ms;
|
double timeDiff_s = timeDiff_ms * UnitConversions.MS_TO_S;
|
||||||
|
speed_mps = (float) (wheelDiff * wheel_circumference_mm * UnitConversions.MM_TO_M / timeDiff_s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,7 +140,7 @@ public final class SensorDataCycling {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "speed=" + getSpeed_ms() + "_" + getWheelRevolutionsTime();
|
return "speed=" + getSpeed_mps() + "_" + getWheelRevolutionsTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ public final class SensorDataSet {
|
|||||||
trackPoint.setCyclingCadence_rpm(cyclingCadence.getCadence_rpm());
|
trackPoint.setCyclingCadence_rpm(cyclingCadence.getCadence_rpm());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cyclingSpeed != null && cyclingSpeed.hasSpeed()) {
|
if (cyclingSpeed != null && cyclingSpeed.hasSpeed_mps()) {
|
||||||
trackPoint.setSpeed(cyclingSpeed.getSpeed_ms());
|
trackPoint.setSpeed(cyclingSpeed.getSpeed_mps());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -449,10 +449,10 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
|
|
||||||
setHeartRateSensorData(sensorDataSet, isSelectedTrackRecording());
|
setHeartRateSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||||
setCadenceSensorData(sensorDataSet, isSelectedTrackRecording());
|
setCadenceSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||||
|
setSpeedSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setHeartRateSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
private void setHeartRateSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||||
// heart rate
|
|
||||||
int isVisible = View.VISIBLE;
|
int isVisible = View.VISIBLE;
|
||||||
if (!isRecording || PreferencesUtils.isBluetoothHeartRateSensorAddressNone(getContext())) {
|
if (!isRecording || PreferencesUtils.isBluetoothHeartRateSensorAddressNone(getContext())) {
|
||||||
isVisible = View.INVISIBLE;
|
isVisible = View.INVISIBLE;
|
||||||
@@ -475,7 +475,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setCadenceSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
private void setCadenceSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||||
// heart rate
|
|
||||||
int isVisible = View.VISIBLE;
|
int isVisible = View.VISIBLE;
|
||||||
if (!isRecording || PreferencesUtils.isBluetoothCyclingCadenceSensorAddressNone(getContext())) {
|
if (!isRecording || PreferencesUtils.isBluetoothCyclingCadenceSensorAddressNone(getContext())) {
|
||||||
isVisible = View.INVISIBLE;
|
isVisible = View.INVISIBLE;
|
||||||
@@ -497,6 +496,16 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setSpeedSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||||
|
if (isRecording) {
|
||||||
|
if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
|
||||||
|
if (sensorDataSet.getCyclingSpeed().hasSpeed_mps() && sensorDataSet.getCyclingSpeed().isRecent()) {
|
||||||
|
setSpeed(sensorDataSet.getCyclingSpeed().getSpeed_mps());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateStats() {
|
private void updateStats() {
|
||||||
String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
|
String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
|
||||||
|
|
||||||
@@ -600,12 +609,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
// Set speed/pace
|
// Set speed/pace
|
||||||
speedContainer.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
speedContainer.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
speedLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
|
||||||
|
|
||||||
double speed = lastTrackPoint != null && lastTrackPoint.hasSpeed() ? lastTrackPoint.getSpeed() : Double.NaN;
|
double speed = lastTrackPoint != null && lastTrackPoint.hasSpeed() ? lastTrackPoint.getSpeed() : Double.NaN;
|
||||||
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
setSpeed(speed);
|
||||||
speedValue.setText(parts.first);
|
|
||||||
speedUnit.setText(parts.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set elevation
|
// Set elevation
|
||||||
@@ -635,4 +640,15 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
longitudeValue.setText(longitudeText);
|
longitudeValue.setText(longitudeText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setSpeed(double speed) {
|
||||||
|
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||||
|
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext());
|
||||||
|
|
||||||
|
speedLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
||||||
|
|
||||||
|
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||||
|
speedValue.setText(parts.first);
|
||||||
|
speedUnit.setText(parts.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -56,8 +56,9 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
|
|||||||
|
|
||||||
private boolean started = false;
|
private boolean started = false;
|
||||||
|
|
||||||
private final BluetoothConnectionManager heartRate = new BluetoothConnectionManager.HeartRate(this);
|
private final BluetoothConnectionManager.HeartRate heartRate = new BluetoothConnectionManager.HeartRate(this);
|
||||||
private final BluetoothConnectionManager cyclingCadence = new BluetoothConnectionManager.CyclingCadence(this);
|
private final BluetoothConnectionManager.CyclingCadence cyclingCadence = new BluetoothConnectionManager.CyclingCadence(this);
|
||||||
|
private final BluetoothConnectionManager.CyclingSpeed cyclingSpeed = new BluetoothConnectionManager.CyclingSpeed(this);
|
||||||
|
|
||||||
private final SensorDataSet sensorDataSet = new SensorDataSet();
|
private final SensorDataSet sensorDataSet = new SensorDataSet();
|
||||||
|
|
||||||
@@ -67,23 +68,20 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
|
|||||||
if (!started) return;
|
if (!started) return;
|
||||||
|
|
||||||
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_heart_rate_key, key)) {
|
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_heart_rate_key, key)) {
|
||||||
if (PreferencesUtils.isBluetoothHeartRateSensorAddressNone(context)) {
|
|
||||||
stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String address = PreferencesUtils.getBluetoothHeartRateSensorAddress(context);
|
String address = PreferencesUtils.getBluetoothHeartRateSensorAddress(context);
|
||||||
connect(heartRate, address);
|
connect(heartRate, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) {
|
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) {
|
||||||
if (PreferencesUtils.isBluetoothCyclingCadenceSensorAddressNone(context)) {
|
|
||||||
stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String address = PreferencesUtils.getBluetoothCyclingCadenceSensorAddress(context);
|
String address = PreferencesUtils.getBluetoothCyclingCadenceSensorAddress(context);
|
||||||
|
|
||||||
connect(cyclingCadence, address);
|
connect(cyclingCadence, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) {
|
||||||
|
String address = PreferencesUtils.getBluetoothCyclingSpeedSensorAddress(context);
|
||||||
|
|
||||||
|
connect(cyclingSpeed, address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,7 +161,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
|
|||||||
Log.d(TAG, "onChanged: speed data repeated.");
|
Log.d(TAG, "onChanged: speed data repeated.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
((SensorDataCycling.Speed) sensorData).compute(sensorDataSet.getCyclingSpeed());
|
((SensorDataCycling.Speed) sensorData).compute(sensorDataSet.getCyclingSpeed(), PreferencesUtils.getWheelCircumference(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
sensorDataSet.set(sensorData);
|
sensorDataSet.set(sensorData);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class PreferencesUtils {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
//NOTE: is at the moment still used to determine if a track is currently recorded; better ask the service directly.
|
//NOTE: is at the moment still used to determine if a track is currently recorded; better ask the service directly.
|
||||||
//NOTE: This was also used to recover from a reboot, but this data should not be exposed to the whole application.
|
//NOTE: This was also used to recover from a service restart, but this data should not be exposed to the whole application.
|
||||||
public static final long RECORDING_TRACK_ID_DEFAULT = -1L;
|
public static final long RECORDING_TRACK_ID_DEFAULT = -1L;
|
||||||
|
|
||||||
public static long getRecordingTrackId(Context context) {
|
public static long getRecordingTrackId(Context context) {
|
||||||
@@ -250,6 +250,10 @@ public class PreferencesUtils {
|
|||||||
return getString(context, R.string.settings_sensor_bluetooth_cycling_speed_key, getBluetoothSensorAddressNone(context));
|
return getString(context, R.string.settings_sensor_bluetooth_cycling_speed_key, getBluetoothSensorAddressNone(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getWheelCircumference(Context context) {
|
||||||
|
final int DEFAULT = Integer.parseInt(context.getResources().getString(R.string.settings_sensor_bluetooth_cycling_speed_wheel_circumference_default));
|
||||||
|
return getInt(context, R.string.settings_sensor_bluetooth_cycling_speed_wheel_circumference_key, DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean shouldShowStatsOnLockscreen(Context context) {
|
public static boolean shouldShowStatsOnLockscreen(Context context) {
|
||||||
final boolean STATS_SHOW_ON_LOCKSCREEN_DEFAULT = context.getResources().getBoolean(R.bool.stats_show_on_lockscreen_while_recording_default);
|
final boolean STATS_SHOW_ON_LOCKSCREEN_DEFAULT = context.getResources().getBoolean(R.bool.stats_show_on_lockscreen_while_recording_default);
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public class UnitConversions {
|
|||||||
// multiplication factor to convert kilometers to miles
|
// multiplication factor to convert kilometers to miles
|
||||||
public static final double KM_TO_MI = 0.621371192;
|
public static final double KM_TO_MI = 0.621371192;
|
||||||
|
|
||||||
|
public static final double MM_TO_M = 0.001;
|
||||||
|
|
||||||
// Distance
|
// Distance
|
||||||
// multiplication factor to convert miles to feet
|
// multiplication factor to convert miles to feet
|
||||||
public static final double MI_TO_FT = 5280.0;
|
public static final double MI_TO_FT = 5280.0;
|
||||||
|
|||||||
@@ -20,6 +20,21 @@
|
|||||||
<string name="settings_sensor_bluetooth_cycling_speed_key" translatable="false">bluetoothCyclingSpeedSensor</string>
|
<string name="settings_sensor_bluetooth_cycling_speed_key" translatable="false">bluetoothCyclingSpeedSensor</string>
|
||||||
<string name="sensor_type_value_none" translatable="false">NONE</string>
|
<string name="sensor_type_value_none" translatable="false">NONE</string>
|
||||||
|
|
||||||
|
<string name="settings_sensor_bluetooth_cycling_speed_wheel_circumference_key" translatable="false">bluetoothCyclingSpeedWheelCircumference</string>
|
||||||
|
<string name="settings_sensor_bluetooth_cycling_speed_wheel_circumference_default" translatable="false">2135</string>
|
||||||
|
<string-array name="wheel_circumference_values">
|
||||||
|
<item>2100</item>
|
||||||
|
<item>2125</item>
|
||||||
|
<item>@string/settings_sensor_bluetooth_cycling_speed_wheel_circumference_default</item>
|
||||||
|
<item>2150</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="wheel_circumference_options">
|
||||||
|
<item>20-622</item>
|
||||||
|
<item>23-622</item>
|
||||||
|
<item>25-622</item>
|
||||||
|
<item>28-622</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string name="default_activity_key" translatable="false">defaultActivity</string>
|
<string name="default_activity_key" translatable="false">defaultActivity</string>
|
||||||
<string name="default_activity_default" translatable="false">@string/activity_type_unknown</string>
|
<string name="default_activity_default" translatable="false">@string/activity_type_unknown</string>
|
||||||
<string-array name="activity_types">
|
<string-array name="activity_types">
|
||||||
|
|||||||
@@ -397,6 +397,9 @@ limitations under the License.
|
|||||||
<string name="settings_sensor_connecting">Connected to %1$s</string>
|
<string name="settings_sensor_connecting">Connected to %1$s</string>
|
||||||
<string name="settings_sensor_connected">Connected to %1$s</string>
|
<string name="settings_sensor_connected">Connected to %1$s</string>
|
||||||
<string name="settings_sensor_disconnected">Disconnected from %1$s</string>
|
<string name="settings_sensor_disconnected">Disconnected from %1$s</string>
|
||||||
|
|
||||||
|
<string name="settings_sensor_wheel_circumference">Wheel size (ETRTO)</string>
|
||||||
|
|
||||||
<!-- Settings Stats -->
|
<!-- Settings Stats -->
|
||||||
<string name="settings_stats_coordinate">Latitude/Longitude</string>
|
<string name="settings_stats_coordinate">Latitude/Longitude</string>
|
||||||
<string name="settings_stats_rate_title">Preferred rate</string>
|
<string name="settings_stats_rate_title">Preferred rate</string>
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ limitations under the License.
|
|||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/settings_recording"
|
|
||||||
android:key="@string/settings_recording_key"
|
android:key="@string/settings_recording_key"
|
||||||
|
android:title="@string/settings_recording"
|
||||||
app:initialExpandedChildrenCount="4">
|
app:initialExpandedChildrenCount="4">
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="@bool/stats_show_on_lockscreen_while_recording_default"
|
android:defaultValue="@bool/stats_show_on_lockscreen_while_recording_default"
|
||||||
@@ -119,10 +119,17 @@ limitations under the License.
|
|||||||
android:defaultValue="@string/sensor_type_value_none"
|
android:defaultValue="@string/sensor_type_value_none"
|
||||||
android:key="@string/settings_sensor_bluetooth_cycling_cadence_key"
|
android:key="@string/settings_sensor_bluetooth_cycling_cadence_key"
|
||||||
android:title="@string/sensor_state_cadence" />
|
android:title="@string/sensor_state_cadence" />
|
||||||
<!-- <de.dennisguse.opentracks.settings.bluetooth.BluetoothLeCyclingCadenceAndSpeedPreference-->
|
<de.dennisguse.opentracks.settings.bluetooth.BluetoothLeCyclingCadenceAndSpeedPreference
|
||||||
<!-- android:defaultValue="@string/sensor_type_value_none"-->
|
android:defaultValue="@string/sensor_type_value_none"
|
||||||
<!-- android:key="@string/settings_sensor_bluetooth_cycling_speed_key"-->
|
android:key="@string/settings_sensor_bluetooth_cycling_speed_key"
|
||||||
<!-- android:title="@string/stats_speed" />-->
|
android:title="@string/stats_speed" />
|
||||||
|
<ListPreference
|
||||||
|
android:defaultValue="@string/settings_sensor_bluetooth_cycling_speed_wheel_circumference_default"
|
||||||
|
android:entries="@array/wheel_circumference_options"
|
||||||
|
android:entryValues="@array/wheel_circumference_values"
|
||||||
|
android:key="settings_sensor_bluetooth_cycling_speed_wheel_circumference_key"
|
||||||
|
android:title="@string/settings_sensor_wheel_circumference"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/generic_tracks">
|
<PreferenceCategory android:title="@string/generic_tracks">
|
||||||
|
|||||||
Reference in New Issue
Block a user