forked from upstream-mirrors/OpenTracks
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5d1e421a4 | |||
| c3b30815c8 | |||
| 5a4919efd2 | |||
| bb549fdc93 | |||
| 73e59cbba2 | |||
| 27727b6dcf | |||
| 06d2957407 | |||
| 8b08af6bcf | |||
| 78dad95ef6 | |||
| be9d56721e | |||
| e5785dd3ac | |||
| 11d912d14d | |||
| 807ac3fc9f |
@@ -111,19 +111,17 @@ The API can be invoked by sending an explicit Intent to start an activity.
|
||||
* **Start a recording:** `de.dennisguse.opentracks.publicapi.StartRecording`
|
||||
* **Stop a recording:** `de.dennisguse.opentracks.publicapi.StopRecording`
|
||||
|
||||
For testing via adb: `adb shell am start -n "package/class"`
|
||||
For testing via adb: `adb shell am start -e someParameter someValue -n "package/class"`
|
||||
|
||||
`StartRecording` supports the following parameters:
|
||||
|
||||
* Set track data: `TRACK_NAME`, `TRACK_CATEGORY`, and `TRACK_DESCRIPTION`
|
||||
* Send recorded data to another application via _Dashboard API_: `STATS_TARGET_PACKAGE`
|
||||
and `STATS_TARGET_CLASS`
|
||||
* Set track data: `TRACK_NAME`, `TRACK_DESCRIPTION`, `TRACK_CATEGORY`, and `TRACK_ICON` (non-localized identifier see [/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38](/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38)).
|
||||
NOTE: if `TRACK_ICON` is not present, `TRACK_CATEGORY` will be used to determine the icon (localized).
|
||||
* Send recorded data to another application via _Dashboard API_: `STATS_TARGET_PACKAGE` and `STATS_TARGET_CLASS`
|
||||
|
||||
The Public API is disabled by default to protect the user's privacy, but it can easily be enabled in
|
||||
the settings.
|
||||
The Public API is disabled by default to protect the user's privacy, but it can easily be enabled in the settings.
|
||||
|
||||
__IMPORTANT__: triggering `StartRecording` does not check if Android permissions (location or
|
||||
Bluetooth) were granted. If they are not granted`
|
||||
__IMPORTANT__: triggering `StartRecording` does not check if Android permissions (location or Bluetooth) were granted. If they are not granted, nothing will be recorded.
|
||||
|
||||
## Dashboard API (incl. map)
|
||||
|
||||
|
||||
+7
-4
@@ -6,7 +6,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
||||
classpath 'com.android.tools.build:gradle:7.3.0-rc01'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "de.dennisguse.opentracks"
|
||||
versionCode 5004
|
||||
versionName "v4.0.7"
|
||||
versionCode 5017
|
||||
versionName "v4.0.8"
|
||||
|
||||
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
||||
|
||||
@@ -81,6 +81,8 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
namespace 'de.dennisguse.opentracks'
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
@@ -118,7 +120,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.5.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1'
|
||||
@@ -127,6 +129,7 @@ dependencies {
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.core:core-splashscreen:1.0.0'
|
||||
|
||||
androidTestImplementation 'androidx.test:core:1.4.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
v4.0.8: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Altitude always shown in m/ft
|
||||
- Show track timezone if different than device timezone
|
||||
- PublicAPI: support setting the track icon explicitly
|
||||
|
||||
Developer:
|
||||
- Introduced DistanceFormatter
|
||||
- Upgrade to AGP 7.3/desugar for Duration.class
|
||||
- Android12+: do splashscreen via Androidx
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -7,6 +7,7 @@ import junit.framework.TestCase;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
@@ -105,7 +106,7 @@ public class TrackSelectionTest extends TestCase {
|
||||
long oneDay = 24 * 60 * 60 * 1000;
|
||||
TrackSelection filterWrong1 = new TrackSelection().addDateRange(instant, null);
|
||||
TrackSelection filterWrong2 = new TrackSelection().addDateRange(null, instant);
|
||||
TrackSelection filterOk = new TrackSelection().addDateRange(instant, instant.plusMillis(oneDay));
|
||||
TrackSelection filterOk = new TrackSelection().addDateRange(instant, instant.plus(Duration.ofDays(1)));
|
||||
|
||||
// when
|
||||
SelectionData selectionWrong1 = filterWrong1.buildSelection();
|
||||
|
||||
+1
-1
@@ -463,7 +463,7 @@ public class ExportImportTest {
|
||||
contentProviderUtils.deleteTrack(context, trackId);
|
||||
|
||||
// then
|
||||
InputStream expected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.csv_export);
|
||||
InputStream expected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.csv_export);
|
||||
String expectedText = new BufferedReader(new InputStreamReader(expected, StandardCharsets.UTF_8))
|
||||
.lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
+5
-5
@@ -69,7 +69,7 @@ public class GPXTrackImporterTest {
|
||||
public void gpx_with_pause_resume() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_gpx_pause_resume);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.legacy_gpx_pause_resume);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
@@ -123,7 +123,7 @@ public class GPXTrackImporterTest {
|
||||
public void gpx_without_speed() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx11_without_speed);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx11_without_speed);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
@@ -171,7 +171,7 @@ public class GPXTrackImporterTest {
|
||||
public void gpx_speed_no_namespace() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx11_with_speed_no_namespace);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx11_with_speed_no_namespace);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
@@ -221,8 +221,8 @@ public class GPXTrackImporterTest {
|
||||
public void importExportTest_timezone() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx_timezone);
|
||||
InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx_timezone);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone);
|
||||
InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone);
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
|
||||
+5
-5
@@ -60,7 +60,7 @@ public class KMLTrackImporterTest {
|
||||
public void kml22_order_location_and_when() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_order_location_and_when);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_order_location_and_when);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
@@ -109,7 +109,7 @@ public class KMLTrackImporterTest {
|
||||
public void kml22_time_decreases() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_time_decreases);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_time_decreases);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
@@ -149,7 +149,7 @@ public class KMLTrackImporterTest {
|
||||
public void kml22_with_statistics_marker() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml22_statistics_marker);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.legacy_kml22_statistics_marker);
|
||||
|
||||
// when
|
||||
// 1. import
|
||||
@@ -223,7 +223,7 @@ public class KMLTrackImporterTest {
|
||||
public void kml_without_locations() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_without_locations);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_without_locations);
|
||||
|
||||
// when
|
||||
importTrackId = importer.importFile(inputStream).get(0);
|
||||
@@ -234,7 +234,7 @@ public class KMLTrackImporterTest {
|
||||
public void kml_when_locations_different() throws IOException {
|
||||
// given
|
||||
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_when_locations_different);
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_when_locations_different);
|
||||
|
||||
// when
|
||||
importTrackId = importer.importFile(inputStream).get(0);
|
||||
|
||||
@@ -99,7 +99,7 @@ public class DescriptionGeneratorTest {
|
||||
+ "Min elevation: -500 m (-1640 ft)<br>"
|
||||
+ "Elevation gain: 6000 m (19685 ft)<br>"
|
||||
+ "Elevation loss: 6000 m (19685 ft)<br>"
|
||||
+ "Recorded: " + StringUtils.formatDateTime(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "<br>";
|
||||
+ "Recorded: " + StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "<br>";
|
||||
|
||||
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true));
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class DescriptionGeneratorTest {
|
||||
+ "Fastest pace: 0:10 min/km (0:16 min/mi)<br>"
|
||||
+ "Elevation gain: 6000 m (19685 ft)<br>"
|
||||
+ "Elevation loss: 6000 m (19685 ft)<br>"
|
||||
+ "Recorded: " + StringUtils.formatDateTime(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "<br>";
|
||||
+ "Recorded: " + StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "<br>";
|
||||
|
||||
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true));
|
||||
}
|
||||
|
||||
+1
-2
@@ -21,7 +21,6 @@ import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.data.models.UnitConversions;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||
|
||||
@@ -180,7 +179,7 @@ public class IntervalStatisticsTest {
|
||||
|
||||
// then
|
||||
assertEquals(trackStatistics.getTotalDistance().toM(), totalDistance.toM(), 0.01);
|
||||
assertEquals(trackStatistics.getTotalTime().toMillis(), totalTime * UnitConversions.S_TO_MS, 1);
|
||||
assertEquals(trackStatistics.getTotalTime().toSeconds(), totalTime, 0.01);
|
||||
assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance().toM() / distanceInterval));
|
||||
if (totalGain != null) {
|
||||
assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1);
|
||||
|
||||
@@ -15,7 +15,6 @@ limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="de.dennisguse.opentracks"
|
||||
android:installLocation="auto">
|
||||
|
||||
<supports-screens
|
||||
|
||||
@@ -38,6 +38,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.splashscreen.SplashScreen;
|
||||
import androidx.cursoradapter.widget.ResourceCursorAdapter;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.CursorLoader;
|
||||
@@ -158,8 +159,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// Reset theme after splash
|
||||
setTheme(R.style.ThemeCustom);
|
||||
SplashScreen.installSplashScreen(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
|
||||
|
||||
@@ -6,7 +6,6 @@ import androidx.annotation.VisibleForTesting;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.data.models.UnitConversions;
|
||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
|
||||
@@ -41,7 +40,7 @@ public class ChartPoint {
|
||||
|
||||
if (smoothedSpeed != null) {
|
||||
speed = smoothedSpeed.to(unitSystem);
|
||||
pace = smoothedSpeed.toPace(unitSystem).toMillis() * UnitConversions.MS_TO_S * UnitConversions.S_TO_MIN;
|
||||
pace = smoothedSpeed.toPace(unitSystem).toSeconds() / 60d;
|
||||
}
|
||||
if (trackPoint.hasHeartRate()) {
|
||||
heartRate = (double) trackPoint.getHeartRate().getBPM();
|
||||
|
||||
@@ -2,22 +2,35 @@ package de.dennisguse.opentracks.data.models;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Cadence {
|
||||
|
||||
public static Cadence of(float value) {
|
||||
return new Cadence(value);
|
||||
public static Cadence of(float value, Duration duration) {
|
||||
if (duration.isZero()) {
|
||||
return zero();
|
||||
}
|
||||
|
||||
return new Cadence(value / (duration.toMillis() / (float) Duration.ofMinutes(1).toMillis()));
|
||||
}
|
||||
|
||||
private final float value;
|
||||
public static Cadence of(float value_rpm) {
|
||||
return new Cadence(value_rpm);
|
||||
}
|
||||
|
||||
public static Cadence zero() {
|
||||
return of(0.0f);
|
||||
}
|
||||
|
||||
private final float value_rpm;
|
||||
|
||||
private Cadence(float value) {
|
||||
this.value = value;
|
||||
this.value_rpm = value;
|
||||
}
|
||||
|
||||
public float getRPM() {
|
||||
return value;
|
||||
return value_rpm;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,19 +38,19 @@ public class Cadence {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Cadence cadence = (Cadence) o;
|
||||
return Float.compare(cadence.value, value) == 0;
|
||||
return Float.compare(cadence.value_rpm, value_rpm) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
return Objects.hash(value_rpm);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cadence{" +
|
||||
"value=" + value + " rpm" +
|
||||
"value=" + value_rpm + " rpm" +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,15 @@ public class Distance {
|
||||
}
|
||||
|
||||
public static Distance ofMile(double distance_mile) {
|
||||
return of(distance_mile * UnitConversions.MI_TO_M);
|
||||
return of(distance_mile * MI_TO_M);
|
||||
}
|
||||
|
||||
public static Distance ofNauticalMile(double distance_mile) {
|
||||
return of(distance_mile * UnitConversions.NAUTICAL_MILE_TO_M);
|
||||
return of(distance_mile * NAUTICAL_MILE_TO_M);
|
||||
}
|
||||
|
||||
public static Distance ofKilometer(double distance_km) {
|
||||
return of(distance_km * UnitConversions.KM_TO_M);
|
||||
return of(distance_km * KM_TO_M);
|
||||
}
|
||||
|
||||
public static Distance ofMM(double distance_mm) {
|
||||
@@ -117,19 +117,19 @@ public class Distance {
|
||||
}
|
||||
|
||||
public double toKM() {
|
||||
return distance_m * UnitConversions.M_TO_KM;
|
||||
return distance_m * M_TO_KM;
|
||||
}
|
||||
|
||||
public double toFT() {
|
||||
return distance_m * UnitConversions.M_TO_FT;
|
||||
return distance_m * M_TO_FT;
|
||||
}
|
||||
|
||||
public double toMI() {
|
||||
return toKM() * UnitConversions.KM_TO_MI;
|
||||
return distance_m * M_TO_MI;
|
||||
}
|
||||
|
||||
public double toNauticalMiles() {
|
||||
return toKM() * UnitConversions.KM_TO_NAUTICAL_MILE;
|
||||
return distance_m * M_TO_NAUTICAL_MILE;
|
||||
}
|
||||
|
||||
public double toKM_Miles(UnitSystem unitSystem) {
|
||||
@@ -177,4 +177,17 @@ public class Distance {
|
||||
"distance_m=" + distance_m +
|
||||
'}';
|
||||
}
|
||||
|
||||
// multiplication factors for conversion
|
||||
private static final double KM_TO_M = 1000.0;
|
||||
private static final double M_TO_KM = 1 / KM_TO_M;
|
||||
|
||||
public static final double MI_TO_M = 1609.344;
|
||||
public static final double M_TO_MI = 1 / MI_TO_M;
|
||||
|
||||
private static final double MI_TO_FT = 5280.0;
|
||||
public static final double M_TO_FT = M_TO_MI * MI_TO_FT;
|
||||
|
||||
private static final double NAUTICAL_MILE_TO_M = 1852.0;
|
||||
private static final double M_TO_NAUTICAL_MILE = 1 / NAUTICAL_MILE_TO_M;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ public class DistanceFormatter {
|
||||
|
||||
private final int decimalCount;
|
||||
|
||||
private final double threshold;
|
||||
|
||||
private final UnitSystem unitSystem;
|
||||
|
||||
private DistanceFormatter(Resources resources, int decimalCount, UnitSystem unitSystem) {
|
||||
private DistanceFormatter(Resources resources, int decimalCount, double threshold, UnitSystem unitSystem) {
|
||||
this.resources = resources;
|
||||
this.decimalCount = decimalCount;
|
||||
this.threshold = threshold;
|
||||
this.unitSystem = unitSystem;
|
||||
assert unitSystem != null;
|
||||
}
|
||||
@@ -56,19 +59,19 @@ public class DistanceFormatter {
|
||||
|
||||
switch (unitSystem) {
|
||||
case METRIC:
|
||||
if (distance.greaterThan(Distance.of(500))) {
|
||||
if (distance.greaterThan(Distance.ofKilometer(threshold))) {
|
||||
return new Pair<>(StringUtils.formatDecimal(distance.toKM(), decimalCount), resources.getString(R.string.unit_kilometer));
|
||||
} else {
|
||||
return new Pair<>(StringUtils.formatDecimal(distance.toM(), decimalCount), resources.getString(R.string.unit_meter));
|
||||
}
|
||||
case IMPERIAL:
|
||||
if (distance.greaterThan(Distance.ofMile(0.5))) {
|
||||
if (distance.greaterThan(Distance.ofMile(threshold))) {
|
||||
return new Pair<>(StringUtils.formatDecimal(distance.toMI(), decimalCount), resources.getString(R.string.unit_mile));
|
||||
} else {
|
||||
return new Pair<>(StringUtils.formatDecimal(distance.toFT(), decimalCount), resources.getString(R.string.unit_feet));
|
||||
}
|
||||
case NAUTICAL_IMPERIAL:
|
||||
if (distance.greaterThan(Distance.ofNauticalMile(0.5))) {
|
||||
if (distance.greaterThan(Distance.ofNauticalMile(threshold))) {
|
||||
return new Pair<>(StringUtils.formatDecimal(distance.toNauticalMiles(), decimalCount), resources.getString(R.string.unit_nautical_mile));
|
||||
} else {
|
||||
return new Pair<>(StringUtils.formatDecimal(distance.toFT(), decimalCount), resources.getString(R.string.unit_feet));
|
||||
@@ -88,8 +91,11 @@ public class DistanceFormatter {
|
||||
|
||||
private UnitSystem unitSystem;
|
||||
|
||||
private double threshold;
|
||||
|
||||
public Builder() {
|
||||
decimalCount = 2;
|
||||
threshold = 0.5;
|
||||
}
|
||||
|
||||
public Builder setDecimalCount(int decimalCount) {
|
||||
@@ -102,8 +108,13 @@ public class DistanceFormatter {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setThreshold(double threshold) {
|
||||
this.threshold = threshold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistanceFormatter build(Resources resource) {
|
||||
return new DistanceFormatter(resource, decimalCount, unitSystem);
|
||||
return new DistanceFormatter(resource, decimalCount, threshold, unitSystem);
|
||||
}
|
||||
|
||||
public DistanceFormatter build(Context context) {
|
||||
|
||||
@@ -15,7 +15,7 @@ public class Speed {
|
||||
return zero();
|
||||
}
|
||||
|
||||
return new Speed(distance.toM() / (duration.toMillis() * UnitConversions.MS_TO_S));
|
||||
return new Speed(distance.toM() / (duration.toMillis() / (double) Duration.ofSeconds(1).toMillis()));
|
||||
}
|
||||
|
||||
public static Speed of(double speed_mps) {
|
||||
@@ -85,16 +85,23 @@ public class Speed {
|
||||
return speed_mps;
|
||||
}
|
||||
|
||||
/**
|
||||
* We interpret {@link Speed} here as a {@link Distance} over 1h.
|
||||
*/
|
||||
private Distance toH() {
|
||||
return Distance.of(speed_mps * Duration.ofHours(1).toSeconds());
|
||||
}
|
||||
|
||||
public double toKMH() {
|
||||
return speed_mps * UnitConversions.MPS_TO_KMH;
|
||||
return toH().toKM();
|
||||
}
|
||||
|
||||
public double toMPH() {
|
||||
return toKMH() * UnitConversions.KM_TO_MI;
|
||||
return toH().toMI();
|
||||
}
|
||||
|
||||
public double toKnots() {
|
||||
return toKMH() * UnitConversions.KM_TO_NAUTICAL_MILE;
|
||||
return toH().toNauticalMiles();
|
||||
}
|
||||
|
||||
public Duration toPace(UnitSystem unitSystem) {
|
||||
@@ -102,20 +109,7 @@ public class Speed {
|
||||
return Duration.ofSeconds(0);
|
||||
}
|
||||
|
||||
double distance = speed_mps;
|
||||
switch (unitSystem) { //TODO Can we use to(UnitSystem)?
|
||||
case METRIC:
|
||||
distance *= UnitConversions.M_TO_KM;
|
||||
break;
|
||||
case IMPERIAL:
|
||||
distance *= UnitConversions.M_TO_MI;
|
||||
break;
|
||||
case NAUTICAL_IMPERIAL:
|
||||
distance *= UnitConversions.M_TO_NAUTICAL_MILE;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
double distance = Distance.of(speed_mps).toKM_Miles(unitSystem);
|
||||
|
||||
return Duration.ofSeconds(Math.round(1 / distance));
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package de.dennisguse.opentracks.data.models;
|
||||
|
||||
/**
|
||||
* Unit conversion constants.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class UnitConversions {
|
||||
|
||||
// Time //TODO Use Duration
|
||||
// multiplication factor to convert seconds to milliseconds
|
||||
@Deprecated
|
||||
public static final long S_TO_MS = 1000;
|
||||
|
||||
// multiplication factor to convert milliseconds to seconds
|
||||
@Deprecated
|
||||
public static final double MS_TO_S = 1d / S_TO_MS;
|
||||
// multiplication factor to convert minutes to seconds
|
||||
@Deprecated
|
||||
public static final double MIN_TO_S = 60.0;
|
||||
// multiplication factor to convert seconds to minutes
|
||||
@Deprecated
|
||||
public static final double S_TO_MIN = 1 / MIN_TO_S;
|
||||
// multiplication factor to convert minutes to hours
|
||||
@Deprecated
|
||||
public static final double MIN_TO_HR = 1 / 60.0;
|
||||
|
||||
// multiplication factor to convert kilometers to miles
|
||||
public static final double KM_TO_MI = 0.621371192;
|
||||
|
||||
// Distance //TODO Make private to Distance class!
|
||||
// multiplication factor to convert miles to feet
|
||||
private static final double MI_TO_FT = 5280.0;
|
||||
// multiplication factor to covert kilometers to meters
|
||||
public static final double KM_TO_M = 1000.0;
|
||||
// multiplication factor to convert meters to kilometers
|
||||
public static final double M_TO_KM = 1 / KM_TO_M;
|
||||
// multiplication factor to convert meters to miles
|
||||
public static final double M_TO_MI = M_TO_KM * KM_TO_MI;
|
||||
// multiplication factor to convert meters to feet
|
||||
public static final double M_TO_FT = M_TO_MI * MI_TO_FT;
|
||||
public static final double NAUTICAL_MILE_TO_M = 1852.0;
|
||||
public static final double M_TO_NAUTICAL_MILE = 1 / NAUTICAL_MILE_TO_M;
|
||||
public static final double KM_TO_NAUTICAL_MILE = 1000 * M_TO_NAUTICAL_MILE;
|
||||
// multiplication factor to convert meters per second to kilometers per hour
|
||||
public static final double MPS_TO_KMH = M_TO_KM / (S_TO_MIN * MIN_TO_HR);
|
||||
// multiplication factor to convert miles to km
|
||||
public static final double MI_TO_KM = 1 / KM_TO_MI;
|
||||
// multiplication factor to convert miles to m
|
||||
public static final double MI_TO_M = MI_TO_KM * KM_TO_M;
|
||||
|
||||
private UnitConversions() {
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public class StatisticsRecordedFragment extends Fragment {
|
||||
private void loadTrackDescription(@NonNull Track track) {
|
||||
viewBinding.statsNameValue.setText(track.getName());
|
||||
viewBinding.statsDescriptionValue.setText(track.getDescription());
|
||||
viewBinding.statsStartDatetimeValue.setText(StringUtils.formatDateTime(track.getStartTime()));
|
||||
viewBinding.statsStartDatetimeValue.setText(StringUtils.formatDateTimeWithOffsetIfDifferent(track.getStartTime()));
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.splashscreen.SplashScreen;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
@@ -30,7 +31,10 @@ public abstract class AbstractAPIActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
splashScreen.setKeepOnScreenCondition(() -> true );
|
||||
|
||||
if (PreferencesUtils.isPublicAPIenabled()) {
|
||||
Log.i(TAG, "Received and trying to execute requested action.");
|
||||
new TrackRecordingServiceConnection(serviceConnectedCallback)
|
||||
|
||||
@@ -15,6 +15,7 @@ public class StartRecording extends AbstractAPIActivity {
|
||||
|
||||
public static final String EXTRA_TRACK_NAME = "TRACK_NAME";
|
||||
public static final String EXTRA_TRACK_CATEGORY = "TRACK_CATEGORY";
|
||||
public static final String EXTRA_TRACK_ICON = "TRACK_ICON";
|
||||
public static final String EXTRA_TRACK_DESCRIPTION = "TRACK_DESCRIPTION";
|
||||
|
||||
public static final String EXTRA_STATS_TARGET_PACKAGE = "STATS_TARGET_PACKAGE";
|
||||
@@ -40,8 +41,11 @@ public class StartRecording extends AbstractAPIActivity {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(this);
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
|
||||
TrackUtils.updateTrack(this, track, bundle.getString(EXTRA_TRACK_NAME, null),
|
||||
bundle.getString(EXTRA_TRACK_CATEGORY, null), bundle.getString(EXTRA_TRACK_DESCRIPTION, null),
|
||||
TrackUtils.updateTrack(this, track,
|
||||
bundle.getString(EXTRA_TRACK_NAME, null),
|
||||
bundle.getString(EXTRA_TRACK_CATEGORY, null),
|
||||
bundle.getString(EXTRA_TRACK_ICON, null),
|
||||
bundle.getString(EXTRA_TRACK_DESCRIPTION, null),
|
||||
contentProviderUtils);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import java.time.Duration;
|
||||
import de.dennisguse.opentracks.data.models.Cadence;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.UnitConversions;
|
||||
import de.dennisguse.opentracks.sensors.UintUtils;
|
||||
|
||||
/**
|
||||
@@ -68,8 +67,9 @@ public final class SensorDataCycling {
|
||||
|
||||
public void compute(CyclingCadence previous) {
|
||||
if (hasData() && previous != null && previous.hasData()) {
|
||||
float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
|
||||
if (timeDiff_ms <= 0) {
|
||||
float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * 1000;
|
||||
Duration timeDiff = Duration.ofMillis((long) timeDiff_ms);
|
||||
if (timeDiff.isZero() || timeDiff.isNegative()) {
|
||||
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
|
||||
value = null;
|
||||
return;
|
||||
@@ -82,8 +82,7 @@ public final class SensorDataCycling {
|
||||
}
|
||||
|
||||
long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX);
|
||||
float cadence_ms = crankDiff / timeDiff_ms;
|
||||
value = Cadence.of((float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN));
|
||||
value = Cadence.of(crankDiff, timeDiff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +146,7 @@ public final class SensorDataCycling {
|
||||
|
||||
public void compute(DistanceSpeed previous, Distance wheelCircumference) {
|
||||
if (hasData() && previous != null && previous.hasData()) {
|
||||
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
|
||||
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * 1000;
|
||||
Duration timeDiff = Duration.ofMillis((long) timeDiff_ms);
|
||||
if (timeDiff.isZero() || timeDiff.isNegative()) {
|
||||
Log.e(TAG, "Timestamps difference is invalid: cannot compute speed.");
|
||||
|
||||
@@ -323,7 +323,7 @@ public class PreferencesUtils {
|
||||
UnitSystem unitSystem = getUnitSystem();
|
||||
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(1)
|
||||
.setDecimalCount(0)
|
||||
.setUnit(unitSystem)
|
||||
.build(resources);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
@@ -417,7 +417,8 @@ public class PreferencesUtils {
|
||||
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setUnit(unitSystem)
|
||||
.setDecimalCount(1)
|
||||
.setDecimalCount(0)
|
||||
.setThreshold(Double.MAX_VALUE)
|
||||
.build(resources);
|
||||
for (int i = 0; i < entryValues.length; i++) {
|
||||
int value = Integer.parseInt(entryValues[i]);
|
||||
@@ -461,7 +462,8 @@ public class PreferencesUtils {
|
||||
UnitSystem unitSystem = getUnitSystem();
|
||||
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(1)
|
||||
.setDecimalCount(0)
|
||||
.setThreshold(Double.MAX_VALUE)
|
||||
.setUnit(unitSystem)
|
||||
.build(resources);
|
||||
for (int i = 0; i < entryValues.length; i++) {
|
||||
@@ -534,7 +536,8 @@ public class PreferencesUtils {
|
||||
UnitSystem unitSystem = getUnitSystem();
|
||||
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(1)
|
||||
.setDecimalCount(0)
|
||||
.setThreshold(Double.MAX_VALUE)
|
||||
.setUnit(unitSystem)
|
||||
.build(resources);
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.SpeedFormatter;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.UnitConversions;
|
||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
@@ -154,7 +153,7 @@ public class DescriptionGenerator {
|
||||
}
|
||||
|
||||
// Recorded time
|
||||
builder.append(context.getString(R.string.description_recorded_time, StringUtils.formatDateTime(OffsetDateTime.ofInstant(stats.getStartTime(), ZoneId.systemDefault()))));
|
||||
builder.append(context.getString(R.string.description_recorded_time, StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(stats.getStartTime(), ZoneId.systemDefault()))));
|
||||
builder.append(lineBreak);
|
||||
|
||||
return builder.toString();
|
||||
@@ -230,7 +229,7 @@ public class DescriptionGenerator {
|
||||
@VisibleForTesting
|
||||
void writeAltitude(double altitude_m, StringBuilder builder, int resId, String lineBreak) {
|
||||
long altitudeInM = Math.round(altitude_m);
|
||||
long altitudeInFt = Math.round(altitude_m * UnitConversions.M_TO_FT);
|
||||
long altitudeInFt = Math.round(Distance.of(altitude_m).toFT());
|
||||
builder.append(context.getString(resId, altitudeInM, altitudeInFt));
|
||||
builder.append(lineBreak);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.data.models.UnitConversions;
|
||||
|
||||
/**
|
||||
* Updater for {@link TrackStatistics}.
|
||||
@@ -196,7 +195,7 @@ public class TrackStatisticsUpdater {
|
||||
// See if the speed seems physically likely. Ignore any speeds that imply acceleration greater than 2g.
|
||||
Duration timeDifference = Duration.between(lastTrackPoint.getTime(), trackPoint.getTime());
|
||||
Speed maxSpeedDifference = Speed.of(Distance.of(SPEED_MAX_ACCELERATION), Duration.ofMillis(1000))
|
||||
.mul(timeDifference.toMillis() / UnitConversions.S_TO_MS);
|
||||
.mul(timeDifference.toSeconds());
|
||||
|
||||
Speed speedDifference = Speed.absDiff(lastTrackPoint.getSpeed(), trackPoint.getSpeed());
|
||||
return speedDifference.lessThan(maxSpeedDifference);
|
||||
|
||||
@@ -108,7 +108,11 @@ public class ListItemUtils {
|
||||
String timeValue = null;
|
||||
if (!isRecording) {
|
||||
dateValue = StringUtils.formatDateTodayRelative(context, offsetDateTime);
|
||||
timeValue = offsetDateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
||||
String pattern = "HH:mm";
|
||||
if (!offsetDateTime.getOffset().equals(OffsetDateTime.now().getOffset())) {
|
||||
pattern = "HH:mm x";
|
||||
}
|
||||
timeValue = offsetDateTime.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
setTextView(context, dateTextView, dateValue, hasPhoto);
|
||||
setTextView(context, timeTextView, timeValue, hasPhoto);
|
||||
|
||||
@@ -61,13 +61,6 @@ public class StringUtils {
|
||||
private StringUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the date and time of the OffsetDateTime (using default Locale format)
|
||||
*/
|
||||
public static String formatDateTime(OffsetDateTime odt) {
|
||||
return odt.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the date and time with the offset (using default Locale format).
|
||||
*/
|
||||
@@ -75,6 +68,13 @@ public class StringUtils {
|
||||
return odt.toZonedDateTime().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
|
||||
}
|
||||
|
||||
public static String formatDateTimeWithOffsetIfDifferent(OffsetDateTime odt) {
|
||||
if (!odt.getOffset().equals(OffsetDateTime.now().getOffset())) {
|
||||
return odt.toZonedDateTime().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
|
||||
}
|
||||
return odt.toZonedDateTime().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));
|
||||
}
|
||||
|
||||
public static String formatLocalDateTime(LocalDateTime localDateTime) {
|
||||
return localDateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
|
||||
}
|
||||
@@ -257,7 +257,8 @@ public class StringUtils {
|
||||
//TODO altitude_m should be double or a value object
|
||||
public static Pair<String, String> getAltitudeParts(Context context, Float altitude_m, UnitSystem unitSystem) {
|
||||
DistanceFormatter formatter = DistanceFormatter.Builder()
|
||||
.setDecimalCount(1)
|
||||
.setDecimalCount(0)
|
||||
.setThreshold(Double.MAX_VALUE)
|
||||
.setUnit(unitSystem)
|
||||
.build(context);
|
||||
|
||||
|
||||
@@ -26,12 +26,17 @@ import de.dennisguse.opentracks.data.models.Track;
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
@Deprecated //TODO Refactor: all this should happen somewhere else (ContentProviderUtils?)
|
||||
public class TrackUtils {
|
||||
|
||||
private TrackUtils() {
|
||||
}
|
||||
|
||||
public static void updateTrack(Context context, Track track, String name, String category, String description, ContentProviderUtils contentProviderUtils) {
|
||||
updateTrack(context, track, name, category, TrackIconUtils.getIconValue(context, category), description, contentProviderUtils);
|
||||
}
|
||||
|
||||
public static void updateTrack(Context context, Track track, String name, String category, String iconValue, String description, ContentProviderUtils contentProviderUtils) {
|
||||
boolean update = false;
|
||||
if (name != null) {
|
||||
track.setName(name);
|
||||
@@ -39,9 +44,13 @@ public class TrackUtils {
|
||||
}
|
||||
if (category != null) {
|
||||
track.setCategory(category);
|
||||
track.setIcon(TrackIconUtils.getIconValue(context, category));
|
||||
update = true;
|
||||
}
|
||||
if (iconValue != null) {
|
||||
track.setIcon(iconValue);
|
||||
} else if (category != null){
|
||||
track.setIcon(TrackIconUtils.getIconValue(context, category));
|
||||
}
|
||||
if (description != null) {
|
||||
track.setDescription(description);
|
||||
update = true;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="100"
|
||||
android:viewportHeight="100">
|
||||
|
||||
<group
|
||||
android:name="rotationGroup"
|
||||
android:pivotX="50"
|
||||
android:pivotY="50"
|
||||
android:scaleX="0.6"
|
||||
android:scaleY="0.6"
|
||||
>
|
||||
<path android:pathData="M82.489,12.834C83.196,10.418 82.043,9.556 79.926,10.917L10.087,55.828c-2.117,1.361 -1.795,2.628 0.714,2.815L39.806,60.807c2.51,0.188 5.291,2.267 6.18,4.621l10.282,27.208c0.89,2.354 2.195,2.304 2.902,-0.111z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="70.0"
|
||||
android:endY="30.0"
|
||||
android:startX="7.0"
|
||||
android:startY="83.0"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#FFFBB22F"
|
||||
android:offset="0" />
|
||||
<item
|
||||
android:color="#FFFF6D00"
|
||||
android:offset="1" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:opacity="opaque">
|
||||
|
||||
<item android:drawable="@color/splashscreen_background" />
|
||||
|
||||
<item
|
||||
android:width="300dp"
|
||||
android:height="300dp"
|
||||
android:gravity="center"
|
||||
tools:targetApi="m">
|
||||
<inset
|
||||
android:drawable="@drawable/ic_logo_color_24dp"
|
||||
android:inset="20dp" />
|
||||
</item>
|
||||
|
||||
</layer-list>
|
||||
@@ -59,10 +59,11 @@ limitations under the License.
|
||||
<item name="indicatorColor">?attr/colorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="SplashTheme" parent="ThemeCustom">
|
||||
<item name="android:statusBarColor">@color/splashscreen_background</item>
|
||||
<item name="android:navigationBarColor">@color/splashscreen_background</item>
|
||||
<item name="android:windowBackground">@drawable/splashscreen</item>
|
||||
<style name="SplashTheme" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
||||
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_logo_color_splashscreen</item>
|
||||
<item name="postSplashScreenTheme">@style/ThemeCustom</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.OpenTracks.FloatingActionButton" parent="Widget.MaterialComponents.FloatingActionButton">
|
||||
|
||||
Reference in New Issue
Block a user