forked from upstream-mirrors/OpenTracks
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 397e056f6f | |||
| eb79f2277a | |||
| ae8833d21b | |||
| e8017a4e9d | |||
| cea180f871 | |||
| be1b6ece9d | |||
| 0592863d3c | |||
| 18bc100d5a | |||
| 4476a15558 | |||
| 215c28be85 | |||
| a429fbe4df | |||
| 6b470c7fdc | |||
| 6b690f38ad | |||
| f138826d60 | |||
| 14ac29095d | |||
| a3f4de7d18 | |||
| 6392e88dc7 | |||
| 1e913d6bb5 | |||
| ced8454f59 | |||
| 974a5afeb1 | |||
| 9c9bdde6b9 | |||
| ca2bc6426c | |||
| 81097aac40 | |||
| a74b5fc743 |
@@ -9,6 +9,7 @@
|
|||||||
* Polar OH1
|
* Polar OH1
|
||||||
Has updatable firmware that requires a user account at polar.com
|
Has updatable firmware that requires a user account at polar.com
|
||||||
* Wahoo Tickr (Model: WFBTHR02)
|
* Wahoo Tickr (Model: WFBTHR02)
|
||||||
|
* Mi Band 3, Amazfit Band 5, Amazfit Bip. These devices are manufactured by Huami, and other Huami devices will very likely work. Theoretically, this sensor must be enabled, but testing reveals that it works even without enabling. For details on how to enable see [Gadgetbridge wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Huami-Heartrate-measurement#bluetooth-heart-rate-sensor)
|
||||||
|
|
||||||
## CSCP: Cycling Cadence and Speed Service
|
## CSCP: Cycling Cadence and Speed Service
|
||||||
|
|
||||||
@@ -40,3 +41,4 @@ Also the distance is not computed.
|
|||||||
* QUARQ Red DZero Powermeter
|
* QUARQ Red DZero Powermeter
|
||||||
* Tacx Satori Smart
|
* Tacx Satori Smart
|
||||||
* Wahoo Kickr v4.0
|
* Wahoo Kickr v4.0
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ cp "$CHANGELOG_DIR/next_release.txt" "$CHANGELOG_FILE"
|
|||||||
sed -i "s/(versionName)/$VERSIONNAME/" "$CHANGELOG_FILE"
|
sed -i "s/(versionName)/$VERSIONNAME/" "$CHANGELOG_FILE"
|
||||||
|
|
||||||
echo -e "\nGit commit since last release\n------------"
|
echo -e "\nGit commit since last release\n------------"
|
||||||
git log $(git describe --tags --abbrev=0)..HEAD --no-merges --oneline
|
git log "$(git describe --tags --abbrev=0)..HEAD" --no-merges --oneline
|
||||||
|
|
||||||
echo -e "\nPlease edit the changelog for the new release"
|
echo -e "\nPlease edit the changelog for the new release"
|
||||||
gedit -w "$CHANGELOG_FILE"
|
gedit -w "$CHANGELOG_FILE"
|
||||||
|
|||||||
+3
-3
@@ -51,8 +51,8 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "de.dennisguse.opentracks"
|
applicationId "de.dennisguse.opentracks"
|
||||||
versionCode 3737
|
versionCode 3761
|
||||||
versionName "v3.13.1"
|
versionName "v3.14.0"
|
||||||
|
|
||||||
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
||||||
|
|
||||||
@@ -98,5 +98,5 @@ dependencies {
|
|||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||||
androidTestImplementation 'androidx.test:rules:1.3.0'
|
androidTestImplementation 'androidx.test:rules:1.3.0'
|
||||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||||
androidTestImplementation 'org.mockito:mockito-android:3.6.0'
|
androidTestImplementation 'org.mockito:mockito-android:3.6.28'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
v3.13.2: OpenTracks
|
||||||
|
|
||||||
|
Bugfix:
|
||||||
|
- Crash in landscape mode
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
v3.14.0: OpenTracks
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Properly support for right-to-left
|
||||||
|
- Import: faster cleanup after import failure
|
||||||
|
- Text in charts scales according to Android settings
|
||||||
|
- Heart rate: support for Huami devices (requires Gadgetbridge)
|
||||||
|
|
||||||
|
Developer:
|
||||||
|
- Import is now handled in-memory
|
||||||
@@ -48,7 +48,9 @@ public class ChartValueSeriesTest {
|
|||||||
R.string.description_elevation_metric,
|
R.string.description_elevation_metric,
|
||||||
R.string.description_elevation_imperial,
|
R.string.description_elevation_imperial,
|
||||||
R.color.chart_elevation_fill,
|
R.color.chart_elevation_fill,
|
||||||
R.color.chart_elevation_border) {
|
R.color.chart_elevation_border,
|
||||||
|
15,
|
||||||
|
18) {
|
||||||
@Override
|
@Override
|
||||||
double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getElevation();
|
return chartPoint.getElevation();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import androidx.test.filters.LargeTest;
|
|||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
@@ -196,6 +197,7 @@ public class ExportImportTest {
|
|||||||
assertNull(importedTrack);
|
assertNull(importedTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@Test
|
@Test
|
||||||
public void kmz_only_track() {
|
public void kmz_only_track() {
|
||||||
@@ -203,6 +205,7 @@ public class ExportImportTest {
|
|||||||
Log.e(TAG, "Test not implemented.");
|
Log.e(TAG, "Test not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@Test
|
@Test
|
||||||
public void kmz_with_trackdetail() {
|
public void kmz_with_trackdetail() {
|
||||||
@@ -210,6 +213,7 @@ public class ExportImportTest {
|
|||||||
Log.e(TAG, "Test not implemented.");
|
Log.e(TAG, "Test not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@Test
|
@Test
|
||||||
public void kmz_with_trackdetail_and_sensordata() {
|
public void kmz_with_trackdetail_and_sensordata() {
|
||||||
@@ -217,6 +221,7 @@ public class ExportImportTest {
|
|||||||
Log.e(TAG, "Test not implemented.");
|
Log.e(TAG, "Test not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@Test
|
@Test
|
||||||
public void kmz_with_trackdetail_and_sensordata_and_pictures() {
|
public void kmz_with_trackdetail_and_sensordata_and_pictures() {
|
||||||
|
|||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
package de.dennisguse.opentracks.io.file.importer;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
import androidx.test.filters.LargeTest;
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
|
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||||
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports a legacy kml file with a statistics marker at the beginning
|
||||||
|
*/
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class LegacyKmlImportTest {
|
||||||
|
|
||||||
|
private final Context context = ApplicationProvider.getApplicationContext();
|
||||||
|
private final ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||||
|
|
||||||
|
private Track.Id importTrackId;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
if (importTrackId != null) {
|
||||||
|
contentProviderUtils.deleteTrack(context, importTrackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@LargeTest
|
||||||
|
@Test
|
||||||
|
public void kml_legacy_track_import() {
|
||||||
|
// given
|
||||||
|
KmlFileTrackImporter trackImporter = new KmlFileTrackImporter(context);
|
||||||
|
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_track);
|
||||||
|
|
||||||
|
// when
|
||||||
|
// 1. import
|
||||||
|
importTrackId = trackImporter.importFile(inputStream);
|
||||||
|
|
||||||
|
// then
|
||||||
|
// 1. track
|
||||||
|
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||||
|
assertNotNull(importedTrack);
|
||||||
|
assertEquals("unknown", importedTrack.getCategory());
|
||||||
|
assertEquals("Test Track", importedTrack.getDescription());
|
||||||
|
assertEquals("2020-11-28 18:06", importedTrack.getName());
|
||||||
|
assertEquals("UNKNOWN", importedTrack.getIcon());
|
||||||
|
|
||||||
|
// 2. markers
|
||||||
|
assertEquals(0, contentProviderUtils.getMarkerCount(importTrackId));
|
||||||
|
|
||||||
|
// 3. trackpoints
|
||||||
|
List<TrackPoint> importedTrackPoints = contentProviderUtils.getTrackPoints(importTrackId);
|
||||||
|
assertEquals(8, importedTrackPoints.size()); // 6 trackpoints + pause and resume
|
||||||
|
|
||||||
|
// first 3 trackpoints
|
||||||
|
assertTrackpoint(importedTrackPoints.get(0), "2020-11-28T17:06:22.401Z", 1.234156, 12.340097, 469.286376953125);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(1), "2020-11-28T17:06:25.448Z", 1.23415, 12.340036, 439.1626281738281);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(2), "2020-11-28T17:06:47.888Z", 1.23405, 12.340057, 421.8070983886719);
|
||||||
|
|
||||||
|
// created pause trackpoint with time of previous valid trackpoint
|
||||||
|
assertTrackpoint(importedTrackPoints.get(3), "2020-11-28T17:06:47.888Z", 0.0, 100, 0.0);
|
||||||
|
// created resume trackpoint with time of next valid trackpoint
|
||||||
|
assertTrackpoint(importedTrackPoints.get(4), "2020-11-28T17:06:55.861Z", 0.0, 200, 0.0);
|
||||||
|
|
||||||
|
// last 3 trackpoints
|
||||||
|
assertTrackpoint(importedTrackPoints.get(5), "2020-11-28T17:06:55.861Z", 1.23405, 12.340057, 419.93902587890625);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(6), "2020-11-28T17:06:56.905Z", 1.23405, 12.340057, 419.9036560058594);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(7), "2020-11-28T17:07:20.870Z", 1.234046, 12.340082, 417.99432373046875);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertTrackpoint(final TrackPoint trackPoint, final String when, final double longitude, final double latitude, final double altitude) {
|
||||||
|
assertEquals(StringUtils.parseTime(when), trackPoint.getTime());
|
||||||
|
assertEquals(latitude, trackPoint.getLatitude(), 0.001d);
|
||||||
|
assertEquals(longitude, trackPoint.getLongitude(), 0.001d);
|
||||||
|
assertEquals(altitude, trackPoint.getAltitude(), 0.001d);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -9,7 +9,7 @@ import org.junit.Test;
|
|||||||
*/
|
*/
|
||||||
public class ElevationSumManagerTest {
|
public class ElevationSumManagerTest {
|
||||||
|
|
||||||
private ElevationSumManager elevationSumManager = new ElevationSumManager();
|
private final ElevationSumManager elevationSumManager = new ElevationSumManager();
|
||||||
|
|
||||||
private static void addSensorValue(ElevationSumManager elevationSumManager, float[] values) {
|
private static void addSensorValue(ElevationSumManager elevationSumManager, float[] values) {
|
||||||
for (float f : values) {
|
for (float f : values) {
|
||||||
|
|||||||
@@ -226,4 +226,13 @@ public class StringUtilsTest {
|
|||||||
assertEquals("min/km", StringUtils.getSpeedParts(context, 0, true, false).second);
|
assertEquals("min/km", StringUtils.getSpeedParts(context, 0, true, false).second);
|
||||||
assertEquals("min/mi", StringUtils.getSpeedParts(context, 0, false, false).second);
|
assertEquals("min/mi", StringUtils.getSpeedParts(context, 0, false, false).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormatSpeed() {
|
||||||
|
assertEquals("4:59 min/km", StringUtils.formatSpeed(context, 3.34, true, false));
|
||||||
|
assertEquals("8:02 min/mi", StringUtils.formatSpeed(context, 3.34, false, false));
|
||||||
|
|
||||||
|
assertEquals("12.02 km/h", StringUtils.formatSpeed(context, 3.34, true, true));
|
||||||
|
assertEquals("7.47 mph", StringUtils.formatSpeed(context, 3.34, false, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<kml xmlns="http://www.opengis.net/kml/2.2"
|
||||||
|
xmlns:gx="http://www.google.com/kml/ext/2.2"
|
||||||
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
|
xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1">
|
||||||
|
<Document>
|
||||||
|
<open>1</open>
|
||||||
|
<visibility>1</visibility>
|
||||||
|
<name><![CDATA[2020-11-28 18:06]]></name>
|
||||||
|
<atom:generator><![CDATA[OpenTracks (Debug)]]></atom:generator>
|
||||||
|
<Style id="track">
|
||||||
|
<LineStyle><color>7f0000ff</color><width>4</width></LineStyle>
|
||||||
|
<IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon><href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href></Icon>
|
||||||
|
</IconStyle>
|
||||||
|
</Style>
|
||||||
|
<Style id="start"><IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon><href>http://maps.google.com/mapfiles/kml/paddle/grn-circle.png</href></Icon>
|
||||||
|
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
|
||||||
|
</IconStyle></Style>
|
||||||
|
<Style id="end"><IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon><href>http://maps.google.com/mapfiles/kml/paddle/red-circle.png</href></Icon>
|
||||||
|
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
|
||||||
|
</IconStyle></Style>
|
||||||
|
<Style id="waypoint"><IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon><href>http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png</href></Icon>
|
||||||
|
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
|
||||||
|
</IconStyle></Style>
|
||||||
|
<Schema id="schema">
|
||||||
|
<gx:SimpleArrayField name="speed" type="float">
|
||||||
|
<displayName><![CDATA[Speed (m/s)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
<gx:SimpleArrayField name="power" type="float">
|
||||||
|
<displayName><![CDATA[Power (W)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
<gx:SimpleArrayField name="cadence" type="float">
|
||||||
|
<displayName><![CDATA[Cadence (rpm)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
<gx:SimpleArrayField name="heart_rate" type="float">
|
||||||
|
<displayName><![CDATA[Heart rate (bpm)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
</Schema>
|
||||||
|
<Folder>
|
||||||
|
<name><![CDATA[Sun, 28 Nov 2020 18:06 Markers]]></name>
|
||||||
|
<open>1</open>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[Split 0]]></name>
|
||||||
|
<description><![CDATA[Total distance: 0.00 km (0.0 mi)
|
||||||
|
Total time: 00:00
|
||||||
|
Moving time: 00:00
|
||||||
|
Average speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Average moving speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Max speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Average pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Average moving pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Fastest pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Max elevation: -9223372036854775808 m (-9223372036854775808 ft)
|
||||||
|
Min elevation: 9223372036854775807 m (9223372036854775807 ft)
|
||||||
|
Elevation gain: 0 m (0 ft)
|
||||||
|
Max grade: 0 %
|
||||||
|
Min grade: 0 %
|
||||||
|
Recorded: 6/23 11:29
|
||||||
|
]]></description>
|
||||||
|
<TimeStamp><when>1970-01-01T00:00:00Z</when></TimeStamp>
|
||||||
|
<styleUrl>#waypoint</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>180.0,100.0</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
</Folder>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[2020-11-28 18:06 (Start)]]></name>
|
||||||
|
<description><![CDATA[]]></description>
|
||||||
|
<TimeStamp><when>2020-11-28T17:06:22.401Z</when></TimeStamp>
|
||||||
|
<styleUrl>#start</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>1.234156,12.340097,469.286376953125</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[2020-11-28 18:06]]></name>
|
||||||
|
<description><![CDATA[Test Track]]></description>
|
||||||
|
<icon><![CDATA[UNKNOWN]]></icon>
|
||||||
|
<opentracks:trackid>2f170875-55d7-445d-b2b8-22a573c81dbc</opentracks:trackid>
|
||||||
|
<styleUrl>#track</styleUrl>
|
||||||
|
<ExtendedData>
|
||||||
|
<Data name="type"><value><![CDATA[unknown]]></value></Data>
|
||||||
|
</ExtendedData>
|
||||||
|
<gx:MultiTrack>
|
||||||
|
<altitudeMode>absolute</altitudeMode>
|
||||||
|
<gx:interpolate>1</gx:interpolate>
|
||||||
|
<gx:Track>
|
||||||
|
<when>2020-11-28T17:06:22.401Z</when>
|
||||||
|
<gx:coord>1.234156 12.340097 469.286376953125</gx:coord>
|
||||||
|
<when>2020-11-28T17:06:25.448Z</when>
|
||||||
|
<gx:coord>1.23415 12.340036 439.1626281738281</gx:coord>
|
||||||
|
<when>2020-11-28T17:06:47.888Z</when>
|
||||||
|
<gx:coord>1.23405 12.340057 421.8070983886719</gx:coord>
|
||||||
|
<ExtendedData>
|
||||||
|
<SchemaData schemaUrl="#schema">
|
||||||
|
<gx:SimpleArrayData name="speed">
|
||||||
|
<gx:value>0.5391469</gx:value>
|
||||||
|
<gx:value>0.15777911</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
<gx:SimpleArrayData name="elevation_gain">
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
</SchemaData>
|
||||||
|
</ExtendedData>
|
||||||
|
</gx:Track>
|
||||||
|
<gx:Track>
|
||||||
|
<when>2020-11-28T17:06:55.861Z</when>
|
||||||
|
<gx:coord>1.23405 12.340057 419.93902587890625</gx:coord>
|
||||||
|
<when>2020-11-28T17:06:56.905Z</when>
|
||||||
|
<gx:coord>1.23405 12.340057 419.9036560058594</gx:coord>
|
||||||
|
<when>2020-11-28T17:07:20.870Z</when>
|
||||||
|
<gx:coord>1.234046 12.340082 417.99432373046875</gx:coord>
|
||||||
|
<ExtendedData>
|
||||||
|
<SchemaData schemaUrl="#schema">
|
||||||
|
<gx:SimpleArrayData name="speed">
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
<gx:SimpleArrayData name="elevation_gain">
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
</SchemaData>
|
||||||
|
</ExtendedData>
|
||||||
|
</gx:Track>
|
||||||
|
</gx:MultiTrack>
|
||||||
|
</Placemark>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[2020-11-28 18:06 (End)]]></name>
|
||||||
|
<description><![CDATA[OpenTracks (Debug)
|
||||||
|
|
||||||
|
Name: 2020-11-28 18:06
|
||||||
|
Activity type: unknown
|
||||||
|
Description: -
|
||||||
|
Total distance: 0.01 km (0.0 mi)
|
||||||
|
Total time: 01:04
|
||||||
|
Moving time: 00:00
|
||||||
|
Average speed: 0.49 km/h (0.3 mi/h)
|
||||||
|
Average moving speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Max speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Average pace: 122:30 min/km (197:08 min/mi)
|
||||||
|
Average moving pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Fastest pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Max elevation: 469 m (1540 ft)
|
||||||
|
Min elevation: 419 m (1376 ft)
|
||||||
|
Elevation gain: 0 m (0 ft)
|
||||||
|
Recorded: 11/28 18:06
|
||||||
|
]]></description>
|
||||||
|
<TimeStamp><when>2020-11-28T17:07:20.870Z</when></TimeStamp>
|
||||||
|
<styleUrl>#end</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>1.234046,12.340082,417.99432373046875</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
</Document>
|
||||||
|
</kml>
|
||||||
@@ -50,10 +50,11 @@ limitations under the License.
|
|||||||
<application
|
<application
|
||||||
android:name=".Startup"
|
android:name=".Startup"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:hasFragileUserData="true"
|
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
|
android:hasFragileUserData="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
android:theme="@style/ThemeCustom">
|
android:theme="@style/ThemeCustom">
|
||||||
|
|
||||||
<activity android:name=".AboutActivity" />
|
<activity android:name=".AboutActivity" />
|
||||||
@@ -71,14 +72,14 @@ limitations under the License.
|
|||||||
<activity android:name=".io.file.importer.ImportActivity">
|
<activity android:name=".io.file.importer.ImportActivity">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND"/>
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="application/gpx+xml"/>
|
<data android:mimeType="application/gpx+xml" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND"/>
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="application/gpx"/>
|
<data android:mimeType="application/gpx" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter
|
<intent-filter
|
||||||
@@ -86,13 +87,15 @@ limitations under the License.
|
|||||||
android:priority="50">
|
android:priority="50">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="file"/>
|
|
||||||
<data android:scheme="content"/>
|
<data android:scheme="file" />
|
||||||
<data android:scheme="data"/>
|
<data android:scheme="content" />
|
||||||
<data android:host="*"/>
|
<data android:scheme="data" />
|
||||||
<data android:mimeType="*/*"/>
|
<data android:host="*" />
|
||||||
|
<data android:mimeType="*/*" />
|
||||||
<data android:pathPattern=".*\\.gpx" />
|
<data android:pathPattern=".*\\.gpx" />
|
||||||
<data android:pathPattern=".*\\..*\\.gpx" />
|
<data android:pathPattern=".*\\..*\\.gpx" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\.gpx" />
|
<data android:pathPattern=".*\\..*\\..*\\.gpx" />
|
||||||
@@ -110,12 +113,14 @@ limitations under the License.
|
|||||||
android:priority="50">
|
android:priority="50">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="file"/>
|
|
||||||
<data android:scheme="content"/>
|
<data android:scheme="file" />
|
||||||
<data android:scheme="data"/>
|
<data android:scheme="content" />
|
||||||
<data android:host="*"/>
|
<data android:scheme="data" />
|
||||||
|
<data android:host="*" />
|
||||||
<data android:pathPattern=".*\\.gpx" />
|
<data android:pathPattern=".*\\.gpx" />
|
||||||
<data android:pathPattern=".*\\..*\\.gpx" />
|
<data android:pathPattern=".*\\..*\\.gpx" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\.gpx" />
|
<data android:pathPattern=".*\\..*\\..*\\.gpx" />
|
||||||
@@ -129,9 +134,9 @@ limitations under the License.
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND"/>
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="application/vnd.google-earth.kmz"/>
|
<data android:mimeType="application/vnd.google-earth.kmz" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter
|
<intent-filter
|
||||||
@@ -139,13 +144,15 @@ limitations under the License.
|
|||||||
android:priority="50">
|
android:priority="50">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="file"/>
|
|
||||||
<data android:scheme="content"/>
|
<data android:scheme="file" />
|
||||||
<data android:scheme="data"/>
|
<data android:scheme="content" />
|
||||||
<data android:host="*"/>
|
<data android:scheme="data" />
|
||||||
<data android:mimeType="*/*"/>
|
<data android:host="*" />
|
||||||
|
<data android:mimeType="*/*" />
|
||||||
<data android:pathPattern=".*\\.kmz" />
|
<data android:pathPattern=".*\\.kmz" />
|
||||||
<data android:pathPattern=".*\\..*\\.kmz" />
|
<data android:pathPattern=".*\\..*\\.kmz" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\.kmz" />
|
<data android:pathPattern=".*\\..*\\..*\\.kmz" />
|
||||||
@@ -163,12 +170,14 @@ limitations under the License.
|
|||||||
android:priority="50">
|
android:priority="50">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="file"/>
|
|
||||||
<data android:scheme="content"/>
|
<data android:scheme="file" />
|
||||||
<data android:scheme="data"/>
|
<data android:scheme="content" />
|
||||||
<data android:host="*"/>
|
<data android:scheme="data" />
|
||||||
|
<data android:host="*" />
|
||||||
<data android:pathPattern=".*\\.kmz" />
|
<data android:pathPattern=".*\\.kmz" />
|
||||||
<data android:pathPattern=".*\\..*\\.kmz" />
|
<data android:pathPattern=".*\\..*\\.kmz" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\.kmz" />
|
<data android:pathPattern=".*\\..*\\..*\\.kmz" />
|
||||||
@@ -182,9 +191,9 @@ limitations under the License.
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND"/>
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="application/vnd.google-earth.kml+xml"/>
|
<data android:mimeType="application/vnd.google-earth.kml+xml" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter
|
<intent-filter
|
||||||
@@ -192,13 +201,15 @@ limitations under the License.
|
|||||||
android:priority="50">
|
android:priority="50">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="file"/>
|
|
||||||
<data android:scheme="content"/>
|
<data android:scheme="file" />
|
||||||
<data android:scheme="data"/>
|
<data android:scheme="content" />
|
||||||
<data android:host="*"/>
|
<data android:scheme="data" />
|
||||||
<data android:mimeType="*/*"/>
|
<data android:host="*" />
|
||||||
|
<data android:mimeType="*/*" />
|
||||||
<data android:pathPattern=".*\\.kml" />
|
<data android:pathPattern=".*\\.kml" />
|
||||||
<data android:pathPattern=".*\\..*\\.kml" />
|
<data android:pathPattern=".*\\..*\\.kml" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\.kml" />
|
<data android:pathPattern=".*\\..*\\..*\\.kml" />
|
||||||
@@ -216,12 +227,14 @@ limitations under the License.
|
|||||||
android:priority="50">
|
android:priority="50">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data android:scheme="file"/>
|
|
||||||
<data android:scheme="content"/>
|
<data android:scheme="file" />
|
||||||
<data android:scheme="data"/>
|
<data android:scheme="content" />
|
||||||
<data android:host="*"/>
|
<data android:scheme="data" />
|
||||||
|
<data android:host="*" />
|
||||||
<data android:pathPattern=".*\\.kml" />
|
<data android:pathPattern=".*\\.kml" />
|
||||||
<data android:pathPattern=".*\\..*\\.kml" />
|
<data android:pathPattern=".*\\..*\\.kml" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\.kml" />
|
<data android:pathPattern=".*\\..*\\..*\\.kml" />
|
||||||
@@ -237,7 +250,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<activity android:name=".MarkerDetailActivity">
|
<activity android:name=".MarkerDetailActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="de.dennisguse.opentracks.MarkerDetails"/>
|
<action android:name="de.dennisguse.opentracks.MarkerDetails" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
@@ -258,8 +271,8 @@ limitations under the License.
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".TrackListActivity"
|
android:name=".TrackListActivity"
|
||||||
android:theme="@style/SplashTheme"
|
android:launchMode="singleTop"
|
||||||
android:launchMode="singleTop">
|
android:theme="@style/SplashTheme">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class MarkerEditActivity extends AbstractActivity {
|
|||||||
|
|
||||||
private Uri photoUri;
|
private Uri photoUri;
|
||||||
private Uri photoUriOriginal;
|
private Uri photoUriOriginal;
|
||||||
private List<Uri> photoUriDeleteList = new ArrayList<>();
|
private final List<Uri> photoUriDeleteList = new ArrayList<>();
|
||||||
private boolean hasCamera;
|
private boolean hasCamera;
|
||||||
|
|
||||||
private boolean isNewMarker;
|
private boolean isNewMarker;
|
||||||
|
|||||||
@@ -95,9 +95,7 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
|
|||||||
}
|
}
|
||||||
|
|
||||||
setActivityTypeIcon(iconValue);
|
setActivityTypeIcon(iconValue);
|
||||||
viewBinding.trackEditActivityTypeIcon.setOnClickListener(v -> {
|
viewBinding.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.trackEditActivityType.getText().toString()));
|
||||||
ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.trackEditActivityType.getText().toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
viewBinding.trackEditDescription.setText(track.getDescription());
|
viewBinding.trackEditDescription.setText(track.getDescription());
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,14 @@ import android.util.Log;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewParent;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||||
import de.dennisguse.opentracks.content.data.Marker;
|
import de.dennisguse.opentracks.content.data.Marker;
|
||||||
@@ -75,8 +78,10 @@ public class TrackRecordedActivity extends AbstractListActivity implements Confi
|
|||||||
|
|
||||||
trackDataHub = new TrackDataHub(this);
|
trackDataHub = new TrackDataHub(this);
|
||||||
|
|
||||||
viewBinding.trackDetailActivityViewPager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
|
CustomFragmentPagerAdapter pagerAdapter = new CustomFragmentPagerAdapter(this);
|
||||||
viewBinding.trackDetailActivityTablayout.setupWithViewPager(viewBinding.trackDetailActivityViewPager);
|
viewBinding.trackDetailActivityViewPager.setAdapter(pagerAdapter);
|
||||||
|
new TabLayoutMediator(viewBinding.trackDetailActivityTablayout, viewBinding.trackDetailActivityViewPager,
|
||||||
|
(tab, position) -> tab.setText(pagerAdapter.getPageTitle(position))).attach();
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
||||||
}
|
}
|
||||||
@@ -220,20 +225,15 @@ public class TrackRecordedActivity extends AbstractListActivity implements Confi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
public CustomFragmentPagerAdapter(@NonNull FragmentManager fm, int behavior) {
|
public CustomFragmentPagerAdapter(@NonNull FragmentActivity fa) {
|
||||||
super(fm, behavior);
|
super(fa);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
return StatisticsRecordedFragment.newInstance(trackId);
|
return StatisticsRecordedFragment.newInstance(trackId);
|
||||||
@@ -249,6 +249,10 @@ public class TrackRecordedActivity extends AbstractListActivity implements Confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
public CharSequence getPageTitle(int position) {
|
public CharSequence getPageTitle(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import android.view.WindowManager;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.TrackDataHub;
|
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
@@ -148,8 +150,10 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
|
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
|
||||||
trackDataHub = new TrackDataHub(this);
|
trackDataHub = new TrackDataHub(this);
|
||||||
|
|
||||||
viewBinding.trackDetailActivityViewPager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
|
CustomFragmentPagerAdapter pagerAdapter = new CustomFragmentPagerAdapter(this);
|
||||||
viewBinding.trackDetailActivityTablayout.setupWithViewPager(viewBinding.trackDetailActivityViewPager);
|
viewBinding.trackDetailActivityViewPager.setAdapter(pagerAdapter);
|
||||||
|
new TabLayoutMediator(viewBinding.trackDetailActivityTablayout, viewBinding.trackDetailActivityViewPager,
|
||||||
|
(tab, position) -> tab.setText(pagerAdapter.getPageTitle(position))).attach();
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY));
|
||||||
}
|
}
|
||||||
@@ -358,20 +362,15 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
public CustomFragmentPagerAdapter(@NonNull FragmentManager fm, int behavior) {
|
public CustomFragmentPagerAdapter(@NonNull FragmentActivity fa) {
|
||||||
super(fm, behavior);
|
super(fa);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment getItem(int position) {
|
public Fragment createFragment(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
return StatisticsRecordingFragment.newInstance();
|
return StatisticsRecordingFragment.newInstance();
|
||||||
@@ -387,6 +386,10 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
public CharSequence getPageTitle(int position) {
|
public CharSequence getPageTitle(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package de.dennisguse.opentracks.adapters;
|
package de.dennisguse.opentracks.adapters;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -20,10 +19,10 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
|||||||
|
|
||||||
public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.Interval> {
|
public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.Interval> {
|
||||||
|
|
||||||
private StackMode stackMode;
|
private final StackMode stackMode;
|
||||||
private boolean metricUnits;
|
private final boolean metricUnits;
|
||||||
private float sumDistance_m;
|
private float sumDistance_m;
|
||||||
private String category;
|
private final String category;
|
||||||
|
|
||||||
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList, String category, StackMode stackMode) {
|
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList, String category, StackMode stackMode) {
|
||||||
super(context, R.layout.interval_stats_list_item, intervalList);
|
super(context, R.layout.interval_stats_list_item, intervalList);
|
||||||
@@ -61,15 +60,12 @@ public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.I
|
|||||||
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
|
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
|
||||||
|
|
||||||
if (PreferencesUtils.isReportSpeed(getContext(), category)) {
|
if (PreferencesUtils.isReportSpeed(getContext(), category)) {
|
||||||
Pair<String, String> speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, true);
|
viewHolder.rate.setText(StringUtils.formatSpeed(getContext(), interval.getSpeed_ms(), metricUnits, true));
|
||||||
viewHolder.rate.setText(speedParts.first + " " + speedParts.second);
|
|
||||||
} else {
|
} else {
|
||||||
Pair<String, String> paceParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, false);
|
viewHolder.rate.setText(StringUtils.formatSpeed(getContext(), interval.getSpeed_ms(), metricUnits, false));
|
||||||
viewHolder.rate.setText(paceParts.first + " " + paceParts.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<String, String> gainParts = StringUtils.formatElevation(getContext(), interval.getGain_m(), metricUnits);
|
viewHolder.gain.setText(StringUtils.formatDistance(getContext(), interval.getGain_m(), metricUnits));
|
||||||
viewHolder.gain.setText(gainParts.first + " " + gainParts.second);
|
|
||||||
|
|
||||||
return intervalView;
|
return intervalView;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ abstract class ChartValueSeries {
|
|||||||
* @param fillColor the fill color
|
* @param fillColor the fill color
|
||||||
* @param strokeColor the stroke color
|
* @param strokeColor the stroke color
|
||||||
*/
|
*/
|
||||||
ChartValueSeries(Context context, int absoluteMin, int absoluteMax, int[] intervalValues, int metricTitleId, int imperialTitleId, int fillColor, int strokeColor) {
|
ChartValueSeries(Context context, int absoluteMin, int absoluteMax, int[] intervalValues, int metricTitleId, int imperialTitleId, int fillColor, int strokeColor, int fontSizeSmall, int fontSizeMedium) {
|
||||||
this.absoluteMin = absoluteMin;
|
this.absoluteMin = absoluteMin;
|
||||||
this.absoluteMax = absoluteMax;
|
this.absoluteMax = absoluteMax;
|
||||||
this.intervalValues = intervalValues;
|
this.intervalValues = intervalValues;
|
||||||
@@ -85,16 +85,14 @@ abstract class ChartValueSeries {
|
|||||||
strokePaint.setColor(context.getResources().getColor(strokeColor));
|
strokePaint.setColor(context.getResources().getColor(strokeColor));
|
||||||
strokePaint.setAntiAlias(true);
|
strokePaint.setAntiAlias(true);
|
||||||
|
|
||||||
float scale = context.getResources().getDisplayMetrics().density;
|
|
||||||
|
|
||||||
// Make copies of the stroke paint with the default thickness
|
// Make copies of the stroke paint with the default thickness
|
||||||
titlePaint = new Paint(strokePaint);
|
titlePaint = new Paint(strokePaint);
|
||||||
titlePaint.setTextSize(ChartView.MEDIUM_TEXT_SIZE * scale);
|
titlePaint.setTextSize(fontSizeMedium);
|
||||||
titlePaint.setTextAlign(Align.CENTER);
|
titlePaint.setTextAlign(Align.CENTER);
|
||||||
titlePaint.setStyle(Style.FILL_AND_STROKE);
|
titlePaint.setStyle(Style.FILL_AND_STROKE);
|
||||||
|
|
||||||
markerPaint = new Paint(strokePaint);
|
markerPaint = new Paint(strokePaint);
|
||||||
markerPaint.setTextSize(ChartView.SMALL_TEXT_SIZE * scale);
|
markerPaint.setTextSize(fontSizeSmall);
|
||||||
markerPaint.setTextAlign(Align.RIGHT);
|
markerPaint.setTextAlign(Align.RIGHT);
|
||||||
markerPaint.setStyle(Style.FILL_AND_STROKE);
|
markerPaint.setStyle(Style.FILL_AND_STROKE);
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,11 @@ import android.view.GestureDetector;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewParent;
|
||||||
import android.widget.Scroller;
|
import android.widget.Scroller;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.view.GestureDetectorCompat;
|
import androidx.core.view.GestureDetectorCompat;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
@@ -58,9 +60,6 @@ import de.dennisguse.opentracks.util.UnitConversions;
|
|||||||
*/
|
*/
|
||||||
public class ChartView extends View {
|
public class ChartView extends View {
|
||||||
|
|
||||||
static final float MEDIUM_TEXT_SIZE = 18f;
|
|
||||||
static final float SMALL_TEXT_SIZE = 12f;
|
|
||||||
|
|
||||||
static final int Y_AXIS_INTERVALS = 5;
|
static final int Y_AXIS_INTERVALS = 5;
|
||||||
|
|
||||||
private static final int TARGET_X_AXIS_INTERVALS = 4;
|
private static final int TARGET_X_AXIS_INTERVALS = 4;
|
||||||
@@ -114,7 +113,7 @@ public class ChartView extends View {
|
|||||||
private int effectiveWidth = 0;
|
private int effectiveWidth = 0;
|
||||||
private int effectiveHeight = 0;
|
private int effectiveHeight = 0;
|
||||||
|
|
||||||
private boolean chartByDistance;
|
private final boolean chartByDistance;
|
||||||
private boolean metricUnits = true;
|
private boolean metricUnits = true;
|
||||||
private boolean reportSpeed = true;
|
private boolean reportSpeed = true;
|
||||||
private boolean showPointer = false;
|
private boolean showPointer = false;
|
||||||
@@ -192,6 +191,9 @@ public class ChartView extends View {
|
|||||||
public ChartView(Context context, final boolean chartByDistance) {
|
public ChartView(Context context, final boolean chartByDistance) {
|
||||||
super(context);
|
super(context);
|
||||||
this.chartByDistance = chartByDistance;
|
this.chartByDistance = chartByDistance;
|
||||||
|
int fontSizeSmall = ThemeUtils.getFontSizeSmallInPx(context);
|
||||||
|
int fontSizeMedium = ThemeUtils.getFontSizeMediumInPx(context);
|
||||||
|
|
||||||
seriesList.add(new ChartValueSeries(context,
|
seriesList.add(new ChartValueSeries(context,
|
||||||
Integer.MIN_VALUE,
|
Integer.MIN_VALUE,
|
||||||
Integer.MAX_VALUE,
|
Integer.MAX_VALUE,
|
||||||
@@ -199,7 +201,9 @@ public class ChartView extends View {
|
|||||||
R.string.description_elevation_metric,
|
R.string.description_elevation_metric,
|
||||||
R.string.description_elevation_imperial,
|
R.string.description_elevation_imperial,
|
||||||
R.color.chart_elevation_fill,
|
R.color.chart_elevation_fill,
|
||||||
R.color.chart_elevation_border) {
|
R.color.chart_elevation_border,
|
||||||
|
fontSizeSmall,
|
||||||
|
fontSizeMedium) {
|
||||||
@Override
|
@Override
|
||||||
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getElevation();
|
return chartPoint.getElevation();
|
||||||
@@ -218,7 +222,9 @@ public class ChartView extends View {
|
|||||||
R.string.description_speed_metric,
|
R.string.description_speed_metric,
|
||||||
R.string.description_speed_imperial,
|
R.string.description_speed_imperial,
|
||||||
R.color.chart_speed_fill,
|
R.color.chart_speed_fill,
|
||||||
R.color.chart_speed_border) {
|
R.color.chart_speed_border,
|
||||||
|
fontSizeSmall,
|
||||||
|
fontSizeMedium) {
|
||||||
@Override
|
@Override
|
||||||
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getSpeed();
|
return chartPoint.getSpeed();
|
||||||
@@ -238,7 +244,9 @@ public class ChartView extends View {
|
|||||||
R.string.description_pace_metric,
|
R.string.description_pace_metric,
|
||||||
R.string.description_pace_imperial,
|
R.string.description_pace_imperial,
|
||||||
R.color.chart_pace_fill,
|
R.color.chart_pace_fill,
|
||||||
R.color.chart_pace_border) {
|
R.color.chart_pace_border,
|
||||||
|
fontSizeSmall,
|
||||||
|
fontSizeMedium) {
|
||||||
@Override
|
@Override
|
||||||
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getPace();
|
return chartPoint.getPace();
|
||||||
@@ -258,7 +266,9 @@ public class ChartView extends View {
|
|||||||
R.string.description_sensor_heart_rate,
|
R.string.description_sensor_heart_rate,
|
||||||
R.string.description_sensor_heart_rate,
|
R.string.description_sensor_heart_rate,
|
||||||
R.color.chart_heart_rate_fill,
|
R.color.chart_heart_rate_fill,
|
||||||
R.color.chart_heart_rate_border) {
|
R.color.chart_heart_rate_border,
|
||||||
|
fontSizeSmall,
|
||||||
|
fontSizeMedium) {
|
||||||
@Override
|
@Override
|
||||||
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getHeartRate();
|
return chartPoint.getHeartRate();
|
||||||
@@ -277,7 +287,9 @@ public class ChartView extends View {
|
|||||||
R.string.description_sensor_cadence,
|
R.string.description_sensor_cadence,
|
||||||
R.string.description_sensor_cadence,
|
R.string.description_sensor_cadence,
|
||||||
R.color.chart_cadence_fill,
|
R.color.chart_cadence_fill,
|
||||||
R.color.chart_cadence_border) {
|
R.color.chart_cadence_border,
|
||||||
|
fontSizeSmall,
|
||||||
|
fontSizeMedium) {
|
||||||
@Override
|
@Override
|
||||||
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getCadence();
|
return chartPoint.getCadence();
|
||||||
@@ -295,7 +307,9 @@ public class ChartView extends View {
|
|||||||
R.string.description_sensor_power,
|
R.string.description_sensor_power,
|
||||||
R.string.description_sensor_power,
|
R.string.description_sensor_power,
|
||||||
R.color.chart_power_fill,
|
R.color.chart_power_fill,
|
||||||
R.color.chart_power_border) {
|
R.color.chart_power_border,
|
||||||
|
fontSizeSmall,
|
||||||
|
fontSizeMedium) {
|
||||||
@Override
|
@Override
|
||||||
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
|
||||||
return chartPoint.getPower();
|
return chartPoint.getPower();
|
||||||
@@ -309,13 +323,11 @@ public class ChartView extends View {
|
|||||||
|
|
||||||
backgroundColor = ThemeUtils.getBackgroundColor(context);
|
backgroundColor = ThemeUtils.getBackgroundColor(context);
|
||||||
|
|
||||||
float scale = context.getResources().getDisplayMetrics().density;
|
|
||||||
|
|
||||||
axisPaint = new Paint();
|
axisPaint = new Paint();
|
||||||
axisPaint.setStyle(Style.FILL_AND_STROKE);
|
axisPaint.setStyle(Style.FILL_AND_STROKE);
|
||||||
axisPaint.setColor(ThemeUtils.getTextColorPrimary(context));
|
axisPaint.setColor(ThemeUtils.getTextColorPrimary(context));
|
||||||
axisPaint.setAntiAlias(true);
|
axisPaint.setAntiAlias(true);
|
||||||
axisPaint.setTextSize(SMALL_TEXT_SIZE * scale);
|
axisPaint.setTextSize(fontSizeSmall);
|
||||||
|
|
||||||
xAxisMarkerPaint = new Paint(axisPaint);
|
xAxisMarkerPaint = new Paint(axisPaint);
|
||||||
xAxisMarkerPaint.setTextAlign(Align.CENTER);
|
xAxisMarkerPaint.setTextAlign(Align.CENTER);
|
||||||
@@ -330,7 +342,7 @@ public class ChartView extends View {
|
|||||||
markerPaint.setStyle(Style.STROKE);
|
markerPaint.setStyle(Style.STROKE);
|
||||||
markerPaint.setAntiAlias(false);
|
markerPaint.setAntiAlias(false);
|
||||||
|
|
||||||
pointer = context.getResources().getDrawable(R.drawable.ic_logo_color_24dp);
|
pointer = ContextCompat.getDrawable(context, R.drawable.ic_logo_color_24dp);
|
||||||
pointer.setBounds(0, 0, pointer.getIntrinsicWidth(), pointer.getIntrinsicHeight());
|
pointer.setBounds(0, 0, pointer.getIntrinsicWidth(), pointer.getIntrinsicHeight());
|
||||||
|
|
||||||
markerPin = MarkerUtils.getDefaultPhoto(context);
|
markerPin = MarkerUtils.getDefaultPhoto(context);
|
||||||
@@ -489,6 +501,18 @@ public class ChartView extends View {
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle parent's view disallow touch event.
|
||||||
|
*
|
||||||
|
* @param disallow Does disallow parent touch event?
|
||||||
|
*/
|
||||||
|
private void requestDisallowInterceptTouchEventInParent(boolean disallow) {
|
||||||
|
ViewParent parent = getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.requestDisallowInterceptTouchEvent(disallow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrolls the view horizontally by a given amount.
|
* Scrolls the view horizontally by a given amount.
|
||||||
*
|
*
|
||||||
@@ -496,13 +520,15 @@ public class ChartView extends View {
|
|||||||
*/
|
*/
|
||||||
private void scrollBy(int deltaX) {
|
private void scrollBy(int deltaX) {
|
||||||
int scrollX = getScrollX() + deltaX;
|
int scrollX = getScrollX() + deltaX;
|
||||||
if (scrollX < 0) {
|
if (scrollX <= 0) {
|
||||||
scrollX = 0;
|
scrollX = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxWidth = effectiveWidth * (zoomLevel - 1);
|
int maxWidth = effectiveWidth * (zoomLevel - 1);
|
||||||
if (scrollX > maxWidth) {
|
if (scrollX >= maxWidth) {
|
||||||
scrollX = maxWidth;
|
scrollX = maxWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollTo(scrollX, 0);
|
scrollTo(scrollX, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +553,10 @@ public class ChartView extends View {
|
|||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
boolean isZoom = detectorZoom.onTouchEvent(event);
|
boolean isZoom = detectorZoom.onTouchEvent(event);
|
||||||
boolean isScrollTab = detectorScrollFlingTab.onTouchEvent(event);
|
boolean isScrollTab = detectorScrollFlingTab.onTouchEvent(event);
|
||||||
|
|
||||||
|
// ChartView handles zoom gestures (more than one pointer) and all gestures when zoomed itself
|
||||||
|
requestDisallowInterceptTouchEventInParent(event.getPointerCount() != 1 || zoomLevel != MIN_ZOOM_LEVEL);
|
||||||
|
|
||||||
return isZoom || isScrollTab;
|
return isZoom || isScrollTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,6 +911,7 @@ public class ChartView extends View {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the index of the first data point containing data for a series.
|
* Finds the index of the first data point containing data for a series.
|
||||||
|
*
|
||||||
* @return -1 if no data point contains data for the series.
|
* @return -1 if no data point contains data for the series.
|
||||||
*/
|
*/
|
||||||
private int getFirstPopulatedChartDataIndex(ChartValueSeries chartValueSeries) {
|
private int getFirstPopulatedChartDataIndex(ChartValueSeries chartValueSeries) {
|
||||||
|
|||||||
@@ -488,7 +488,7 @@ public class ContentProviderUtils {
|
|||||||
private void deleteMarkerPhoto(Context context, Marker marker) {
|
private void deleteMarkerPhoto(Context context, Marker marker) {
|
||||||
if (marker != null && marker.hasPhoto()) {
|
if (marker != null && marker.hasPhoto()) {
|
||||||
Uri uri = marker.getPhotoURI();
|
Uri uri = marker.getPhotoURI();
|
||||||
File file = FileUtils.getPhotoFileIfExists(context, marker.getTrackId(), uri);
|
File file = FileUtils.buildInternalPhotoFile(context, marker.getTrackId(), uri);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
File parent = file.getParentFile();
|
File parent = file.getParentFile();
|
||||||
file.delete();
|
file.delete();
|
||||||
@@ -616,7 +616,7 @@ public class ContentProviderUtils {
|
|||||||
* @param trackId the trackPoints id
|
* @param trackId the trackPoints id
|
||||||
* @return the number of trackPoints inserted
|
* @return the number of trackPoints inserted
|
||||||
*/
|
*/
|
||||||
//TODO Only used for testing and file import; might be better to replace it.
|
//TODO Only used for testing; might be better to replace it.
|
||||||
public int bulkInsertTrackPoint(TrackPoint[] trackPoints, Track.Id trackId) {
|
public int bulkInsertTrackPoint(TrackPoint[] trackPoints, Track.Id trackId) {
|
||||||
ContentValues[] values = new ContentValues[trackPoints.length];
|
ContentValues[] values = new ContentValues[trackPoints.length];
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
@@ -625,6 +625,15 @@ public class ContentProviderUtils {
|
|||||||
return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values);
|
return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Only used for file import; might be better to replace it.
|
||||||
|
public int bulkInsertTrackPoint(List<TrackPoint> trackPoints, Track.Id trackId) {
|
||||||
|
ContentValues[] values = new ContentValues[trackPoints.size()];
|
||||||
|
for (int i = 0; i < trackPoints.size(); i++) {
|
||||||
|
values[i] = createContentValues(trackPoints.get(i), trackId);
|
||||||
|
}
|
||||||
|
return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the first location id for a track.
|
* Gets the first location id for a track.
|
||||||
* Returns null if it doesn't exist.
|
* Returns null if it doesn't exist.
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
|||||||
|
|
||||||
private ChartBinding viewBinding;
|
private ChartBinding viewBinding;
|
||||||
|
|
||||||
//TODO Why is this needed?
|
//TODO REMOVE: Used to restore the TrackStatistics via TrackStatisticsUpdater; for the diagrams we should consider not this setting and just use all data that is in the database
|
||||||
|
@Deprecated
|
||||||
private int recordingDistanceInterval;
|
private int recordingDistanceInterval;
|
||||||
private String category = "";
|
private String category = "";
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
protected IntervalStatisticsAdapter.StackMode stackModeListView;
|
protected IntervalStatisticsAdapter.StackMode stackModeListView;
|
||||||
private IntervalStatisticsModel.IntervalOption selectedInterval;
|
private IntervalStatisticsModel.IntervalOption selectedInterval;
|
||||||
|
|
||||||
private String intervalUnit;
|
private boolean metricUnits;
|
||||||
private IntervalStatisticsAdapter adapter;
|
private IntervalStatisticsAdapter adapter;
|
||||||
private ArrayAdapter<IntervalStatisticsModel.IntervalOption> spinnerAdapter;
|
private ArrayAdapter<IntervalStatisticsModel.IntervalOption> spinnerAdapter;
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
|
|
||||||
protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
||||||
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
|
||||||
intervalUnit = PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile);
|
metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
spinnerAdapter.notifyDataSetChanged();
|
spinnerAdapter.notifyDataSetChanged();
|
||||||
@@ -74,7 +74,7 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
|
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
|
||||||
intervalUnit = PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile);
|
metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||||
|
|
||||||
viewBinding.intervalList.setEmptyView(viewBinding.intervalListEmptyView);
|
viewBinding.intervalList.setEmptyView(viewBinding.intervalListEmptyView);
|
||||||
|
|
||||||
@@ -87,15 +87,17 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
@Override
|
@Override
|
||||||
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
TextView v = (TextView) super.getView(position, convertView, parent);
|
TextView v = (TextView) super.getView(position, convertView, parent);
|
||||||
v.setText(v.getText() + " " + intervalUnit);
|
if (metricUnits) {
|
||||||
|
v.setText(getContext().getString(R.string.value_integer_kilometer, Integer.parseInt(v.getText().toString())));
|
||||||
|
} else {
|
||||||
|
v.setText(getContext().getString(R.string.value_integer_mile, Integer.parseInt(v.getText().toString())));
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
TextView v = (TextView) super.getDropDownView(position, convertView, parent);
|
return getView(position, convertView, parent);
|
||||||
v.setText(v.getText() + " " + intervalUnit);
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,7 +151,6 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
|
||||||
IntervalStatistics intervalStatistics = viewModel.getIntervalStats(metricUnits, selectedInterval);
|
IntervalStatistics intervalStatistics = viewModel.getIntervalStats(metricUnits, selectedInterval);
|
||||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList(), category, stackModeListView);
|
adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList(), category, stackModeListView);
|
||||||
viewBinding.intervalList.setAdapter(adapter);
|
viewBinding.intervalList.setAdapter(adapter);
|
||||||
|
|||||||
@@ -109,9 +109,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
|||||||
handlerUpdateUI = new Handler();
|
handlerUpdateUI = new Handler();
|
||||||
|
|
||||||
|
|
||||||
viewBinding.statsActivityTypeIcon.setOnClickListener(v -> {
|
viewBinding.statsActivityTypeIcon.setOnClickListener(v -> ((TrackRecordingActivity) getActivity()).chooseActivityType(category));
|
||||||
((TrackRecordingActivity) getActivity()).chooseActivityType(category);
|
|
||||||
});
|
|
||||||
|
|
||||||
sensorsAdapter = new SensorsAdapter(getContext());
|
sensorsAdapter = new SensorsAdapter(getContext());
|
||||||
sensorsRecyclerView = viewBinding.statsSensorsRecyclerView;
|
sensorsRecyclerView = viewBinding.statsSensorsRecyclerView;
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ public class ExportActivity extends FragmentActivity implements ExportServiceRes
|
|||||||
public boolean resolve() {
|
public boolean resolve() {
|
||||||
if (autoConflict == CONFLICT_NONE) {
|
if (autoConflict == CONFLICT_NONE) {
|
||||||
Track track = contentProviderUtils.getTrack(trackId);
|
Track track = contentProviderUtils.getTrack(trackId);
|
||||||
viewBinding.exportProgressAlertIcon.setImageDrawable(getDrawable(R.drawable.ic_report_problem_24));
|
viewBinding.exportProgressAlertIcon.setImageDrawable(ContextCompat.getDrawable(ExportActivity.this, R.drawable.ic_report_problem_24));
|
||||||
viewBinding.exportProgressAlertMsg.setText(getString(R.string.export_track_already_exists_msg, track.getName()));
|
viewBinding.exportProgressAlertMsg.setText(getString(R.string.export_track_already_exists_msg, track.getName()));
|
||||||
setConflictVisibility(View.VISIBLE);
|
setConflictVisibility(View.VISIBLE);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
@Override
|
@Override
|
||||||
public void writeMarker(Marker marker) {
|
public void writeMarker(Marker marker) {
|
||||||
if (printWriter != null && exportTrackDetail) {
|
if (printWriter != null && exportTrackDetail) {
|
||||||
boolean existsPhoto = FileUtils.getPhotoFileIfExists(context, marker.getTrackId(), marker.getPhotoURI()) != null;
|
boolean existsPhoto = FileUtils.buildInternalPhotoFile(context, marker.getTrackId(), marker.getPhotoURI()) != null;
|
||||||
if (marker.hasPhoto() && exportPhotos && existsPhoto) {
|
if (marker.hasPhoto() && exportPhotos && existsPhoto) {
|
||||||
float heading = getHeading(marker.getTrackId(), marker.getLocation());
|
float heading = getHeading(marker.getTrackId(), marker.getLocation());
|
||||||
writePhotoOverlay(marker, heading);
|
writePhotoOverlay(marker, heading);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class KmzTrackExporter implements TrackExporter {
|
|||||||
private final FileTrackExporter fileTrackExporter;
|
private final FileTrackExporter fileTrackExporter;
|
||||||
|
|
||||||
private final boolean exportPhotos;
|
private final boolean exportPhotos;
|
||||||
private Context context;
|
private final Context context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -108,7 +108,7 @@ public class KmzTrackExporter implements TrackExporter {
|
|||||||
Marker marker = contentProviderUtils.createMarker(cursor);
|
Marker marker = contentProviderUtils.createMarker(cursor);
|
||||||
if (marker.hasPhoto()) {
|
if (marker.hasPhoto()) {
|
||||||
Uri uriPhoto = marker.getPhotoURI();
|
Uri uriPhoto = marker.getPhotoURI();
|
||||||
boolean existsPhoto = FileUtils.getPhotoFileIfExists(context, track.getId(), uriPhoto) != null;
|
boolean existsPhoto = FileUtils.buildInternalPhotoFile(context, track.getId(), uriPhoto) != null;
|
||||||
if (existsPhoto) {
|
if (existsPhoto) {
|
||||||
addImage(context, zipOutputStream, uriPhoto, marker);
|
addImage(context, zipOutputStream, uriPhoto, marker);
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-28
@@ -29,7 +29,6 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -61,9 +60,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
|
|
||||||
private static final String TAG = AbstractFileTrackImporter.class.getSimpleName();
|
private static final String TAG = AbstractFileTrackImporter.class.getSimpleName();
|
||||||
|
|
||||||
// The maximum number of buffered locations for bulk-insertion
|
|
||||||
private static final int MAX_BUFFERED_LOCATIONS = 512;
|
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final ContentProviderUtils contentProviderUtils;
|
private final ContentProviderUtils contentProviderUtils;
|
||||||
private final int recordingDistanceInterval;
|
private final int recordingDistanceInterval;
|
||||||
@@ -127,18 +123,15 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
|
|
||||||
saxParser.parse(inputStream, this);
|
saxParser.parse(inputStream, this);
|
||||||
Log.d(TAG, "Total import time: " + (System.currentTimeMillis() - start) + "ms");
|
Log.d(TAG, "Total import time: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
if (trackIds.size() != 1) {
|
|
||||||
// TODO Multi track is not supported yet.
|
|
||||||
throw new ImportParserException("Multi track not supported");
|
|
||||||
}
|
|
||||||
return trackIds.get(0);
|
return trackIds.get(0);
|
||||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||||
Log.e(TAG, "Unable to import file", e);
|
Log.e(TAG, "Unable to import file", e);
|
||||||
cleanImport();
|
if (trackIds.size() > 0) {
|
||||||
|
cleanImport();
|
||||||
|
}
|
||||||
throw new ImportParserException(e);
|
throw new ImportParserException(e);
|
||||||
} catch (SQLiteConstraintException e) {
|
} catch (SQLiteConstraintException e) {
|
||||||
Log.e(TAG, "Unable to import file", e);
|
Log.e(TAG, "Unable to import file", e);
|
||||||
cleanImport();
|
|
||||||
throw new ImportAlreadyExistsException(e);
|
throw new ImportAlreadyExistsException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,17 +221,12 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
*/
|
*/
|
||||||
protected void onTrackStart() throws SAXException {
|
protected void onTrackStart() throws SAXException {
|
||||||
trackData = new TrackData();
|
trackData = new TrackData();
|
||||||
Uri uri = contentProviderUtils.insertTrack(trackData.track);
|
|
||||||
Track.Id trackId = new Track.Id(Long.parseLong(uri.getLastPathSegment()));
|
|
||||||
trackIds.add(trackId);
|
|
||||||
trackData.track.setId(trackId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On track end.
|
* On track end.
|
||||||
*/
|
*/
|
||||||
protected void onTrackEnd() {
|
protected void onTrackEnd() {
|
||||||
flushLocations(trackData);
|
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
trackData.track.setName(name);
|
trackData.track.setName(name);
|
||||||
}
|
}
|
||||||
@@ -268,17 +256,27 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
}
|
}
|
||||||
trackData.track.setTrackStatistics(trackData.trackStatisticsUpdater.getTrackStatistics());
|
trackData.track.setTrackStatistics(trackData.trackStatisticsUpdater.getTrackStatistics());
|
||||||
|
|
||||||
try {
|
Track track = contentProviderUtils.getTrack(trackData.track.getUuid());
|
||||||
contentProviderUtils.updateTrack(trackData.track);
|
if (track != null) {
|
||||||
} catch (SQLiteConstraintException e) {
|
|
||||||
if (PreferencesUtils.getPreventReimportTracks(context)) {
|
if (PreferencesUtils.getPreventReimportTracks(context)) {
|
||||||
throw e;
|
throw new ImportAlreadyExistsException(context.getString(R.string.import_prevent_reimport));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO This is a workaround until we have proper UI.
|
//TODO This is a workaround until we have proper UI.
|
||||||
trackData.track.setUuid(UUID.randomUUID());
|
trackData.track.setUuid(UUID.randomUUID());
|
||||||
contentProviderUtils.updateTrack(trackData.track);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trackIds.size() > 0) {
|
||||||
|
// TODO Multi track is not supported yet.
|
||||||
|
cleanImport();
|
||||||
|
throw new ImportParserException("Multi track not supported");
|
||||||
|
}
|
||||||
|
Uri uri = contentProviderUtils.insertTrack(trackData.track);
|
||||||
|
Track.Id trackId = new Track.Id(Long.parseLong(uri.getLastPathSegment()));
|
||||||
|
trackIds.add(trackId);
|
||||||
|
trackData.track.setId(trackId);
|
||||||
|
|
||||||
|
flushLocations(trackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,7 +301,8 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
TrackPoint trackPoint = createTrackPoint();
|
TrackPoint trackPoint = createTrackPoint();
|
||||||
|
|
||||||
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
||||||
throw new SAXException(createErrorMessage("Invalid location detected: " + trackPoint));
|
Log.w(TAG, "Marker with invalid coordinates ignored: " + trackPoint.getLocation());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Marker marker = new Marker(trackPoint.getLocation());
|
Marker marker = new Marker(trackPoint.getLocation());
|
||||||
|
|
||||||
@@ -482,13 +481,9 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
}
|
}
|
||||||
trackData.trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
|
trackData.trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
|
||||||
|
|
||||||
trackData.bufferedTrackPoints[trackData.numBufferedTrackPoints] = trackPoint;
|
trackData.bufferedTrackPoints.add(trackPoint);
|
||||||
trackData.numBufferedTrackPoints++;
|
trackData.numBufferedTrackPoints++;
|
||||||
trackData.numberOfLocations++;
|
trackData.numberOfLocations++;
|
||||||
|
|
||||||
if (trackData.numBufferedTrackPoints >= MAX_BUFFERED_LOCATIONS) {
|
|
||||||
flushLocations(trackData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -500,7 +495,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
if (data.numBufferedTrackPoints <= 0) {
|
if (data.numBufferedTrackPoints <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(data.bufferedTrackPoints, 0, data.numBufferedTrackPoints), data.track.getId());
|
contentProviderUtils.bulkInsertTrackPoint(data.bufferedTrackPoints, data.track.getId());
|
||||||
data.numBufferedTrackPoints = 0;
|
data.numBufferedTrackPoints = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,7 +532,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
final long importTime = System.currentTimeMillis();
|
final long importTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// The buffered locations
|
// The buffered locations
|
||||||
final TrackPoint[] bufferedTrackPoints = new TrackPoint[MAX_BUFFERED_LOCATIONS];
|
final List<TrackPoint> bufferedTrackPoints = new ArrayList<>();
|
||||||
|
|
||||||
// The number of buffered locations
|
// The number of buffered locations
|
||||||
int numBufferedTrackPoints = 0;
|
int numBufferedTrackPoints = 0;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
@@ -161,12 +162,12 @@ public class ImportActivity extends FragmentActivity {
|
|||||||
viewBinding.importProgressLeftButton.setVisibility(View.VISIBLE);
|
viewBinding.importProgressLeftButton.setVisibility(View.VISIBLE);
|
||||||
viewBinding.importProgressLeftButton.setText(getString(R.string.generic_show_errors));
|
viewBinding.importProgressLeftButton.setText(getString(R.string.generic_show_errors));
|
||||||
viewBinding.importProgressLeftButton.setOnClickListener((view) -> ErrorListDialog.showDialog(getSupportFragmentManager(), getString(R.string.import_error_list_dialog_title), summary.getFileErrors()));
|
viewBinding.importProgressLeftButton.setOnClickListener((view) -> ErrorListDialog.showDialog(getSupportFragmentManager(), getString(R.string.import_error_list_dialog_title), summary.getFileErrors()));
|
||||||
viewBinding.importProgressAlertIcon.setImageDrawable(getDrawable(R.drawable.ic_report_problem_24));
|
viewBinding.importProgressAlertIcon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_report_problem_24));
|
||||||
String msg = getResources().getQuantityString(R.plurals.generic_completed_with_errors, summary.getErrorCount(), summary.getErrorCount());
|
String msg = getResources().getQuantityString(R.plurals.generic_completed_with_errors, summary.getErrorCount(), summary.getErrorCount());
|
||||||
viewBinding.importProgressAlertMsg.setText(msg);
|
viewBinding.importProgressAlertMsg.setText(msg);
|
||||||
} else {
|
} else {
|
||||||
viewBinding.importProgressLeftButton.setVisibility(View.GONE);
|
viewBinding.importProgressLeftButton.setVisibility(View.GONE);
|
||||||
viewBinding.importProgressAlertIcon.setImageDrawable(getDrawable(R.drawable.ic_dialog_success_24dp));
|
viewBinding.importProgressAlertIcon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_dialog_success_24dp));
|
||||||
viewBinding.importProgressAlertMsg.setText(getString(R.string.generic_completed));
|
viewBinding.importProgressAlertMsg.setText(getString(R.string.generic_completed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -4,4 +4,8 @@ class ImportAlreadyExistsException extends RuntimeException {
|
|||||||
public ImportAlreadyExistsException(Exception e) {
|
public ImportAlreadyExistsException(Exception e) {
|
||||||
super(e);
|
super(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImportAlreadyExistsException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,12 +63,12 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
|||||||
|
|
||||||
private boolean trackStarted = false;
|
private boolean trackStarted = false;
|
||||||
private String extendedDataType;
|
private String extendedDataType;
|
||||||
private ArrayList<TrackPoint> trackPoints = new ArrayList<>();
|
private final ArrayList<TrackPoint> trackPoints = new ArrayList<>();
|
||||||
private ArrayList<Float> speedList = new ArrayList<>();
|
private final ArrayList<Float> speedList = new ArrayList<>();
|
||||||
private ArrayList<Float> cadenceList = new ArrayList<>();
|
private final ArrayList<Float> cadenceList = new ArrayList<>();
|
||||||
private ArrayList<Float> heartRateList = new ArrayList<>();
|
private final ArrayList<Float> heartRateList = new ArrayList<>();
|
||||||
private ArrayList<Float> powerList = new ArrayList<>();
|
private final ArrayList<Float> powerList = new ArrayList<>();
|
||||||
private ArrayList<Float> elevationGainList = new ArrayList<>();
|
private final ArrayList<Float> elevationGainList = new ArrayList<>();
|
||||||
|
|
||||||
public KmlFileTrackImporter(Context context) {
|
public KmlFileTrackImporter(Context context) {
|
||||||
this(context, new ContentProviderUtils(context));
|
this(context, new ContentProviderUtils(context));
|
||||||
|
|||||||
@@ -177,6 +177,10 @@ public class KmzTrackImporter implements TrackImporter {
|
|||||||
|
|
||||||
zipInputStream.closeEntry();
|
zipInputStream.closeEntry();
|
||||||
}
|
}
|
||||||
|
if (trackId == null) {
|
||||||
|
Log.d(TAG, "Unable to find doc.kml in kmz");
|
||||||
|
throw new RuntimeException(context.getString(R.string.import_no_kml_file_found));
|
||||||
|
}
|
||||||
return trackId;
|
return trackId;
|
||||||
} catch (ImportParserException | ImportAlreadyExistsException e) {
|
} catch (ImportParserException | ImportAlreadyExistsException e) {
|
||||||
Log.e(TAG, "Unable to import file", e);
|
Log.e(TAG, "Unable to import file", e);
|
||||||
@@ -271,6 +275,7 @@ public class KmzTrackImporter implements TrackImporter {
|
|||||||
* Reads an image file (zipInputStream) and save it in a file called fileName inside photo folder.
|
* Reads an image file (zipInputStream) and save it in a file called fileName inside photo folder.
|
||||||
*
|
*
|
||||||
* @param zipInputStream the zip input stream
|
* @param zipInputStream the zip input stream
|
||||||
|
* @param trackId the track's id which image belongs to.
|
||||||
* @param fileName the file name
|
* @param fileName the file name
|
||||||
*/
|
*/
|
||||||
private void readAndSaveImageFile(ZipInputStream zipInputStream, Track.Id trackId, String fileName) throws IOException {
|
private void readAndSaveImageFile(ZipInputStream zipInputStream, Track.Id trackId, String fileName) throws IOException {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class GpsStatus {
|
|||||||
|
|
||||||
private GpsStatusValue gpsStatus = GpsStatusValue.GPS_NONE;
|
private GpsStatusValue gpsStatus = GpsStatusValue.GPS_NONE;
|
||||||
private GpsStatusListener client;
|
private GpsStatusListener client;
|
||||||
private Context context;
|
private final Context context;
|
||||||
|
|
||||||
// Last location. It can be null.
|
// Last location. It can be null.
|
||||||
private Location lastLocation = null;
|
private Location lastLocation = null;
|
||||||
@@ -51,7 +51,7 @@ class GpsStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Handler gpsStatusHandler;
|
private final Handler gpsStatusHandler;
|
||||||
private GpsStatusRunner gpsStatusRunner = null;
|
private GpsStatusRunner gpsStatusRunner = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import de.dennisguse.opentracks.content.data.TrackPoint;
|
|||||||
|
|
||||||
public class HandlerServer {
|
public class HandlerServer {
|
||||||
|
|
||||||
private static String TAG = HandlerServer.class.getSimpleName();
|
private static final String TAG = HandlerServer.class.getSimpleName();
|
||||||
|
|
||||||
private final LocationHandler locationHandler;
|
private final LocationHandler locationHandler;
|
||||||
private final HandlerServerInterface service;
|
private final HandlerServerInterface service;
|
||||||
|
|||||||
@@ -95,9 +95,7 @@ public class ActivityTypePreference extends DialogPreference {
|
|||||||
});
|
});
|
||||||
|
|
||||||
iconView = view.findViewById(R.id.activity_type_preference_spinner);
|
iconView = view.findViewById(R.id.activity_type_preference_spinner);
|
||||||
iconView.setOnClickListener((it) -> {
|
iconView.setOnClickListener((it) -> showIconSelectDialog());
|
||||||
showIconSelectDialog();
|
|
||||||
});
|
|
||||||
|
|
||||||
updateIcon(TrackIconUtils.getIconValue(context, category));
|
updateIcon(TrackIconUtils.getIconValue(context, category));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
|||||||
activityPreferenceDialog = ActivityTypePreference.ActivityPreferenceDialog.newInstance(preference.getKey());
|
activityPreferenceDialog = ActivityTypePreference.ActivityPreferenceDialog.newInstance(preference.getKey());
|
||||||
dialogFragment = activityPreferenceDialog;
|
dialogFragment = activityPreferenceDialog;
|
||||||
} else if (preference instanceof BluetoothLeHeartRatePreference) {
|
} else if (preference instanceof BluetoothLeHeartRatePreference) {
|
||||||
dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.HEART_RATE_SERVICE_UUID);
|
dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.HEART_RATE_SUPPORTING_DEVICES);
|
||||||
} else if (preference instanceof BluetoothLeCyclingCadenceAndSpeedPreference) {
|
} else if (preference instanceof BluetoothLeCyclingCadenceAndSpeedPreference) {
|
||||||
dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID);
|
dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID);
|
||||||
} else if (preference instanceof BluetoothLeCyclingPowerPreference) {
|
} else if (preference instanceof BluetoothLeCyclingPowerPreference) {
|
||||||
|
|||||||
+30
-16
@@ -8,8 +8,6 @@ import android.bluetooth.le.ScanResult;
|
|||||||
import android.bluetooth.le.ScanSettings;
|
import android.bluetooth.le.ScanSettings;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.graphics.drawable.Animatable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -18,13 +16,15 @@ import android.util.Log;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.preference.DialogPreference;
|
import androidx.preference.DialogPreference;
|
||||||
import androidx.preference.PreferenceDialogFragmentCompat;
|
import androidx.preference.PreferenceDialogFragmentCompat;
|
||||||
|
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.settings.BluetoothLeAdapter;
|
import de.dennisguse.opentracks.settings.BluetoothLeAdapter;
|
||||||
@@ -39,7 +39,7 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
|
|
||||||
private static final String TAG = BluetoothLeSensorPreference.class.getSimpleName();
|
private static final String TAG = BluetoothLeSensorPreference.class.getSimpleName();
|
||||||
|
|
||||||
private static final String ARG_BLUETOOTH_UUID = "bluetoothUUID";
|
private static final String ARG_BLE_SERVICE_UUIDS = "bluetoothUUID";
|
||||||
|
|
||||||
private static final int DEVICE_NONE_RESOURCEID = R.string.value_none;
|
private static final int DEVICE_NONE_RESOURCEID = R.string.value_none;
|
||||||
|
|
||||||
@@ -94,6 +94,8 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
|
|
||||||
public static class BluetoothLeSensorPreferenceDialog extends PreferenceDialogFragmentCompat {
|
public static class BluetoothLeSensorPreferenceDialog extends PreferenceDialogFragmentCompat {
|
||||||
|
|
||||||
|
private AnimatedVectorDrawableCompat bluetoothIcon;
|
||||||
|
|
||||||
private int selectedEntryIndex;
|
private int selectedEntryIndex;
|
||||||
private final BluetoothLeAdapter listAdapter = new BluetoothLeAdapter();
|
private final BluetoothLeAdapter listAdapter = new BluetoothLeAdapter();
|
||||||
|
|
||||||
@@ -109,8 +111,9 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBatchScanResults(List<ScanResult> results) {
|
public void onBatchScanResults(List<ScanResult> results) {
|
||||||
for (ScanResult scanResult : results) {
|
for (ScanResult result : results) {
|
||||||
listAdapter.add(scanResult.getDevice());
|
Log.d(TAG, "Found device " + result.getDevice().getName() + " " + result);
|
||||||
|
listAdapter.add(result.getDevice());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,10 +127,14 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static BluetoothLeSensorPreferenceDialog newInstance(String preferenceKey, UUID sensorUUID) {
|
public static BluetoothLeSensorPreferenceDialog newInstance(String preferenceKey, UUID sensorUUID) {
|
||||||
|
return newInstance(preferenceKey, Collections.singletonList(sensorUUID));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BluetoothLeSensorPreferenceDialog newInstance(String preferenceKey, List<UUID> sensorUUIDs) {
|
||||||
final BluetoothLeSensorPreferenceDialog fragment = new BluetoothLeSensorPreferenceDialog();
|
final BluetoothLeSensorPreferenceDialog fragment = new BluetoothLeSensorPreferenceDialog();
|
||||||
final Bundle b = new Bundle(1);
|
final Bundle b = new Bundle(1);
|
||||||
b.putString(ARG_KEY, preferenceKey);
|
b.putString(ARG_KEY, preferenceKey);
|
||||||
b.putSerializable(ARG_BLUETOOTH_UUID, sensorUUID);
|
b.putParcelableArrayList(ARG_BLE_SERVICE_UUIDS, new ArrayList<>(sensorUUIDs.stream().map(ParcelUuid::new).collect(Collectors.toList())));
|
||||||
fragment.setArguments(b);
|
fragment.setArguments(b);
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
@@ -136,8 +143,12 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
UUID sensorUUID = (UUID) getArguments().getSerializable(ARG_BLUETOOTH_UUID);
|
List<ParcelUuid> serviceUUIDs = getArguments().getParcelableArrayList(ARG_BLE_SERVICE_UUIDS);
|
||||||
Log.i(TAG, "UUID: " + sensorUUID);
|
|
||||||
|
// Don't know why: need to load the drawable _twice_, so that animation is actually started.
|
||||||
|
bluetoothIcon = AnimatedVectorDrawableCompat.create(getContext(), R.drawable.ic_bluetooth_searching_animated_24dp);
|
||||||
|
bluetoothIcon = AnimatedVectorDrawableCompat.create(getContext(), R.drawable.ic_bluetooth_searching_animated_24dp);
|
||||||
|
bluetoothIcon.start();
|
||||||
|
|
||||||
BluetoothAdapter bluetoothAdapter = BluetoothUtils.getAdapter(getContext());
|
BluetoothAdapter bluetoothAdapter = BluetoothUtils.getAdapter(getContext());
|
||||||
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
|
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
|
||||||
@@ -148,7 +159,7 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bluetoothAdapter.isDiscovering()) {
|
if (bluetoothAdapter.isDiscovering()) {
|
||||||
Log.i(TAG, "Cancelling ongoing B<aluetooth discovery.");
|
Log.i(TAG, "Cancelling ongoing Bluetooth discovery.");
|
||||||
bluetoothAdapter.cancelDiscovery();
|
bluetoothAdapter.cancelDiscovery();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,9 +181,7 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
selectedEntryIndex = 1;
|
selectedEntryIndex = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(sensorUUID));
|
List<ScanFilter> scanFilter = serviceUUIDs.stream().map(it -> new ScanFilter.Builder().setServiceUuid(it).build()).collect(Collectors.toList());
|
||||||
List<ScanFilter> scanFilter = new ArrayList<>();
|
|
||||||
scanFilter.add(scanFilterBuilder.build());
|
|
||||||
|
|
||||||
ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
|
ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
|
||||||
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
|
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
|
||||||
@@ -193,9 +202,7 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
});
|
});
|
||||||
|
|
||||||
Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_bluetooth_searching_animated_24dp);
|
builder.setIcon(bluetoothIcon);
|
||||||
((Animatable) icon).start();
|
|
||||||
builder.setIcon(icon);
|
|
||||||
|
|
||||||
builder.setPositiveButton(null, null);
|
builder.setPositiveButton(null, null);
|
||||||
}
|
}
|
||||||
@@ -214,5 +221,12 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
bluetoothIcon = null;
|
||||||
|
scanner = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ import android.util.Log;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
|
||||||
@@ -39,6 +42,12 @@ public class BluetoothUtils {
|
|||||||
public static final UUID HEART_RATE_SERVICE_UUID = new UUID(0x180D00001000L, 0x800000805f9b34fbL);
|
public static final UUID HEART_RATE_SERVICE_UUID = new UUID(0x180D00001000L, 0x800000805f9b34fbL);
|
||||||
public static final UUID HEART_RATE_MEASUREMENT_CHAR_UUID = new UUID(0x2A3700001000L, 0x800000805f9b34fbL);
|
public static final UUID HEART_RATE_MEASUREMENT_CHAR_UUID = new UUID(0x2A3700001000L, 0x800000805f9b34fbL);
|
||||||
|
|
||||||
|
public static final List<UUID> HEART_RATE_SUPPORTING_DEVICES = Collections.unmodifiableList(Arrays.asList(
|
||||||
|
BluetoothUtils.HEART_RATE_SERVICE_UUID,
|
||||||
|
//Devices that support HEART_RATE_SERVICE_UUID, but do not announce HEART_RATE_SERVICE_UUID in there BLE announcement messages (during device discovery).
|
||||||
|
UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb") //Miband3
|
||||||
|
));
|
||||||
|
|
||||||
public static final UUID CYCLING_POWER_UUID = new UUID(0x181800001000L, 0x800000805f9b34fbL);
|
public static final UUID CYCLING_POWER_UUID = new UUID(0x181800001000L, 0x800000805f9b34fbL);
|
||||||
public static final UUID CYCLING_POWER_MEASUREMENT_CHAR_UUID = new UUID(0x2A6300001000L, 0x800000805f9b34fbL);
|
public static final UUID CYCLING_POWER_MEASUREMENT_CHAR_UUID = new UUID(0x2A6300001000L, 0x800000805f9b34fbL);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
|
|
||||||
@@ -15,6 +16,6 @@ public class MarkerUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Drawable getDefaultPhoto(@NonNull Context context) {
|
public static Drawable getDefaultPhoto(@NonNull Context context) {
|
||||||
return context.getResources().getDrawable(ICON_ID);
|
return ContextCompat.getDrawable(context, ICON_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,18 @@ import android.hardware.SensorManager;
|
|||||||
public class PressureSensorUtils {
|
public class PressureSensorUtils {
|
||||||
|
|
||||||
//Everything above is considered a meaningful change in elevation.
|
//Everything above is considered a meaningful change in elevation.
|
||||||
private static float ELEVATION_CHANGE_DIFF_M = 3.0f;
|
private static final float ELEVATION_CHANGE_DIFF_M = 3.0f;
|
||||||
|
|
||||||
private static float EXPONENTIAL_SMOOTHING = 0.3f;
|
private static final float EXPONENTIAL_SMOOTHING = 0.3f;
|
||||||
|
|
||||||
private PressureSensorUtils() {
|
private PressureSensorUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ElevationChange {
|
public static class ElevationChange {
|
||||||
|
|
||||||
private float currentSensorValue_hPa;
|
private final float currentSensorValue_hPa;
|
||||||
|
|
||||||
private float elevationChange_m;
|
private final float elevationChange_m;
|
||||||
|
|
||||||
public ElevationChange(float currentSensorValue_hPa, float elevationChange_m) {
|
public ElevationChange(float currentSensorValue_hPa, float elevationChange_m) {
|
||||||
this.currentSensorValue_hPa = currentSensorValue_hPa;
|
this.currentSensorValue_hPa = currentSensorValue_hPa;
|
||||||
|
|||||||
@@ -118,6 +118,34 @@ public class StringUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatSpeed(Context context, double speed_mps, boolean metricUnits, boolean reportSpeed) {
|
||||||
|
if (Double.isNaN(speed_mps) || Double.isInfinite(speed_mps)) {
|
||||||
|
speed_mps = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double speed = speed_mps * UnitConversions.M_TO_KM; //KM p sec
|
||||||
|
if (!metricUnits) {
|
||||||
|
speed *= UnitConversions.KM_TO_MI;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reportSpeed) {
|
||||||
|
if (metricUnits) {
|
||||||
|
return context.getString(R.string.value_float_kilometer_hour, speed * UnitConversions.S_TO_HR);
|
||||||
|
} else {
|
||||||
|
return context.getString(R.string.value_float_mile_hour, speed * UnitConversions.S_TO_HR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int pace = speed == 0 ? 0 : (int) Math.round(1 / speed); //sec / [KM | MI]
|
||||||
|
int minutes = pace / 60;
|
||||||
|
int seconds = pace % 60;
|
||||||
|
if (metricUnits) {
|
||||||
|
return context.getString(R.string.value_pace_kilometer, minutes, seconds);
|
||||||
|
} else {
|
||||||
|
return context.getString(R.string.value_pace_mile, minutes, seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String formatDecimal(double value) {
|
private static String formatDecimal(double value) {
|
||||||
return StringUtils.formatDecimal(value, 2);
|
return StringUtils.formatDecimal(value, 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package de.dennisguse.opentracks.util;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.R;
|
||||||
|
|
||||||
public class ThemeUtils {
|
public class ThemeUtils {
|
||||||
|
|
||||||
private ThemeUtils() {
|
private ThemeUtils() {
|
||||||
@@ -37,4 +40,18 @@ public class ThemeUtils {
|
|||||||
|
|
||||||
return ContextCompat.getColor(context, typedValue.resourceId);
|
return ContextCompat.getColor(context, typedValue.resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getFontSizeSmallInPx(Context context) {
|
||||||
|
TypedArray typedArray = context.obtainStyledAttributes(R.style.TextSmall, new int[]{android.R.attr.textSize});
|
||||||
|
int fontSize = typedArray.getDimensionPixelSize(0, 12);
|
||||||
|
typedArray.recycle();
|
||||||
|
return fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getFontSizeMediumInPx(Context context) {
|
||||||
|
TypedArray typedArray = context.obtainStyledAttributes(R.style.TextMedium, new int[]{android.R.attr.textSize});
|
||||||
|
int fontSize = typedArray.getDimensionPixelSize(0, 15);
|
||||||
|
typedArray.recycle();
|
||||||
|
return fontSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import de.dennisguse.opentracks.util.LocationUtils;
|
|||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
|
|
||||||
public class IntervalStatistics {
|
public class IntervalStatistics {
|
||||||
private List<Interval> intervalList = new ArrayList<>();
|
private final List<Interval> intervalList = new ArrayList<>();
|
||||||
private float distanceInterval_m;
|
private float distanceInterval_m;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ limitations under the License.
|
|||||||
android:id="@+id/track_controller_container"
|
android:id="@+id/track_controller_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/track_controller_background_normal"
|
android:background="@drawable/track_controller_background"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingRight="8dp">
|
android:paddingEnd="8dp">
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/track_controller_record"
|
android:id="@+id/track_controller_record"
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ limitations under the License.
|
|||||||
android:id="@+id/track_list_arrow_long"
|
android:id="@+id/track_list_arrow_long"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentStart="true"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="12dp"
|
android:paddingStart="12dp"
|
||||||
android:paddingRight="16dp">
|
android:paddingEnd="16dp">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -73,7 +73,7 @@ limitations under the License.
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_toRightOf="@id/track_list_arrow_long"
|
android:layout_toEndOf="@id/track_list_arrow_long"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/track_detail_activity_view_pager"
|
android:id="@+id/track_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -20,21 +20,18 @@
|
|||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/TextLarge"
|
style="@style/TextLarge"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="4"
|
|
||||||
android:gravity="center_horizontal|center_vertical"
|
android:gravity="center_horizontal|center_vertical"
|
||||||
android:text="@string/aggregated_stats_empty_message" />
|
android:text="@string/aggregated_stats_empty_message" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" />
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,9 @@
|
|||||||
android:id="@+id/aggregated_stats_sport_icon"
|
android:id="@+id/aggregated_stats_sport_icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
app:layout_constraintLeft_toLeftOf="@id/guideline1"
|
app:layout_constraintStart_toStartOf="@id/guideline1"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/ic_activity_bike_24dp" />
|
app:srcCompat="@drawable/ic_activity_bike_24dp" />
|
||||||
|
|
||||||
@@ -45,10 +45,10 @@
|
|||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="0dp"
|
||||||
android:layout_marginBottom="0dp"
|
android:layout_marginBottom="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_sport_icon"
|
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_sport_icon"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_sport_icon"
|
app:layout_constraintStart_toEndOf="@+id/aggregated_stats_sport_icon"
|
||||||
app:layout_constraintTop_toTopOf="@+id/aggregated_stats_sport_icon"
|
app:layout_constraintTop_toTopOf="@+id/aggregated_stats_sport_icon"
|
||||||
tools:text="@string/activity_type_cycling"
|
tools:text="@string/activity_type_cycling"
|
||||||
android:layout_marginLeft="16dp" />
|
android:layout_marginStart="16dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/aggregated_stats_num_tracks"
|
android:id="@+id/aggregated_stats_num_tracks"
|
||||||
@@ -56,36 +56,36 @@
|
|||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="0dp"
|
||||||
android:layout_marginBottom="0dp"
|
android:layout_marginBottom="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_type_label"
|
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_type_label"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_type_label"
|
app:layout_constraintStart_toEndOf="@+id/aggregated_stats_type_label"
|
||||||
app:layout_constraintTop_toTopOf="@+id/aggregated_stats_type_label"
|
app:layout_constraintTop_toTopOf="@+id/aggregated_stats_type_label"
|
||||||
tools:text="(1)"
|
tools:text="(1)"
|
||||||
android:layout_marginLeft="4dp" />
|
android:layout_marginStart="4dp" />
|
||||||
|
|
||||||
<!-- Distance -->
|
<!-- Distance -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/aggregated_stats_distance"
|
android:id="@+id/aggregated_stats_distance"
|
||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
app:layout_constraintLeft_toLeftOf="@id/guideline1"
|
app:layout_constraintStart_toStartOf="@id/guideline1"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_sport_icon"
|
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_sport_icon"
|
||||||
tools:text="100000"
|
tools:text="100000"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp" />
|
android:layout_marginTop="16dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/aggregated_stats_distance_unit"
|
android:id="@+id/aggregated_stats_distance_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_distance"
|
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_distance"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_distance"
|
app:layout_constraintStart_toEndOf="@+id/aggregated_stats_distance"
|
||||||
tools:text="km" />
|
tools:text="km" />
|
||||||
|
|
||||||
<!-- Time -->
|
<!-- Time -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/aggregated_stats_time"
|
android:id="@+id/aggregated_stats_time"
|
||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
app:layout_constraintRight_toRightOf="@id/guideline3"
|
app:layout_constraintEnd_toEndOf="@id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_sport_icon"
|
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_sport_icon"
|
||||||
tools:text="00:00:00"
|
tools:text="00:00:00"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginTop="16dp" />
|
android:layout_marginTop="16dp" />
|
||||||
|
|
||||||
<!-- Avg. rate -->
|
<!-- Avg. rate -->
|
||||||
@@ -94,8 +94,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_distance"
|
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_distance"
|
||||||
app:layout_constraintLeft_toRightOf="@id/guideline1"
|
app:layout_constraintStart_toEndOf="@id/guideline1"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/aggregated_stats_avg_rate_unit"
|
app:layout_constraintEnd_toStartOf="@+id/aggregated_stats_avg_rate_unit"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
tools:text="30" />
|
tools:text="30" />
|
||||||
|
|
||||||
@@ -103,8 +103,8 @@
|
|||||||
android:id="@+id/aggregated_stats_avg_rate_unit"
|
android:id="@+id/aggregated_stats_avg_rate_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_avg_rate"
|
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_avg_rate"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_avg_rate"
|
app:layout_constraintStart_toEndOf="@+id/aggregated_stats_avg_rate"
|
||||||
app:layout_constraintRight_toRightOf="@id/guideline2"
|
app:layout_constraintEnd_toEndOf="@id/guideline2"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -112,8 +112,8 @@
|
|||||||
style="@style/StatsTinyLabel"
|
style="@style/StatsTinyLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_avg_rate"
|
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_avg_rate"
|
||||||
app:layout_constraintLeft_toRightOf="@id/guideline1"
|
app:layout_constraintStart_toEndOf="@id/guideline1"
|
||||||
app:layout_constraintRight_toRightOf="@id/guideline2"
|
app:layout_constraintEnd_toEndOf="@id/guideline2"
|
||||||
tools:text="@string/stats_average_moving_speed" />
|
tools:text="@string/stats_average_moving_speed" />
|
||||||
|
|
||||||
<!-- Max. rate -->
|
<!-- Max. rate -->
|
||||||
@@ -122,8 +122,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_time"
|
app:layout_constraintTop_toBottomOf="@id/aggregated_stats_time"
|
||||||
app:layout_constraintLeft_toRightOf="@id/guideline2"
|
app:layout_constraintStart_toEndOf="@id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/aggregated_stats_max_rate_unit"
|
app:layout_constraintEnd_toStartOf="@+id/aggregated_stats_max_rate_unit"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
tools:text="70" />
|
tools:text="70" />
|
||||||
|
|
||||||
@@ -131,8 +131,8 @@
|
|||||||
android:id="@+id/aggregated_stats_max_rate_unit"
|
android:id="@+id/aggregated_stats_max_rate_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_max_rate"
|
app:layout_constraintBottom_toBottomOf="@+id/aggregated_stats_max_rate"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/aggregated_stats_max_rate"
|
app:layout_constraintStart_toEndOf="@+id/aggregated_stats_max_rate"
|
||||||
app:layout_constraintRight_toLeftOf="@id/guideline3"
|
app:layout_constraintEnd_toStartOf="@id/guideline3"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -140,8 +140,8 @@
|
|||||||
style="@style/StatsTinyLabel"
|
style="@style/StatsTinyLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_max_rate"
|
app:layout_constraintTop_toBottomOf="@+id/aggregated_stats_max_rate"
|
||||||
app:layout_constraintLeft_toRightOf="@id/guideline2"
|
app:layout_constraintStart_toEndOf="@id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@id/guideline3"
|
app:layout_constraintEnd_toStartOf="@id/guideline3"
|
||||||
tools:text="@string/stats_max_speed" />
|
tools:text="@string/stats_max_speed" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="0dp">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
@@ -62,9 +62,9 @@
|
|||||||
style="@style/ProgressBar"
|
style="@style/ProgressBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="24dp"
|
android:layout_marginStart="24dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginRight="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/export_progress_done"
|
app:layout_constraintTop_toBottomOf="@id/export_progress_done"
|
||||||
@@ -113,8 +113,8 @@
|
|||||||
android:id="@+id/export_progress_apply_to_all"
|
android:id="@+id/export_progress_apply_to_all"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="24dp"
|
android:layout_marginStart="24dp"
|
||||||
android:layout_marginRight="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:checked="false"
|
android:checked="false"
|
||||||
android:text="@string/export_all_do_it_for_all"
|
android:text="@string/export_all_do_it_for_all"
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
<Button
|
<Button
|
||||||
android:id="@+id/export_progress_right_button"
|
android:id="@+id/export_progress_right_button"
|
||||||
style="@style/BottomButton"
|
style="@style/BottomButton"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/generic_overwrite"
|
android:text="@string/generic_overwrite"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="0dp">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
@@ -60,9 +60,9 @@
|
|||||||
style="@style/ProgressBar"
|
style="@style/ProgressBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="24dp"
|
android:layout_marginStart="24dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginRight="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/import_progress_done"
|
app:layout_constraintTop_toBottomOf="@id/import_progress_done"
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
<Button
|
<Button
|
||||||
android:id="@+id/import_progress_right_button"
|
android:id="@+id/import_progress_right_button"
|
||||||
style="@style/BottomButton"
|
style="@style/BottomButton"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/generic_ok"
|
android:text="@string/generic_ok"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_margin="8dp">
|
android:layout_marginEnd="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
style="@style/TextMediumPrimary"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/stats_split_interval"
|
android:text="@string/stats_split_interval" />
|
||||||
style="@style/TextMedium" />
|
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/spinner_intervals"
|
android:id="@+id/spinner_intervals"
|
||||||
@@ -28,56 +29,39 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_margin="8dp">
|
android:layout_marginEnd="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_distance"
|
android:id="@+id/interval_distance"
|
||||||
android:layout_width="0dp"
|
style="@style/IntervalLabel"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
style="@style/TextMedium"
|
|
||||||
android:layout_margin="1dp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:text="@string/stats_distance" />
|
android:text="@string/stats_distance" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_rate"
|
android:id="@+id/interval_rate"
|
||||||
android:layout_width="0dp"
|
style="@style/IntervalLabel"
|
||||||
android:layout_height="wrap_content"
|
tools:text="Speed" />
|
||||||
android:layout_weight="1"
|
|
||||||
style="@style/TextMedium"
|
|
||||||
android:layout_margin="1dp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
tools:text="Speed"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_elevation"
|
android:id="@+id/interval_elevation"
|
||||||
android:layout_width="0dp"
|
style="@style/IntervalLabel"
|
||||||
android:layout_height="wrap_content"
|
android:text="@string/stats_gain" />
|
||||||
android:layout_weight="1"
|
|
||||||
style="@style/TextMedium"
|
|
||||||
android:layout_margin="1dp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:text="@string/stats_elevation" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:background="@color/stats_separator"/>
|
android:background="@color/stats_separator" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/interval_list"
|
android:id="@+id/interval_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8dp"/>
|
android:layout_margin="8dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_list_empty_view"
|
android:id="@+id/interval_list_empty_view"
|
||||||
|
|||||||
@@ -1,47 +1,31 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_item_distance"
|
android:id="@+id/interval_item_distance"
|
||||||
android:layout_width="0dp"
|
style="@style/TextMedium"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_gravity="center_vertical"
|
tools:text="1 km" />
|
||||||
style="@style/TextMedium"
|
|
||||||
tools:text="1 km" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/interval_item_rate"
|
android:id="@+id/interval_item_rate"
|
||||||
android:layout_width="0dp"
|
style="@style/TextMedium"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_gravity="center_vertical"
|
tools:text="15 km/h" />
|
||||||
style="@style/TextMedium"
|
|
||||||
tools:text="15 km/h" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:layout_width="0dp"
|
android:id="@+id/interval_item_gain"
|
||||||
android:layout_height="wrap_content"
|
style="@style/TextMedium"
|
||||||
android:layout_weight="1"
|
android:layout_width="0dp"
|
||||||
android:orientation="horizontal">
|
android:layout_weight="1"
|
||||||
|
app:drawableStartCompat="@drawable/ic_arrow_drop_up_24"
|
||||||
<ImageView
|
tools:text="100 m" />
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/ic_arrow_drop_up_24" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/interval_item_gain"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
style="@style/TextMedium"
|
|
||||||
tools:text="100 m" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -44,7 +44,8 @@ limitations under the License.
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingRight="12dp"
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
android:paddingBottom="12dp"
|
android:paddingBottom="12dp"
|
||||||
android:shrinkColumns="1"
|
android:shrinkColumns="1"
|
||||||
android:stretchColumns="1">
|
android:stretchColumns="1">
|
||||||
@@ -56,8 +57,8 @@ limitations under the License.
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginStart="4dp"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:contentDescription="@string/image_track"
|
android:contentDescription="@string/image_track"
|
||||||
app:tint="?android:textColorPrimary" />
|
app:tint="?android:textColorPrimary" />
|
||||||
<!-- Table 1: Row 1: Column 2: (Table 2) -->
|
<!-- Table 1: Row 1: Column 2: (Table 2) -->
|
||||||
@@ -105,8 +106,8 @@ limitations under the License.
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:layout_marginLeft="2dp"
|
android:layout_marginStart="2dp"
|
||||||
android:layout_marginRight="2dp"
|
android:layout_marginEnd="2dp"
|
||||||
android:layout_marginBottom="1dp"
|
android:layout_marginBottom="1dp"
|
||||||
android:contentDescription="@string/image_marker_count"
|
android:contentDescription="@string/image_marker_count"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="centerInside"
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ limitations under the License.
|
|||||||
<Button
|
<Button
|
||||||
android:id="@+id/marker_edit_cancel"
|
android:id="@+id/marker_edit_cancel"
|
||||||
style="@style/BottomButton"
|
style="@style/BottomButton"
|
||||||
android:layout_gravity="left"
|
android:layout_gravity="start"
|
||||||
android:text="@string/generic_cancel" />
|
android:text="@string/generic_cancel" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/marker_edit_done"
|
android:id="@+id/marker_edit_done"
|
||||||
style="@style/BottomButton"
|
style="@style/BottomButton"
|
||||||
android:layout_gravity="right" />
|
android:layout_gravity="end" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -19,9 +19,9 @@ limitations under the License.
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
android:paddingRight="8dp">
|
android:paddingEnd="8dp">
|
||||||
|
|
||||||
<AutoCompleteTextView
|
<AutoCompleteTextView
|
||||||
android:id="@+id/activity_type_preference_text_view"
|
android:id="@+id/activity_type_preference_text_view"
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/stats_distance"
|
android:text="@string/stats_distance"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_distance_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_distance_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_distance_label"
|
||||||
tools:text="100" />
|
tools:text="100" />
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@
|
|||||||
android:id="@+id/stats_distance_unit"
|
android:id="@+id/stats_distance_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_distance_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_distance_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
tools:text="km" />
|
tools:text="km" />
|
||||||
|
|
||||||
<!-- Activity Type -->
|
<!-- Activity Type -->
|
||||||
@@ -64,16 +64,16 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/track_edit_activity_type_hint"
|
android:text="@string/track_edit_activity_type_hint"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/stats_activity_type_icon"
|
android:id="@+id/stats_activity_type_icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||||
app:layout_constraintTop_toTopOf="@+id/stats_distance_value"
|
app:layout_constraintTop_toTopOf="@+id/stats_distance_value"
|
||||||
app:tint="?android:attr/textColorPrimary"
|
app:tint="?android:attr/textColorPrimary"
|
||||||
@@ -85,15 +85,15 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/stats_total_time"
|
android:text="@string/stats_total_time"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/stats_total_time_value"
|
android:id="@+id/stats_total_time_value"
|
||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_total_time_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_total_time_label"
|
||||||
tools:text="00:00:00" />
|
tools:text="00:00:00" />
|
||||||
|
|
||||||
@@ -103,8 +103,8 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/stats_moving_time"
|
android:text="@string/stats_moving_time"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toTopOf="@+id/stats_total_time_label"
|
app:layout_constraintTop_toTopOf="@+id/stats_total_time_label"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" />
|
app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" />
|
||||||
|
|
||||||
@@ -112,8 +112,8 @@
|
|||||||
android:id="@+id/stats_moving_time_value"
|
android:id="@+id/stats_moving_time_value"
|
||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_label"
|
||||||
tools:text="00:00:00" />
|
tools:text="00:00:00" />
|
||||||
|
|
||||||
@@ -130,8 +130,8 @@
|
|||||||
android:id="@+id/stats_speed_horizontal_line"
|
android:id="@+id/stats_speed_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_time_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_time_barrier" />
|
||||||
|
|
||||||
<!-- Average speed/pace -->
|
<!-- Average speed/pace -->
|
||||||
@@ -139,8 +139,8 @@
|
|||||||
android:id="@+id/stats_average_speed_label"
|
android:id="@+id/stats_average_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
||||||
tools:text="Avg. Speed" />
|
tools:text="Avg. Speed" />
|
||||||
|
|
||||||
@@ -149,8 +149,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_average_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_average_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -158,8 +158,8 @@
|
|||||||
android:id="@+id/stats_average_speed_unit"
|
android:id="@+id/stats_average_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_average_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_average_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_average_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_average_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Speed max -->
|
<!-- Speed max -->
|
||||||
@@ -167,8 +167,8 @@
|
|||||||
android:id="@+id/stats_max_speed_label"
|
android:id="@+id/stats_max_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||||
tools:text="Max. Speed" />
|
tools:text="Max. Speed" />
|
||||||
|
|
||||||
@@ -177,8 +177,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_max_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_max_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -186,8 +186,8 @@
|
|||||||
android:id="@+id/stats_max_speed_unit"
|
android:id="@+id/stats_max_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_max_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_max_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_max_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_max_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Moving speed max -->
|
<!-- Moving speed max -->
|
||||||
@@ -195,8 +195,8 @@
|
|||||||
android:id="@+id/stats_moving_speed_label"
|
android:id="@+id/stats_moving_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||||
tools:text="Max. Moving Speed" />
|
tools:text="Max. Moving Speed" />
|
||||||
|
|
||||||
@@ -205,8 +205,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_moving_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_moving_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -214,8 +214,8 @@
|
|||||||
android:id="@+id/stats_moving_speed_unit"
|
android:id="@+id/stats_moving_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_moving_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_moving_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_moving_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_moving_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Barrier -->
|
<!-- Barrier -->
|
||||||
@@ -231,8 +231,8 @@
|
|||||||
android:id="@+id/stats_elevation_horizontal_line"
|
android:id="@+id/stats_elevation_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_speed_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_speed_barrier" />
|
||||||
|
|
||||||
<!-- Elevation gain -->
|
<!-- Elevation gain -->
|
||||||
@@ -247,8 +247,8 @@
|
|||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
android:text="@string/stats_gain"
|
android:text="@string/stats_gain"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -256,8 +256,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_elevation_gain_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_elevation_gain_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_gain_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_gain_label"
|
||||||
tools:text="100" />
|
tools:text="100" />
|
||||||
|
|
||||||
@@ -265,8 +265,8 @@
|
|||||||
android:id="@+id/stats_elevation_gain_unit"
|
android:id="@+id/stats_elevation_gain_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_gain_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_gain_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_elevation_gain_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_elevation_gain_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
tools:text="m" />
|
tools:text="m" />
|
||||||
|
|
||||||
<!-- Barrier -->
|
<!-- Barrier -->
|
||||||
@@ -282,8 +282,8 @@
|
|||||||
android:id="@+id/stats_end_horizontal_line"
|
android:id="@+id/stats_end_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_barrier" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/stats_distance"
|
android:text="@string/stats_distance"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_distance_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_distance_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_distance_label"
|
||||||
tools:text="100" />
|
tools:text="100" />
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@
|
|||||||
android:id="@+id/stats_distance_unit"
|
android:id="@+id/stats_distance_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_distance_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_distance_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
tools:text="km" />
|
tools:text="km" />
|
||||||
|
|
||||||
<!-- Activity Type -->
|
<!-- Activity Type -->
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/track_edit_activity_type_hint"
|
android:text="@string/track_edit_activity_type_hint"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@@ -73,8 +73,8 @@
|
|||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_distance_value"
|
||||||
app:layout_constraintTop_toTopOf="@+id/stats_distance_value" />
|
app:layout_constraintTop_toTopOf="@+id/stats_distance_value" />
|
||||||
|
|
||||||
@@ -84,15 +84,15 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/stats_total_time"
|
android:text="@string/stats_total_time"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_distance_value" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/stats_total_time_value"
|
android:id="@+id/stats_total_time_value"
|
||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_total_time_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_total_time_label"
|
||||||
tools:text="00:00:00" />
|
tools:text="00:00:00" />
|
||||||
|
|
||||||
@@ -102,8 +102,8 @@
|
|||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/stats_moving_time"
|
android:text="@string/stats_moving_time"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toTopOf="@+id/stats_total_time_label"
|
app:layout_constraintTop_toTopOf="@+id/stats_total_time_label"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" />
|
app:layout_constraintBottom_toBottomOf="@+id/stats_total_time_label" />
|
||||||
|
|
||||||
@@ -111,8 +111,8 @@
|
|||||||
android:id="@+id/stats_moving_time_value"
|
android:id="@+id/stats_moving_time_value"
|
||||||
style="@style/StatsLargeValue"
|
style="@style/StatsLargeValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_moving_time_label"
|
||||||
tools:text="00:00:00" />
|
tools:text="00:00:00" />
|
||||||
|
|
||||||
@@ -129,8 +129,8 @@
|
|||||||
android:id="@+id/stats_speed_horizontal_line"
|
android:id="@+id/stats_speed_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_time_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_time_barrier" />
|
||||||
|
|
||||||
<!-- Speed/pace -->
|
<!-- Speed/pace -->
|
||||||
@@ -138,8 +138,8 @@
|
|||||||
android:id="@+id/stats_speed_label"
|
android:id="@+id/stats_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
||||||
tools:text="Speed" />
|
tools:text="Speed" />
|
||||||
|
|
||||||
@@ -148,8 +148,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -157,8 +157,8 @@
|
|||||||
android:id="@+id/stats_speed_unit"
|
android:id="@+id/stats_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Average speed/pace -->
|
<!-- Average speed/pace -->
|
||||||
@@ -166,8 +166,8 @@
|
|||||||
android:id="@+id/stats_average_speed_label"
|
android:id="@+id/stats_average_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
app:layout_constraintTop_toBottomOf="@id/stats_speed_horizontal_line"
|
||||||
tools:text="Avg. Speed" />
|
tools:text="Avg. Speed" />
|
||||||
|
|
||||||
@@ -176,8 +176,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_average_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_average_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_average_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -185,8 +185,8 @@
|
|||||||
android:id="@+id/stats_average_speed_unit"
|
android:id="@+id/stats_average_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_average_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_average_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_average_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_average_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Speed max -->
|
<!-- Speed max -->
|
||||||
@@ -194,8 +194,8 @@
|
|||||||
android:id="@+id/stats_max_speed_label"
|
android:id="@+id/stats_max_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||||
tools:text="Max. Speed" />
|
tools:text="Max. Speed" />
|
||||||
|
|
||||||
@@ -204,8 +204,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_max_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_max_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -213,8 +213,8 @@
|
|||||||
android:id="@+id/stats_max_speed_unit"
|
android:id="@+id/stats_max_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_max_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_max_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_max_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_max_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Moving speed max -->
|
<!-- Moving speed max -->
|
||||||
@@ -222,8 +222,8 @@
|
|||||||
android:id="@+id/stats_moving_speed_label"
|
android:id="@+id/stats_moving_speed_label"
|
||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
app:layout_constraintTop_toBottomOf="@id/stats_average_speed_value"
|
||||||
tools:text="Max. Moving Speed" />
|
tools:text="Max. Moving Speed" />
|
||||||
|
|
||||||
@@ -232,8 +232,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_moving_speed_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_moving_speed_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_moving_speed_label"
|
||||||
tools:text="30.00" />
|
tools:text="30.00" />
|
||||||
|
|
||||||
@@ -241,8 +241,8 @@
|
|||||||
android:id="@+id/stats_moving_speed_unit"
|
android:id="@+id/stats_moving_speed_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_moving_speed_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_moving_speed_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_moving_speed_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_moving_speed_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
tools:text="km/h" />
|
tools:text="km/h" />
|
||||||
|
|
||||||
<!-- Barrier -->
|
<!-- Barrier -->
|
||||||
@@ -258,8 +258,8 @@
|
|||||||
android:id="@+id/stats_elevation_horizontal_line"
|
android:id="@+id/stats_elevation_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_speed_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_speed_barrier" />
|
||||||
|
|
||||||
<!-- Elevation -->
|
<!-- Elevation -->
|
||||||
@@ -275,8 +275,8 @@
|
|||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
android:text="@string/stats_elevation"
|
android:text="@string/stats_elevation"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -284,8 +284,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_elevation_current_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_elevation_current_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_current_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_current_label"
|
||||||
tools:text="100" />
|
tools:text="100" />
|
||||||
|
|
||||||
@@ -293,8 +293,8 @@
|
|||||||
android:id="@+id/stats_elevation_current_unit"
|
android:id="@+id/stats_elevation_current_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_current_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_current_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_elevation_current_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_elevation_current_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
tools:text="m" />
|
tools:text="m" />
|
||||||
|
|
||||||
<!-- Current elevation -->
|
<!-- Current elevation -->
|
||||||
@@ -303,8 +303,8 @@
|
|||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
android:text="@string/stats_gain"
|
android:text="@string/stats_gain"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_elevation_horizontal_line" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -312,8 +312,8 @@
|
|||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/stats_elevation_gain_unit"
|
app:layout_constraintEnd_toStartOf="@+id/stats_elevation_gain_unit"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_gain_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_gain_label"
|
||||||
tools:text="100" />
|
tools:text="100" />
|
||||||
|
|
||||||
@@ -321,8 +321,8 @@
|
|||||||
android:id="@+id/stats_elevation_gain_unit"
|
android:id="@+id/stats_elevation_gain_unit"
|
||||||
style="@style/StatsUnit"
|
style="@style/StatsUnit"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_gain_value"
|
app:layout_constraintBottom_toBottomOf="@+id/stats_elevation_gain_value"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/stats_elevation_gain_value"
|
app:layout_constraintStart_toEndOf="@+id/stats_elevation_gain_value"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
tools:text="m" />
|
tools:text="m" />
|
||||||
|
|
||||||
<!-- Coordinate group -->
|
<!-- Coordinate group -->
|
||||||
@@ -345,8 +345,8 @@
|
|||||||
android:id="@+id/stats_coordinate_horizontal_line"
|
android:id="@+id/stats_coordinate_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_elevation_barrier" />
|
||||||
|
|
||||||
<!-- Latitude -->
|
<!-- Latitude -->
|
||||||
@@ -355,15 +355,15 @@
|
|||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
android:text="@string/stats_latitude"
|
android:text="@string/stats_latitude"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/stats_latitude_value"
|
android:id="@+id/stats_latitude_value"
|
||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline2"
|
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_latitude_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_latitude_label"
|
||||||
tools:text="0.834937848" />
|
tools:text="0.834937848" />
|
||||||
|
|
||||||
@@ -373,16 +373,16 @@
|
|||||||
style="@style/StatsSmallLabel"
|
style="@style/StatsSmallLabel"
|
||||||
android:text="@string/stats_longitude"
|
android:text="@string/stats_longitude"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_coordinate_horizontal_line" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/stats_longitude_value"
|
android:id="@+id/stats_longitude_value"
|
||||||
style="@style/StatsSmallValue"
|
style="@style/StatsSmallValue"
|
||||||
android:value="@string/value_unknown"
|
android:value="@string/value_unknown"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline2"
|
app:layout_constraintStart_toEndOf="@+id/guideline2"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_longitude_label"
|
app:layout_constraintTop_toBottomOf="@+id/stats_longitude_label"
|
||||||
tools:text="0.834937848" />
|
tools:text="0.834937848" />
|
||||||
|
|
||||||
@@ -399,8 +399,8 @@
|
|||||||
android:id="@+id/stats_sensor_horizontal_line"
|
android:id="@+id/stats_sensor_horizontal_line"
|
||||||
style="@style/StatsHorizontalLine"
|
style="@style/StatsHorizontalLine"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/stats_location_barrier" />
|
app:layout_constraintTop_toBottomOf="@+id/stats_location_barrier" />
|
||||||
|
|
||||||
<!-- Sensors data -->
|
<!-- Sensors data -->
|
||||||
@@ -408,8 +408,8 @@
|
|||||||
android:id="@+id/stats_sensors_recycler_view"
|
android:id="@+id/stats_sensors_recycler_view"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintLeft_toRightOf="@+id/guideline"
|
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/guideline3"
|
app:layout_constraintEnd_toStartOf="@+id/guideline3"
|
||||||
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
app:layout_constraintTop_toBottomOf="@id/stats_sensor_horizontal_line" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ limitations under the License.
|
|||||||
<Button
|
<Button
|
||||||
android:id="@+id/track_edit_cancel"
|
android:id="@+id/track_edit_cancel"
|
||||||
style="@style/BottomButton"
|
style="@style/BottomButton"
|
||||||
android:layout_gravity="left"
|
android:layout_gravity="start"
|
||||||
android:text="@string/generic_cancel" />
|
android:text="@string/generic_cancel" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/track_edit_save"
|
android:id="@+id/track_edit_save"
|
||||||
style="@style/BottomButton"
|
style="@style/BottomButton"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:text="@string/generic_save" />
|
android:text="@string/generic_save" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -73,7 +73,7 @@ limitations under the License.
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="22"
|
android:layout_weight="22"
|
||||||
android:gravity="left"
|
android:gravity="start"
|
||||||
android:text="@string/track_list_empty_message" />
|
android:text="@string/track_list_empty_message" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ limitations under the License.
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/track_detail_activity_view_pager"
|
android:id="@+id/track_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/track_detail_activity_view_pager"
|
android:id="@+id/track_detail_activity_view_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ limitations under the License.
|
|||||||
a)
|
a)
|
||||||
(live updates) Install <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>.
|
(live updates) Install <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>.
|
||||||
It provides online or offline maps via <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n
|
It provides online or offline maps via <a href="https://www.openstreetmap.org">OpenStreetMap</a>.\n
|
||||||
Actually, OSMDashboard is a separate app that only can access (temporarily) access the data of track(s) that are going to be shown.
|
Actually, OSMDashboard is a separate app that only can access (temporarily) the data of track(s) that are going to be shown.
|
||||||
|
|
||||||
\n
|
\n
|
||||||
b)
|
b)
|
||||||
Via a "normal" map application (e.g., <a href="http://osmand.net/">OsmAnd</a> and <a href="https://maps.me/">MAPS.ME</a>).
|
Via a "normal" map application (e.g., <a href="http://osmand.net/">OsmAnd</a> and <a href="https://maps.me/">MAPS.ME</a>).
|
||||||
Those app need to support the KMZ file format (only locations and timestamps).
|
These apps need to support the KMZ file format (only locations and timestamps).
|
||||||
In fact, an app needs to support <i>ACTION_VIEW</i> with MIME <i>application/vnd.google-earth.kmz</i>.
|
In fact, an app needs to support <i>ACTION_VIEW</i> with MIME <i>application/vnd.google-earth.kmz</i>.
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ limitations under the License.
|
|||||||
What you can do:\n
|
What you can do:\n
|
||||||
a) check if GPS is enabled,\n
|
a) check if GPS is enabled,\n
|
||||||
b) improve GPS reception (e.g., go outdoors),\n
|
b) improve GPS reception (e.g., go outdoors),\n
|
||||||
c) check if with <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/">GPSTest</a> app, and\n
|
c) check with <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/">GPSTest</a> app, and\n
|
||||||
d) disable power saving.\n
|
d) disable power saving.\n
|
||||||
\n
|
\n
|
||||||
If everything does not help please report a bug.
|
If everything does not help please report a bug.
|
||||||
@@ -290,10 +290,12 @@ limitations under the License.
|
|||||||
<string name="import_unsupported_format">Unsupported file format</string>
|
<string name="import_unsupported_format">Unsupported file format</string>
|
||||||
<string name="import_parser_error">Parser error: %1$s</string>
|
<string name="import_parser_error">Parser error: %1$s</string>
|
||||||
<string name="import_unable_to_import_file">Unable to import file: %1$s</string>
|
<string name="import_unable_to_import_file">Unable to import file: %1$s</string>
|
||||||
|
<string name="import_no_kml_file_found">No doc.kml file found in KMZ</string>
|
||||||
<string name="import_error_info">%1$s: %2$s</string>
|
<string name="import_error_info">%1$s: %2$s</string>
|
||||||
<string name="import_error_list_dialog_title">Files not imported</string>
|
<string name="import_error_list_dialog_title">Files not imported</string>
|
||||||
<string name="import_file_imported">File %1$s imported</string>
|
<string name="import_file_imported">File %1$s imported</string>
|
||||||
<string name="import_error">Imported %1$d of %2$s from %3$s</string>
|
<string name="import_error">Imported %1$d of %2$s from %3$s</string>
|
||||||
|
<string name="import_prevent_reimport">You have set prevent re-import track</string>
|
||||||
<string name="import_no_directory">%1$s does not exist</string>
|
<string name="import_no_directory">%1$s does not exist</string>
|
||||||
<string name="import_no_file">There were no files to import. Connect your device to your computer and place the files to import in %1$s.</string>
|
<string name="import_no_file">There were no files to import. Connect your device to your computer and place the files to import in %1$s.</string>
|
||||||
<string name="import_no_file_title">Import files</string>
|
<string name="import_no_file_title">Import files</string>
|
||||||
@@ -507,8 +509,11 @@ limitations under the License.
|
|||||||
<string name="value_always">Always</string>
|
<string name="value_always">Always</string>
|
||||||
<string name="value_float_feet">%1$.2f ft</string>
|
<string name="value_float_feet">%1$.2f ft</string>
|
||||||
<string name="value_float_kilometer">%1$.2f km</string>
|
<string name="value_float_kilometer">%1$.2f km</string>
|
||||||
|
<string name="value_float_kilometer_hour">%1$.2f km/h</string>
|
||||||
<string name="value_float_meter">%1$.2f m</string>
|
<string name="value_float_meter">%1$.2f m</string>
|
||||||
<string name="value_float_mile">%1$.2f mi</string>
|
<string name="value_float_mile">%1$.2f mi</string>
|
||||||
|
<string name="value_float_mile_hour">%1$.2f mph</string>
|
||||||
|
|
||||||
<string name="value_float_mile_poor_gps">%1$.1f mi (poor GPS)</string>
|
<string name="value_float_mile_poor_gps">%1$.1f mi (poor GPS)</string>
|
||||||
<string name="value_integer_feet">%1$d ft</string>
|
<string name="value_integer_feet">%1$d ft</string>
|
||||||
<string name="value_integer_feet_excellent_gps">%1$d ft (excellent GPS)</string>
|
<string name="value_integer_feet_excellent_gps">%1$d ft (excellent GPS)</string>
|
||||||
@@ -524,6 +529,8 @@ limitations under the License.
|
|||||||
<string name="value_integer_minute">%1$d min</string>
|
<string name="value_integer_minute">%1$d min</string>
|
||||||
<string name="value_integer_percent">%1$d %%</string>
|
<string name="value_integer_percent">%1$d %%</string>
|
||||||
<string name="value_integer_second">%1$d s</string>
|
<string name="value_integer_second">%1$d s</string>
|
||||||
|
<string name="value_pace_mile">%1$d:%2$02d min/mi</string>
|
||||||
|
<string name="value_pace_kilometer">%1$d:%2$02d min/km</string>
|
||||||
<string name="value_none">None</string>
|
<string name="value_none">None</string>
|
||||||
<string name="value_off">Off</string>
|
<string name="value_off">Off</string>
|
||||||
<string name="value_smallest">Smallest</string>
|
<string name="value_smallest">Smallest</string>
|
||||||
|
|||||||
@@ -117,7 +117,23 @@ limitations under the License.
|
|||||||
<item name="android:paddingTop">6dp</item>
|
<item name="android:paddingTop">6dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="StatsLargeLabel" parent="@style/TextSmall">
|
<style name="LargeLabel" parent="@style/TextSmall">
|
||||||
|
<item name="android:textAllCaps">true</item>
|
||||||
|
<item name="android:textColor">?attr/colorAccent</item>
|
||||||
|
<item name="android:textStyle">bold</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="IntervalLabel" parent="@style/LargeLabel">
|
||||||
|
<item name="android:singleLine">true</item>
|
||||||
|
<item name="android:layout_margin">1dp</item>
|
||||||
|
<item name="android:textAlignment">textStart</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:layout_width">1dp</item>
|
||||||
|
<item name="android:layout_gravity">center</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="StatsLargeLabel" parent="@style/LargeLabel">
|
||||||
<item name="android:gravity">center</item>
|
<item name="android:gravity">center</item>
|
||||||
<item name="android:layout_gravity">center</item>
|
<item name="android:layout_gravity">center</item>
|
||||||
<item name="android:singleLine">false</item>
|
<item name="android:singleLine">false</item>
|
||||||
|
|||||||
@@ -25,16 +25,7 @@ limitations under the License.
|
|||||||
<item name="windowActionModeOverlay">true</item>
|
<item name="windowActionModeOverlay">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ThemeCustomNotTransparentDialog" parent="ThemeCustom">
|
|
||||||
<!-- TODO Remove when moving to settings to fragments. -->
|
|
||||||
<item name="android:windowContentOverlay">@null</item>
|
|
||||||
<item name="android:windowNoTitle">true</item>
|
|
||||||
<item name="android:windowIsFloating">true</item>
|
|
||||||
<item name="android:backgroundDimEnabled">true</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="TrackDeleteActivity" parent="ThemeCustom">
|
<style name="TrackDeleteActivity" parent="ThemeCustom">
|
||||||
<!-- TODO Remove when moving to TrackDeleteActivity to fragments. -->
|
|
||||||
<item name="android:windowIsTranslucent">true</item>
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
<item name="android:windowIsFloating">true</item>
|
<item name="android:windowIsFloating">true</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user