Compare commits

...

32 Commits

Author SHA1 Message Date
Dennis Guse bfeca771f8 Release v3.9.4 2020-09-05 01:41:01 +02:00
Dennis Guse f128111650 Code cleanup. 2020-09-05 01:19:59 +02:00
Dennis Guse 38fadda762 Bugfix: show on map via GPX/KML/KMZ was failing.
We were sending the trackId as intent extra (actually unused) and this trackId could not be unparceled.
Fixes #411.
2020-09-05 01:19:59 +02:00
Dennis Guse d6d40b01e6 Refactoring.
Also fixes #406.
2020-09-05 01:17:40 +02:00
dependabot[bot] bc051f5d81 Bump mockito-android from 3.5.9 to 3.5.10
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.5.9 to 3.5.10.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.5.9...v3.5.10)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-04 23:45:30 +02:00
dependabot[bot] 39bf2190a1 Bump material from 1.2.0 to 1.2.1
Bumps [material](https://github.com/material-components/material-components-android) from 1.2.0 to 1.2.1.
- [Release notes](https://github.com/material-components/material-components-android/releases)
- [Commits](https://github.com/material-components/material-components-android/compare/1.2.0...1.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-03 16:55:31 +02:00
Román b88f81726b Bugfix: location handler didn't remove updates. Fixes #403. 2020-09-03 15:32:44 +02:00
Dennis Guse 24e6cdec62 Interval Stats: fixed NPE introduced in 25ef0ecad1.
Includes some refactoring.
2020-09-02 23:12:52 +02:00
Dennis Guse 951671b2f3 Update PULL_REQUEST_TEMPLATE.md 2020-09-02 22:20:50 +02:00
dependabot[bot] 21e30545a0 Bump mockito-android from 3.4.6 to 3.5.9
Bumps [mockito-android](https://github.com/mockito/mockito) from 3.4.6 to 3.5.9.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.4.6...v3.5.9)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-02 19:26:45 +02:00
Dennis Guse 946edb7e16 Update CONTRIBUTING.md 2020-09-02 19:24:33 +02:00
Román 89c44af374 Recorded stats: natural order for intervals. 2020-09-02 14:32:32 +02:00
Dennis Guse faad451e22 Added contribution guidelines 2020-09-02 08:10:55 +02:00
Dennis Guse 25ef0ecad1 Interval Stats: use a tab for recorded tracks as well. 2020-09-02 07:52:33 +02:00
Román efa6caca66 New style for spinner with text. 2020-09-02 07:52:33 +02:00
Román 5be4c107f4 Announcement: while recording report current interval pace or speed.
Fixes #134.
2020-09-02 07:52:33 +02:00
Román 65f42dd3e5 Interval Stats: improve code and fixed some UI issues. 2020-09-02 07:52:33 +02:00
Román 287d246777 Interval Stats: track's id it's not long anymore. 2020-09-02 07:52:33 +02:00
Román d56f652d0a Interval stats: while user is recording a track intervals are refreshed every 5 seconds.
Interval stats: completed the list of split intervals: 1, 2, 3, 4, 5, 10, 20 or 50 km or mi.
Fixes #87.
2020-09-02 07:52:33 +02:00
Román 1f1ef4445f Interval stats: added IntervalStatisticsTest. 2020-09-02 07:52:33 +02:00
Román 22a669a573 Interval stats: added a new tab in TrackRecordingActivity that shows the intervals on live. 2020-09-02 07:52:33 +02:00
Román f55cce5614 Interval stats: improve code. 2020-09-02 07:52:33 +02:00
Román a6c3cf1c28 Interval statistics: listen preferred units change (metric/imperial) and recreate intervals. 2020-09-02 07:52:33 +02:00
Román cbc803d038 Interval statistics: retain interval value after change orientation and recreation. 2020-09-02 07:52:33 +02:00
Román a8cefcd0fd Interval statistics: show accumulate in distance column. 2020-09-02 07:52:33 +02:00
Román 2b95dbab22 Adjusted intervals. 2020-09-02 07:52:33 +02:00
Román 7a923a947e Added intervals in StatisticsRecordedFragment with distance, speed and pace for all activity types.
Users can select the length of the interval (in a spinner with several options).
The intervals will be in km or mi depending on settings.
2020-09-02 07:52:33 +02:00
Román 19e35a7609 StatisticsRecordedFragment doesn't need TrackDataHub.
TrackRecordedActivity saves Track object instead of track's id.
2020-09-02 07:52:33 +02:00
Dennis Guse b8088169ee Settings: animate the Bluetooth icon.
Fixes #314.
2020-09-01 22:19:19 +02:00
Román a5594fbb7a Release v3.9.3 2020-08-31 12:47:33 +02:00
Román a733d87c37 Bugfix: export all failed trying to convert to string the Track.Id. 2020-08-31 12:25:58 +02:00
Dennis Guse 79d8ba9ef8 Configure Dependabot for Gradle and Github actions 2020-08-30 23:28:50 +02:00
59 changed files with 1700 additions and 587 deletions
+8
View File
@@ -1,5 +1,13 @@
# Thanks for your contribution. # Thanks for your contribution.
## PLEASE REMOVE
To support us in providing a nice (and fast) open-source experience:
1. Verify that the tests are passing
2. Check that the code is properly formatted (using AndroidStudio's autoformatter)
3. Provide write access to the [branch](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork)
4. If the PR is not ready for review, please submit it as a [draft](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests)
## PLEASE REMOVE
**Describe the pull request** **Describe the pull request**
A clear and concise description of what the pull request changes/adds. A clear and concise description of what the pull request changes/adds.
+10
View File
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
+35
View File
@@ -0,0 +1,35 @@
# How to contribute?
## Testing
Just use OpenTracks and tell us what can be improved by opening an issue [here](https://github.com/OpenTracksApp/OpenTracks/issues/new/choose)
If we broke things (happens now and then), please tell us also.
## Coding new features
You have a cool idea for a feature that is missing in OpenTracks?
And you would like to help by implementing it?
If not, you can just take a look at the [issue tracker](https://github.com/OpenTracksApp/OpenTracks/issues).
Advices:
* creating an issue beforehand might be a good idea
Sometimes it is helpful to discuss your idea and also your implementation approach first.
We may be able to give you some hints on how to tackle the problem.
It also makes merging your changes easier and, usually, faster.
* please only add new dependencies if is absolutely necessary
If you need to:
* tell us why those are required,
* what alternatives are existing, and
* why you choose this dependency.
And also verify that the license(s) are compatible with _Apache 2.0_ as well as open-source.
## Coding conventions
None so far.
Just keep it simple.
And follow the _scout rule_.
You can take a look at existing code and get a feeling for it.
Please autoformat your code using AndroidStudio's code formatter.
+4 -4
View File
@@ -47,8 +47,8 @@ android {
defaultConfig { defaultConfig {
applicationId "de.dennisguse.opentracks" applicationId "de.dennisguse.opentracks"
versionCode 3541 versionCode 3573
versionName "v3.9.2" versionName "v3.9.4"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\"" buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
@@ -87,12 +87,12 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.documentfile:documentfile:1.0.1' implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'com.google.android.material:material:1.2.0' implementation 'com.google.android.material:material:1.2.1'
implementation 'com.android.support.constraint:constraint-layout:2.0.1' implementation 'com.android.support.constraint:constraint-layout:2.0.1'
androidTestImplementation 'androidx.test:core:1.3.0' androidTestImplementation 'androidx.test:core:1.3.0'
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.4.6' androidTestImplementation 'org.mockito:mockito-android:3.5.10'
} }
@@ -0,0 +1,4 @@
v3.9.3: OpenTracks
Bugfixes:
- Fixed export all tracks bug.
@@ -0,0 +1,10 @@
v3.9.4: OpenTracks
Changes:
- Added interval computation
- Voice announcements present last interval statistics
- Settings: Bluetooth icon is animated
Bugfix:
- GPS was not turned off when stopping a recording
- Show on map via KML/KMZ/GPX was broken due to refactoring
@@ -19,13 +19,16 @@ import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/** /**
* Tests {@link ChartValueSeries}. * Tests {@link ChartValueSeries}.
* *
@@ -60,16 +63,16 @@ public class ChartValueSeriesTest {
@Test @Test
public void testInitialConditions() { public void testInitialConditions() {
Assert.assertEquals(1, series.getInterval()); assertEquals(1, series.getInterval());
Assert.assertEquals(0, series.getMinMarkerValue()); assertEquals(0, series.getMinMarkerValue());
Assert.assertEquals(5, series.getMaxMarkerValue()); assertEquals(5, series.getMaxMarkerValue());
Assert.assertTrue(series.isEnabled()); assertTrue(series.isEnabled());
} }
@Test @Test
public void testEnabled() { public void testEnabled() {
series.setEnabled(false); series.setEnabled(false);
Assert.assertFalse(series.isEnabled()); assertFalse(series.isEnabled());
} }
@Test @Test
@@ -77,9 +80,9 @@ public class ChartValueSeriesTest {
series.update(new ChartPoint(0)); series.update(new ChartPoint(0));
series.update(new ChartPoint(10)); series.update(new ChartPoint(10));
series.updateDimension(); series.updateDimension();
Assert.assertEquals(100, series.getInterval()); assertEquals(100, series.getInterval());
Assert.assertEquals(0, series.getMinMarkerValue()); assertEquals(0, series.getMinMarkerValue());
Assert.assertEquals(500, series.getMaxMarkerValue()); assertEquals(500, series.getMaxMarkerValue());
} }
@Test @Test
@@ -87,9 +90,9 @@ public class ChartValueSeriesTest {
series.update(new ChartPoint(0)); series.update(new ChartPoint(0));
series.update(new ChartPoint(901)); series.update(new ChartPoint(901));
series.updateDimension(); series.updateDimension();
Assert.assertEquals(1000, series.getInterval()); assertEquals(1000, series.getInterval());
Assert.assertEquals(0, series.getMinMarkerValue()); assertEquals(0, series.getMinMarkerValue());
Assert.assertEquals(5000, series.getMaxMarkerValue()); assertEquals(5000, series.getMaxMarkerValue());
} }
@Test @Test
@@ -97,8 +100,8 @@ public class ChartValueSeriesTest {
series.update(new ChartPoint(220)); series.update(new ChartPoint(220));
series.update(new ChartPoint(250)); series.update(new ChartPoint(250));
series.updateDimension(); series.updateDimension();
Assert.assertEquals(100, series.getInterval()); assertEquals(100, series.getInterval());
Assert.assertEquals(200, series.getMinMarkerValue()); assertEquals(200, series.getMinMarkerValue());
Assert.assertEquals(700, series.getMaxMarkerValue()); assertEquals(700, series.getMaxMarkerValue());
} }
} }
@@ -21,7 +21,6 @@ import android.content.Context;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -31,6 +30,8 @@ import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.StringUtils; import de.dennisguse.opentracks.util.StringUtils;
import static org.junit.Assert.assertEquals;
/** /**
* Tests for {@link DescriptionGenerator}. * Tests for {@link DescriptionGenerator}.
* *
@@ -85,7 +86,7 @@ public class DescriptionGeneratorTest {
+ "Elevation gain: 6000 m (19685 ft)<br>" + "Elevation gain: 6000 m (19685 ft)<br>"
+ "Recorded: " + StringUtils.formatDateTime(context, START_TIME) + "<br>"; + "Recorded: " + StringUtils.formatDateTime(context, START_TIME) + "<br>";
Assert.assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true)); assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true));
} }
@Test @Test
@@ -119,7 +120,7 @@ public class DescriptionGeneratorTest {
+ "Elevation gain: 6000 m (19685 ft)<br>" + "Elevation gain: 6000 m (19685 ft)<br>"
+ "Recorded: " + StringUtils.formatDateTime(context, START_TIME) + "<br>"; + "Recorded: " + StringUtils.formatDateTime(context, START_TIME) + "<br>";
Assert.assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true)); assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true));
} }
@@ -130,7 +131,7 @@ public class DescriptionGeneratorTest {
public void testWriteDistance() { public void testWriteDistance() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeDistance(1100, builder, R.string.description_total_distance, "<br>"); descriptionGenerator.writeDistance(1100, builder, R.string.description_total_distance, "<br>");
Assert.assertEquals("Total distance: 1.10 km (0.7 mi)<br>", builder.toString()); assertEquals("Total distance: 1.10 km (0.7 mi)<br>", builder.toString());
} }
/** /**
@@ -140,7 +141,7 @@ public class DescriptionGeneratorTest {
public void testWriteTime() { public void testWriteTime() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeTime(1000, builder, R.string.description_total_time, "<br>"); descriptionGenerator.writeTime(1000, builder, R.string.description_total_time, "<br>");
Assert.assertEquals("Total time: 00:01<br>", builder.toString()); assertEquals("Total time: 00:01<br>", builder.toString());
} }
/** /**
@@ -150,7 +151,7 @@ public class DescriptionGeneratorTest {
public void testWriteSpeed() { public void testWriteSpeed() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeSpeed(1.1, builder, R.string.description_average_speed, "\n"); descriptionGenerator.writeSpeed(1.1, builder, R.string.description_average_speed, "\n");
Assert.assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString()); assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString());
} }
/** /**
@@ -160,7 +161,7 @@ public class DescriptionGeneratorTest {
public void testWriteElevation() { public void testWriteElevation() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writeElevation(4.2, builder, R.string.description_min_elevation, "<br>"); descriptionGenerator.writeElevation(4.2, builder, R.string.description_min_elevation, "<br>");
Assert.assertEquals("Min elevation: 4 m (14 ft)<br>", builder.toString()); assertEquals("Min elevation: 4 m (14 ft)<br>", builder.toString());
} }
/** /**
@@ -170,6 +171,6 @@ public class DescriptionGeneratorTest {
public void testWritePace() { public void testWritePace() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
descriptionGenerator.writePace(1.1, builder, R.string.description_average_pace_in_minute, "\n"); descriptionGenerator.writePace(1.1, builder, R.string.description_average_pace_in_minute, "\n");
Assert.assertEquals("Average pace: 15:09 min/km (24:23 min/mi)\n", builder.toString()); assertEquals("Average pace: 15:09 min/km (24:23 min/mi)\n", builder.toString());
} }
} }
@@ -24,7 +24,6 @@ import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.provider.ProviderTestRule; import androidx.test.rule.provider.ProviderTestRule;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@@ -42,6 +41,10 @@ import de.dennisguse.opentracks.content.provider.CustomContentProvider;
import de.dennisguse.opentracks.content.provider.CustomSQLiteOpenHelper; import de.dennisguse.opentracks.content.provider.CustomSQLiteOpenHelper;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/** /**
* Tests for {@link SearchEngine}. * Tests for {@link SearchEngine}.
* These are not meant to be quality tests, but instead feature-by-feature tests. * These are not meant to be quality tests, but instead feature-by-feature tests.
@@ -200,7 +203,7 @@ public class SearchEngineTest {
ArrayList<ScoredResult> results = new ArrayList<>(engine.search(query)); ArrayList<ScoredResult> results = new ArrayList<>(engine.search(query));
// Title > Description > Category. // Title > Description > Category.
Assert.assertEquals(results.toString(), 3, results.size()); assertEquals(results.toString(), 3, results.size());
assertTrackResult(trackId, results.get(0)); assertTrackResult(trackId, results.get(0));
assertWaypointResult(titleWaypointId, results.get(1)); assertWaypointResult(titleWaypointId, results.get(1));
assertWaypointResult(descriptionWaypointId, results.get(2)); assertWaypointResult(descriptionWaypointId, results.get(2));
@@ -274,9 +277,9 @@ public class SearchEngineTest {
} }
private void assertTrackResult(Track.Id trackId, ScoredResult result) { private void assertTrackResult(Track.Id trackId, ScoredResult result) {
Assert.assertNotNull("Not a track", result.track); assertNotNull("Not a track", result.track);
Assert.assertNull("Ambiguous result", result.waypoint); assertNull("Ambiguous result", result.waypoint);
Assert.assertEquals(trackId, result.track.getId()); assertEquals(trackId, result.track.getId());
} }
private void assertTrackResults(List<ScoredResult> results, Track.Id... trackIds) { private void assertTrackResults(List<ScoredResult> results, Track.Id... trackIds) {
@@ -286,19 +289,19 @@ public class SearchEngineTest {
} }
String errMsg = "Expected IDs=" + Arrays.toString(longTrackIds) + "; results=" + results; String errMsg = "Expected IDs=" + Arrays.toString(longTrackIds) + "; results=" + results;
Assert.assertEquals(results.size(), trackIds.length); assertEquals(results.size(), trackIds.length);
for (int i = 0; i < results.size(); i++) { for (int i = 0; i < results.size(); i++) {
ScoredResult result = results.get(i); ScoredResult result = results.get(i);
Assert.assertNotNull(errMsg, result.track); assertNotNull(errMsg, result.track);
Assert.assertNull(errMsg, result.waypoint); assertNull(errMsg, result.waypoint);
Assert.assertEquals(errMsg, trackIds[i], result.track.getId()); assertEquals(errMsg, trackIds[i], result.track.getId());
} }
} }
private void assertWaypointResult(Waypoint.Id waypointId, ScoredResult result) { private void assertWaypointResult(Waypoint.Id waypointId, ScoredResult result) {
Assert.assertNotNull("Not a waypoint", result.waypoint); assertNotNull("Not a waypoint", result.waypoint);
Assert.assertNull("Ambiguous result", result.track); assertNull("Ambiguous result", result.track);
Assert.assertEquals(waypointId, result.waypoint.getId()); assertEquals(waypointId, result.waypoint.getId());
} }
private void assertWaypointResults(List<ScoredResult> results, Waypoint.Id... waypointIds) { private void assertWaypointResults(List<ScoredResult> results, Waypoint.Id... waypointIds) {
@@ -308,12 +311,12 @@ public class SearchEngineTest {
} }
String errMsg = "Expected IDs=" + Arrays.toString(longWaypointIds) + "; results=" + results; String errMsg = "Expected IDs=" + Arrays.toString(longWaypointIds) + "; results=" + results;
Assert.assertEquals(results.size(), waypointIds.length); assertEquals(results.size(), waypointIds.length);
for (int i = 0; i < results.size(); i++) { for (int i = 0; i < results.size(); i++) {
ScoredResult result = results.get(i); ScoredResult result = results.get(i);
Assert.assertNotNull(errMsg, result.waypoint); assertNotNull(errMsg, result.waypoint);
Assert.assertNull(errMsg, result.track); assertNull(errMsg, result.track);
Assert.assertEquals(errMsg, waypointIds[i], result.waypoint.getId()); assertEquals(errMsg, waypointIds[i], result.waypoint.getId());
} }
} }
} }
@@ -25,7 +25,6 @@ import android.util.Pair;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -50,6 +49,11 @@ import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.FileUtils; import de.dennisguse.opentracks.util.FileUtils;
import de.dennisguse.opentracks.util.UUIDUtils; import de.dennisguse.opentracks.util.UUIDUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
/** /**
@@ -122,13 +126,13 @@ public class CustomContentProviderUtilsTest {
try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L, descending)) { try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L, descending)) {
while (it.hasNext()) { while (it.hasNext()) {
TrackPoint loc = it.next(); TrackPoint loc = it.next();
Assert.assertNotNull(loc); assertNotNull(loc);
locations.add(loc); locations.add(loc);
// Make sure the IDs are returned in the right order. // Make sure the IDs are returned in the right order.
Assert.assertEquals(descending ? lastPointId - locations.size() + 1 assertEquals(descending ? lastPointId - locations.size() + 1
: lastPointId - numPoints + locations.size(), it.getTrackPointId()); : lastPointId - numPoints + locations.size(), it.getTrackPointId());
} }
Assert.assertEquals(numPoints, locations.size()); assertEquals(numPoints, locations.size());
} }
} }
@@ -138,7 +142,7 @@ public class CustomContentProviderUtilsTest {
track.setName("Test: " + id.getId()); track.setName("Test: " + id.getId());
contentProviderUtils.insertTrack(track); contentProviderUtils.insertTrack(track);
track = contentProviderUtils.getTrack(id); track = contentProviderUtils.getTrack(id);
Assert.assertNotNull(track); assertNotNull(track);
TrackPoint[] trackPoints = new TrackPoint[numPoints]; TrackPoint[] trackPoints = new TrackPoint[numPoints];
for (int i = 0; i < numPoints; ++i) { for (int i = 0; i < numPoints; ++i) {
@@ -162,8 +166,8 @@ public class CustomContentProviderUtilsTest {
} }
} }
Assert.assertTrue(numPoints == 0 || lastPointId > 0); assertTrue(numPoints == 0 || lastPointId > 0);
Assert.assertEquals(numPoints, counter); assertEquals(numPoints, counter);
return lastPointId; return lastPointId;
} }
@@ -195,8 +199,8 @@ public class CustomContentProviderUtilsTest {
when(cursorMock.getString(columnIndex)).thenReturn(name); when(cursorMock.getString(columnIndex)).thenReturn(name);
Track track = contentProviderUtils.createTrack(cursorMock); Track track = contentProviderUtils.createTrack(cursorMock);
Assert.assertEquals(trackId, track.getId()); assertEquals(trackId, track.getId());
Assert.assertEquals(name, track.getName()); assertEquals(name, track.getName());
} }
/** /**
@@ -213,20 +217,20 @@ public class CustomContentProviderUtilsTest {
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(1, tracksCursor.getCount()); assertEquals(1, tracksCursor.getCount());
Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(10, tracksPointsCursor.getCount()); assertEquals(10, tracksPointsCursor.getCount());
Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(1, waypointCursor.getCount()); assertEquals(1, waypointCursor.getCount());
// Delete all. // Delete all.
contentProviderUtils.deleteAllTracks(context); contentProviderUtils.deleteAllTracks(context);
// Check whether all have been deleted. // Check whether all have been deleted.
tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(0, tracksCursor.getCount()); assertEquals(0, tracksCursor.getCount());
tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(0, tracksPointsCursor.getCount()); assertEquals(0, tracksPointsCursor.getCount());
waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(0, waypointCursor.getCount()); assertEquals(0, waypointCursor.getCount());
} }
/** /**
@@ -244,27 +248,27 @@ public class CustomContentProviderUtilsTest {
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(1, tracksCursor.getCount()); assertEquals(1, tracksCursor.getCount());
Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(10, tracksPointsCursor.getCount()); assertEquals(10, tracksPointsCursor.getCount());
Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(1, waypointCursor.getCount()); assertEquals(1, waypointCursor.getCount());
// Check waypoint has photo and it's in the external storage. // Check waypoint has photo and it's in the external storage.
Assert.assertTrue(waypoint.hasPhoto()); assertTrue(waypoint.hasPhoto());
File dir = FileUtils.getPhotoDir(context, trackId); File dir = FileUtils.getPhotoDir(context, trackId);
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(1, dir.list().length); assertEquals(1, dir.list().length);
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
// Delete all. // Delete all.
contentProviderUtils.deleteAllTracks(context); contentProviderUtils.deleteAllTracks(context);
// Check whether all have been deleted. // Check whether all have been deleted.
tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(0, tracksCursor.getCount()); assertEquals(0, tracksCursor.getCount());
tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(0, tracksPointsCursor.getCount()); assertEquals(0, tracksPointsCursor.getCount());
waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(0, waypointCursor.getCount()); assertEquals(0, waypointCursor.getCount());
Assert.assertFalse(dir.exists()); assertFalse(dir.exists());
} }
/** /**
@@ -289,20 +293,20 @@ public class CustomContentProviderUtilsTest {
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(3, tracksCursor.getCount()); assertEquals(3, tracksCursor.getCount());
Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(20, tracksPointsCursor.getCount()); assertEquals(20, tracksPointsCursor.getCount());
Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(1, waypointCursor.getCount()); assertEquals(1, waypointCursor.getCount());
// Delete one track. // Delete one track.
contentProviderUtils.deleteTrack(context, trackId1); contentProviderUtils.deleteTrack(context, trackId1);
// Check whether all data of a track has been deleted. // Check whether all data of a track has been deleted.
tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(2, tracksCursor.getCount()); assertEquals(2, tracksCursor.getCount());
tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(20, tracksPointsCursor.getCount()); assertEquals(20, tracksPointsCursor.getCount());
waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(0, waypointCursor.getCount()); assertEquals(0, waypointCursor.getCount());
} }
/** /**
@@ -334,29 +338,29 @@ public class CustomContentProviderUtilsTest {
// Check. // Check.
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(3, tracksCursor.getCount()); assertEquals(3, tracksCursor.getCount());
Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(30, tracksPointsCursor.getCount()); assertEquals(30, tracksPointsCursor.getCount());
Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(2, waypointCursor.getCount()); assertEquals(2, waypointCursor.getCount());
Assert.assertTrue(waypoint1.hasPhoto()); assertTrue(waypoint1.hasPhoto());
Assert.assertTrue(dir1.isDirectory()); assertTrue(dir1.isDirectory());
Assert.assertEquals(1, dir1.list().length); assertEquals(1, dir1.list().length);
Assert.assertTrue(dir1.exists()); assertTrue(dir1.exists());
Assert.assertTrue(dir2.isDirectory()); assertTrue(dir2.isDirectory());
Assert.assertEquals(1, dir2.list().length); assertEquals(1, dir2.list().length);
Assert.assertTrue(dir2.exists()); assertTrue(dir2.exists());
// Delete one track. // Delete one track.
contentProviderUtils.deleteTrack(context, trackId1); contentProviderUtils.deleteTrack(context, trackId1);
// Check whether all data of a track has been deleted. // Check whether all data of a track has been deleted.
tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID); tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
Assert.assertEquals(2, tracksCursor.getCount()); assertEquals(2, tracksCursor.getCount());
tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID); tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
Assert.assertEquals(20, tracksPointsCursor.getCount()); assertEquals(20, tracksPointsCursor.getCount());
waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID); waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
Assert.assertEquals(1, waypointCursor.getCount()); assertEquals(1, waypointCursor.getCount());
Assert.assertFalse(dir1.exists()); assertFalse(dir1.exists());
Assert.assertTrue(dir2.exists()); assertTrue(dir2.exists());
} }
/** /**
@@ -373,8 +377,8 @@ public class CustomContentProviderUtilsTest {
List<Track> allTracks = contentProviderUtils.getTracks(); List<Track> allTracks = contentProviderUtils.getTracks();
// then // then
Assert.assertEquals(initialTrackNumber + 1, allTracks.size()); assertEquals(initialTrackNumber + 1, allTracks.size());
Assert.assertEquals(trackId, allTracks.get(allTracks.size() - 1).getId()); assertEquals(trackId, allTracks.get(allTracks.size() - 1).getId());
} }
/** /**
@@ -384,7 +388,7 @@ public class CustomContentProviderUtilsTest {
public void testGetLastTrack() { public void testGetLastTrack() {
Track.Id trackId = new Track.Id(System.currentTimeMillis()); Track.Id trackId = new Track.Id(System.currentTimeMillis());
contentProviderUtils.insertTrack(TestDataUtil.createTrack(trackId)); contentProviderUtils.insertTrack(TestDataUtil.createTrack(trackId));
Assert.assertEquals(trackId, contentProviderUtils.getLastTrack().getId()); assertEquals(trackId, contentProviderUtils.getLastTrack().getId());
} }
/** /**
@@ -397,7 +401,7 @@ public class CustomContentProviderUtilsTest {
contentProviderUtils.insertTrack(TestDataUtil.createTrack(trackId)); contentProviderUtils.insertTrack(TestDataUtil.createTrack(trackId));
// when / then // when / then
Assert.assertNotNull(contentProviderUtils.getTrack(trackId)); assertNotNull(contentProviderUtils.getTrack(trackId));
} }
/** /**
@@ -411,7 +415,7 @@ public class CustomContentProviderUtilsTest {
contentProviderUtils.insertTrack(track); contentProviderUtils.insertTrack(track);
// when / then // when / then
Assert.assertNotNull(contentProviderUtils.getTrack(track.getUuid())); assertNotNull(contentProviderUtils.getTrack(track.getUuid()));
} }
/** /**
@@ -428,10 +432,10 @@ public class CustomContentProviderUtilsTest {
// when / then // when / then
contentProviderUtils.insertTrack(track); contentProviderUtils.insertTrack(track);
Assert.assertEquals(nameOld, contentProviderUtils.getTrack(trackId).getName()); assertEquals(nameOld, contentProviderUtils.getTrack(trackId).getName());
track.setName(nameNew); track.setName(nameNew);
contentProviderUtils.updateTrack(track); contentProviderUtils.updateTrack(track);
Assert.assertEquals(nameNew, contentProviderUtils.getTrack(trackId).getName()); assertEquals(nameNew, contentProviderUtils.getTrack(trackId).getName());
} }
/** /**
@@ -468,9 +472,9 @@ public class CustomContentProviderUtilsTest {
Waypoint.Id waypointId = new Waypoint.Id(System.currentTimeMillis()); Waypoint.Id waypointId = new Waypoint.Id(System.currentTimeMillis());
waypoint.setId(waypointId); waypoint.setId(waypointId);
ContentValues contentValues = contentProviderUtils.createContentValues(waypoint); ContentValues contentValues = contentProviderUtils.createContentValues(waypoint);
Assert.assertEquals(waypointId.getId(), contentValues.get(WaypointsColumns._ID)); assertEquals(waypointId.getId(), contentValues.get(WaypointsColumns._ID));
Assert.assertEquals((int) (TestDataUtil.INITIAL_LONGITUDE * 1000000), contentValues.get(WaypointsColumns.LONGITUDE)); assertEquals((int) (TestDataUtil.INITIAL_LONGITUDE * 1000000), contentValues.get(WaypointsColumns.LONGITUDE));
Assert.assertEquals(TEST_DESC, contentValues.get(WaypointsColumns.DESCRIPTION)); assertEquals(TEST_DESC, contentValues.get(WaypointsColumns.DESCRIPTION));
} }
/** /**
@@ -502,9 +506,9 @@ public class CustomContentProviderUtilsTest {
when(cursorMock.getLong(columnIndex++)).thenReturn(trackId); when(cursorMock.getLong(columnIndex++)).thenReturn(trackId);
Waypoint waypoint = contentProviderUtils.createWaypoint(cursorMock); Waypoint waypoint = contentProviderUtils.createWaypoint(cursorMock);
Assert.assertEquals(id, waypoint.getId().getId()); assertEquals(id, waypoint.getId().getId());
Assert.assertEquals(name, waypoint.getName()); assertEquals(name, waypoint.getName());
Assert.assertEquals(trackId, waypoint.getTrackId().getId()); assertEquals(trackId, waypoint.getTrackId().getId());
} }
/** /**
@@ -524,7 +528,7 @@ public class CustomContentProviderUtilsTest {
contentProviderUtils.insertWaypoint(waypoint1); contentProviderUtils.insertWaypoint(waypoint1);
// Check insert was done. // Check insert was done.
Assert.assertEquals(contentProviderUtils.getWaypointCount(trackId), 1); assertEquals(contentProviderUtils.getWaypointCount(trackId), 1);
// Get waypoint id that needs to delete. // Get waypoint id that needs to delete.
Waypoint.Id waypoint1Id = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint1))); Waypoint.Id waypoint1Id = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint1)));
@@ -532,7 +536,7 @@ public class CustomContentProviderUtilsTest {
// Delete // Delete
contentProviderUtils.deleteWaypoint(context, waypoint1Id); contentProviderUtils.deleteWaypoint(context, waypoint1Id);
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id)); assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
} }
/** /**
@@ -551,24 +555,24 @@ public class CustomContentProviderUtilsTest {
contentProviderUtils.insertWaypoint(waypoint1); contentProviderUtils.insertWaypoint(waypoint1);
// Check insert was done. // Check insert was done.
Assert.assertEquals(contentProviderUtils.getWaypointCount(trackId), 1); assertEquals(contentProviderUtils.getWaypointCount(trackId), 1);
// Get waypoint id that needs to delete. // Get waypoint id that needs to delete.
Waypoint.Id waypoint1Id = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint1))); Waypoint.Id waypoint1Id = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint1)));
// Check waypoint has photo and it's in the external storage. // Check waypoint has photo and it's in the external storage.
Assert.assertTrue(waypoint1.hasPhoto()); assertTrue(waypoint1.hasPhoto());
File dir = FileUtils.getPhotoDir(context, trackId); File dir = FileUtils.getPhotoDir(context, trackId);
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(1, dir.list().length); assertEquals(1, dir.list().length);
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
// Delete // Delete
contentProviderUtils.deleteWaypoint(context, waypoint1Id); contentProviderUtils.deleteWaypoint(context, waypoint1Id);
// Check waypoint doesn't exists and photo folder was deleted. // Check waypoint doesn't exists and photo folder was deleted.
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id)); assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
Assert.assertFalse(dir.exists()); assertFalse(dir.exists());
} }
/** /**
@@ -607,11 +611,11 @@ public class CustomContentProviderUtilsTest {
Waypoint.Id waypoint2Id = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint2))); Waypoint.Id waypoint2Id = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint2)));
// Delete // Delete
Assert.assertNotNull(contentProviderUtils.getWaypoint(waypoint1Id)); assertNotNull(contentProviderUtils.getWaypoint(waypoint1Id));
contentProviderUtils.deleteWaypoint(context, waypoint1Id); contentProviderUtils.deleteWaypoint(context, waypoint1Id);
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id)); assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
Assert.assertEquals(MOCK_DESC, contentProviderUtils.getWaypoint(waypoint2Id).getDescription()); assertEquals(MOCK_DESC, contentProviderUtils.getWaypoint(waypoint2Id).getDescription());
} }
/** /**
@@ -635,7 +639,7 @@ public class CustomContentProviderUtilsTest {
contentProviderUtils.insertWaypoint(waypoint3); contentProviderUtils.insertWaypoint(waypoint3);
contentProviderUtils.insertWaypoint(waypoint4); contentProviderUtils.insertWaypoint(waypoint4);
Assert.assertEquals(4, contentProviderUtils.getNextWaypointNumber(trackId)); assertEquals(4, contentProviderUtils.getNextWaypointNumber(trackId));
} }
/** /**
@@ -652,7 +656,7 @@ public class CustomContentProviderUtilsTest {
waypoint.setTrackId(trackId); waypoint.setTrackId(trackId);
Waypoint.Id waypointId = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint))); Waypoint.Id waypointId = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint)));
Assert.assertEquals(TEST_DESC, contentProviderUtils.getWaypoint(waypointId).getDescription()); assertEquals(TEST_DESC, contentProviderUtils.getWaypoint(waypointId).getDescription());
} }
/** /**
@@ -674,7 +678,7 @@ public class CustomContentProviderUtilsTest {
waypoint.setDescription(TEST_DESC_NEW); waypoint.setDescription(TEST_DESC_NEW);
contentProviderUtils.updateWaypoint(context, waypoint); contentProviderUtils.updateWaypoint(context, waypoint);
Assert.assertEquals(TEST_DESC_NEW, contentProviderUtils.getWaypoint(waypointId).getDescription()); assertEquals(TEST_DESC_NEW, contentProviderUtils.getWaypoint(waypointId).getDescription());
} }
/** /**
@@ -695,9 +699,9 @@ public class CustomContentProviderUtilsTest {
Waypoint.Id waypointId = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint))); Waypoint.Id waypointId = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint)));
File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.getId()); File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.getId());
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(1, dir.list().length); assertEquals(1, dir.list().length);
// Update // Update
waypoint = contentProviderUtils.getWaypoint(waypointId); waypoint = contentProviderUtils.getWaypoint(waypointId);
@@ -705,12 +709,12 @@ public class CustomContentProviderUtilsTest {
waypoint.setDescription(TEST_DESC_NEW); waypoint.setDescription(TEST_DESC_NEW);
contentProviderUtils.updateWaypoint(context, waypoint); contentProviderUtils.updateWaypoint(context, waypoint);
Assert.assertEquals(TEST_NAME_NEW, contentProviderUtils.getWaypoint(waypointId).getName()); assertEquals(TEST_NAME_NEW, contentProviderUtils.getWaypoint(waypointId).getName());
Assert.assertEquals(TEST_DESC_NEW, contentProviderUtils.getWaypoint(waypointId).getDescription()); assertEquals(TEST_DESC_NEW, contentProviderUtils.getWaypoint(waypointId).getDescription());
Assert.assertTrue(waypoint.hasPhoto()); assertTrue(waypoint.hasPhoto());
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(1, dir.list().length); assertEquals(1, dir.list().length);
} }
/** /**
@@ -731,9 +735,9 @@ public class CustomContentProviderUtilsTest {
Waypoint.Id waypointId = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint))); Waypoint.Id waypointId = new Waypoint.Id(ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint)));
File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.getId()); File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.getId());
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(1, dir.list().length); assertEquals(1, dir.list().length);
// Update // Update
waypoint = contentProviderUtils.getWaypoint(waypointId); waypoint = contentProviderUtils.getWaypoint(waypointId);
@@ -742,10 +746,10 @@ public class CustomContentProviderUtilsTest {
waypoint.setPhotoUrl(null); waypoint.setPhotoUrl(null);
contentProviderUtils.updateWaypoint(context, waypoint); contentProviderUtils.updateWaypoint(context, waypoint);
Assert.assertEquals(TEST_NAME_NEW, contentProviderUtils.getWaypoint(waypointId).getName()); assertEquals(TEST_NAME_NEW, contentProviderUtils.getWaypoint(waypointId).getName());
Assert.assertEquals(TEST_DESC_NEW, contentProviderUtils.getWaypoint(waypointId).getDescription()); assertEquals(TEST_DESC_NEW, contentProviderUtils.getWaypoint(waypointId).getDescription());
Assert.assertFalse(waypoint.hasPhoto()); assertFalse(waypoint.hasPhoto());
Assert.assertFalse(dir.exists()); assertFalse(dir.exists());
} }
/** /**
@@ -770,20 +774,20 @@ public class CustomContentProviderUtilsTest {
contentProviderUtils.insertWaypoint(otherWaypoint); contentProviderUtils.insertWaypoint(otherWaypoint);
File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.getId()); File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.getId());
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(2, dir.list().length); assertEquals(2, dir.list().length);
// Update one waypoint deleting photo. // Update one waypoint deleting photo.
waypoint = contentProviderUtils.getWaypoint(waypointId); waypoint = contentProviderUtils.getWaypoint(waypointId);
waypoint.setPhotoUrl(null); waypoint.setPhotoUrl(null);
contentProviderUtils.updateWaypoint(context, waypoint); contentProviderUtils.updateWaypoint(context, waypoint);
Assert.assertEquals(TEST_DESC, contentProviderUtils.getWaypoint(waypointId).getDescription()); assertEquals(TEST_DESC, contentProviderUtils.getWaypoint(waypointId).getDescription());
Assert.assertFalse(waypoint.hasPhoto()); assertFalse(waypoint.hasPhoto());
Assert.assertTrue(dir.exists()); assertTrue(dir.exists());
Assert.assertTrue(dir.isDirectory()); assertTrue(dir.isDirectory());
Assert.assertEquals(1, dir.list().length); assertEquals(1, dir.list().length);
} }
/** /**
@@ -798,9 +802,9 @@ public class CustomContentProviderUtilsTest {
// when / then // when / then
contentProviderUtils.bulkInsertTrackPoint(track.second, trackId); contentProviderUtils.bulkInsertTrackPoint(track.second, trackId);
Assert.assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount());
contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(track.second, 0, 8), trackId); contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(track.second, 0, 8), trackId);
Assert.assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount());
} }
/** /**
@@ -839,11 +843,11 @@ public class CustomContentProviderUtilsTest {
TrackPoint trackPoint = contentProviderUtils.createTrackPoint(cursorMock); TrackPoint trackPoint = contentProviderUtils.createTrackPoint(cursorMock);
// then // then
Assert.assertEquals(longitude, trackPoint.getLongitude(), 0.01); assertEquals(longitude, trackPoint.getLongitude(), 0.01);
Assert.assertEquals(latitude, trackPoint.getLatitude(), 0.01); assertEquals(latitude, trackPoint.getLatitude(), 0.01);
Assert.assertEquals(time, trackPoint.getTime(), 0.01); assertEquals(time, trackPoint.getTime(), 0.01);
Assert.assertEquals(speed, trackPoint.getSpeed(), 0.01); assertEquals(speed, trackPoint.getSpeed(), 0.01);
Assert.assertFalse(trackPoint.hasHeartRate()); assertFalse(trackPoint.hasHeartRate());
} }
/** /**
@@ -857,7 +861,7 @@ public class CustomContentProviderUtilsTest {
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10); Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
contentProviderUtils.insertTrackPoint(TestDataUtil.createTrackPoint(22), trackId); contentProviderUtils.insertTrackPoint(TestDataUtil.createTrackPoint(22), trackId);
Assert.assertEquals(11, contentProviderUtils.getTrackPoints(trackId).size()); assertEquals(11, contentProviderUtils.getTrackPoints(trackId).size());
} }
@Test @Test
@@ -876,10 +880,10 @@ public class CustomContentProviderUtilsTest {
// then // then
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertTrue(trackPoints.get(10).hasHeartRate()); assertTrue(trackPoints.get(10).hasHeartRate());
Assert.assertEquals(trackPoint.getHeartRate_bpm(), trackPoints.get(10).getHeartRate_bpm(), 0.01); assertEquals(trackPoint.getHeartRate_bpm(), trackPoints.get(10).getHeartRate_bpm(), 0.01);
Assert.assertEquals(trackPoint.getCyclingCadence_rpm(), trackPoints.get(10).getCyclingCadence_rpm(), 0.01); assertEquals(trackPoint.getCyclingCadence_rpm(), trackPoints.get(10).getCyclingCadence_rpm(), 0.01);
Assert.assertEquals(trackPoint.getPower(), trackPoints.get(10).getPower(), 0.01); assertEquals(trackPoint.getPower(), trackPoints.get(10).getPower(), 0.01);
} }
/** /**
@@ -914,7 +918,7 @@ public class CustomContentProviderUtilsTest {
Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[1], 5, true); Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[1], 5, true);
// then // then
Assert.assertEquals(2, cursor.getCount()); assertEquals(2, cursor.getCount());
} }
/** /**
@@ -936,7 +940,7 @@ public class CustomContentProviderUtilsTest {
Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5, false); Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5, false);
// then // then
Assert.assertEquals(2, cursor.getCount()); assertEquals(2, cursor.getCount());
} }
/** /**
@@ -960,12 +964,12 @@ public class CustomContentProviderUtilsTest {
// then // then
for (int i = 0; i < trackpointIds.length; i++) { for (int i = 0; i < trackpointIds.length; i++) {
Assert.assertTrue(trackPointIterator.hasNext()); assertTrue(trackPointIterator.hasNext());
TrackPoint trackPoint = trackPointIterator.next(); TrackPoint trackPoint = trackPointIterator.next();
Assert.assertEquals(startTrackPointId - i, trackPointIterator.getTrackPointId()); assertEquals(startTrackPointId - i, trackPointIterator.getTrackPointId());
checkLocation((trackpointIds.length - 1) - i, trackPoint.getLocation()); checkLocation((trackpointIds.length - 1) - i, trackPoint.getLocation());
} }
Assert.assertFalse(trackPointIterator.hasNext()); assertFalse(trackPointIterator.hasNext());
} }
/** /**
@@ -990,13 +994,13 @@ public class CustomContentProviderUtilsTest {
// then // then
for (int i = 0; i < trackpointIds.length; i++) { for (int i = 0; i < trackpointIds.length; i++) {
Assert.assertTrue(trackPointIterator.hasNext()); assertTrue(trackPointIterator.hasNext());
TrackPoint trackPoint = trackPointIterator.next(); TrackPoint trackPoint = trackPointIterator.next();
Assert.assertEquals(startTrackPointId + i, trackPointIterator.getTrackPointId()); assertEquals(startTrackPointId + i, trackPointIterator.getTrackPointId());
checkLocation(i, trackPoint.getLocation()); checkLocation(i, trackPoint.getLocation());
} }
Assert.assertFalse(trackPointIterator.hasNext()); assertFalse(trackPointIterator.hasNext());
} }
/** /**
@@ -1006,16 +1010,16 @@ public class CustomContentProviderUtilsTest {
* @param location the location to be checked * @param location the location to be checked
*/ */
private void checkLocation(int i, Location location) { private void checkLocation(int i, Location location) {
Assert.assertEquals(TestDataUtil.INITIAL_LATITUDE + (double) i / 10000.0, location.getLatitude(), 0.01); assertEquals(TestDataUtil.INITIAL_LATITUDE + (double) i / 10000.0, location.getLatitude(), 0.01);
Assert.assertEquals(TestDataUtil.INITIAL_LONGITUDE - (double) i / 10000.0, location.getLongitude(), 0.01); assertEquals(TestDataUtil.INITIAL_LONGITUDE - (double) i / 10000.0, location.getLongitude(), 0.01);
Assert.assertEquals((float) i / 100.0f, location.getAccuracy(), 0.01); assertEquals((float) i / 100.0f, location.getAccuracy(), 0.01);
Assert.assertEquals(i * TestDataUtil.ALTITUDE_INTERVAL, location.getAltitude(), 0.01); assertEquals(i * TestDataUtil.ALTITUDE_INTERVAL, location.getAltitude(), 0.01);
} }
@Test @Test
public void testFormatIdListForUri() { public void testFormatIdListForUri() {
Assert.assertEquals("", ContentProviderUtils.formatIdListForUri()); assertEquals("", ContentProviderUtils.formatIdListForUri());
Assert.assertEquals("12", ContentProviderUtils.formatIdListForUri(new Track.Id(12))); assertEquals("12", ContentProviderUtils.formatIdListForUri(new Track.Id(12)));
Assert.assertEquals("42,43,44", ContentProviderUtils.formatIdListForUri(new Track.Id(42), new Track.Id(43), new Track.Id(44))); assertEquals("42,43,44", ContentProviderUtils.formatIdListForUri(new Track.Id(42), new Track.Id(43), new Track.Id(44)));
} }
} }
@@ -3,7 +3,6 @@ package de.dennisguse.opentracks.content.provider;
import android.net.Uri; import android.net.Uri;
import android.util.Pair; import android.util.Pair;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.HashSet; import java.util.HashSet;
@@ -12,17 +11,19 @@ import java.util.Set;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.TrackFileFormat;
import static org.junit.Assert.assertEquals;
public class ShareContentProviderTest { public class ShareContentProviderTest {
@Test @Test
public void testCreateandParseURI_invalid() { public void testCreateAndParseURI_invalid() {
Uri uri = Uri.parse("content://de.dennisguse.opentracks.debug.content/tracks/1"); Uri uri = Uri.parse("content://de.dennisguse.opentracks.debug.content/tracks/1");
Assert.assertEquals(0, ShareContentProvider.parseURI(uri).size()); assertEquals(0, ShareContentProvider.parseURI(uri).size());
} }
@Test @Test
public void testCreateandParseURI_valid() { public void testCreateAndParseURI_valid() {
Set<Track.Id> trackIds = new HashSet<>(); Set<Track.Id> trackIds = new HashSet<>();
trackIds.add(new Track.Id(1)); trackIds.add(new Track.Id(1));
trackIds.add(new Track.Id(3)); trackIds.add(new Track.Id(3));
@@ -30,7 +31,7 @@ public class ShareContentProviderTest {
Pair<Uri, String> shareURIandMIME = ShareContentProvider.createURI(trackIds, "TrackName", TrackFileFormat.KML_ONLY_TRACK); Pair<Uri, String> shareURIandMIME = ShareContentProvider.createURI(trackIds, "TrackName", TrackFileFormat.KML_ONLY_TRACK);
Assert.assertEquals(trackIds, ShareContentProvider.parseURI(shareURIandMIME.first)); assertEquals(trackIds, ShareContentProvider.parseURI(shareURIandMIME.first));
} }
@Test @Test
@@ -39,6 +40,6 @@ public class ShareContentProviderTest {
trackIds.add(new Track.Id(1)); trackIds.add(new Track.Id(1));
Pair<Uri, String> shareURIandMIME = ShareContentProvider.createURI(trackIds, "../../&1=1", TrackFileFormat.KML_ONLY_TRACK); Pair<Uri, String> shareURIandMIME = ShareContentProvider.createURI(trackIds, "../../&1=1", TrackFileFormat.KML_ONLY_TRACK);
Assert.assertEquals(Uri.parse("content://de.dennisguse.opentracks.debug.content/tracks/kml_only_track/1/..%2F..%2F%261%3D1.kml"), shareURIandMIME.first); assertEquals(Uri.parse("content://de.dennisguse.opentracks.debug.content/tracks/kml_only_track/1/..%2F..%2F%261%3D1.kml"), shareURIandMIME.first);
} }
} }
@@ -2,12 +2,14 @@ package de.dennisguse.opentracks.content.sensor;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import de.dennisguse.opentracks.util.UintUtils; import de.dennisguse.opentracks.util.UintUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class SensorDataCyclingTest { public class SensorDataCyclingTest {
@@ -21,7 +23,7 @@ public class SensorDataCyclingTest {
current.compute(previous); current.compute(previous);
// then // then
Assert.assertEquals(60, current.getCadence_rpm(), 0.01); assertEquals(60, current.getCadence_rpm(), 0.01);
} }
@Test @Test
@@ -34,7 +36,7 @@ public class SensorDataCyclingTest {
current.compute(previous); current.compute(previous);
// then // then
Assert.assertEquals(33.53, current.getCadence_rpm(), 0.01); assertEquals(33.53, current.getCadence_rpm(), 0.01);
} }
@Test @Test
@@ -47,7 +49,7 @@ public class SensorDataCyclingTest {
current.compute(previous); current.compute(previous);
// then // then
Assert.assertEquals(0, current.getCadence_rpm(), 0.01); assertEquals(0, current.getCadence_rpm(), 0.01);
} }
@@ -61,7 +63,7 @@ public class SensorDataCyclingTest {
current.compute(previous); current.compute(previous);
// then // then
Assert.assertFalse(current.hasCadence_rpm()); assertFalse(current.hasCadence_rpm());
} }
@Test @Test
@@ -74,7 +76,7 @@ public class SensorDataCyclingTest {
current.compute(previous); current.compute(previous);
// then // then
Assert.assertEquals(60, current.getCadence_rpm(), 0.01); assertEquals(60, current.getCadence_rpm(), 0.01);
} }
@Test @Test
@@ -87,7 +89,7 @@ public class SensorDataCyclingTest {
current.compute(previous); current.compute(previous);
// then // then
Assert.assertEquals(60, current.getCadence_rpm(), 0.01); assertEquals(60, current.getCadence_rpm(), 0.01);
} }
@Test @Test
@@ -100,7 +102,7 @@ public class SensorDataCyclingTest {
current.compute(previous, 2150); current.compute(previous, 2150);
// then // then
Assert.assertEquals(1.20, current.getSpeed_mps(), 0.01); assertEquals(1.20, current.getSpeed_mps(), 0.01);
} }
@Test @Test
@@ -113,6 +115,6 @@ public class SensorDataCyclingTest {
current.compute(previous, 2000); current.compute(previous, 2000);
// then // then
Assert.assertEquals(2, current.getSpeed_mps(), 0.01); assertEquals(2, current.getSpeed_mps(), 0.01);
} }
} }
@@ -23,7 +23,6 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@@ -35,6 +34,8 @@ import de.dennisguse.opentracks.chart.ChartView;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.util.UnitConversions; import de.dennisguse.opentracks.util.UnitConversions;
import static org.junit.Assert.assertEquals;
/** /**
* Tests {@link ChartFragment}. * Tests {@link ChartFragment}.
* *
@@ -78,9 +79,9 @@ public class ChartFragmentTest {
ChartPoint point = chartFragment.createPendingPoint(trackPoint); ChartPoint point = chartFragment.createPendingPoint(trackPoint);
// then // then
Assert.assertEquals(Float.NaN, point.getHeartRate(), 0.01); assertEquals(Float.NaN, point.getHeartRate(), 0.01);
Assert.assertEquals(Float.NaN, point.getCadence(), 0.01); assertEquals(Float.NaN, point.getCadence(), 0.01);
Assert.assertEquals(Float.NaN, point.getPower(), 0.01); assertEquals(Float.NaN, point.getPower(), 0.01);
} }
/** /**
@@ -98,9 +99,9 @@ public class ChartFragmentTest {
ChartPoint point = chartFragment.createPendingPoint(trackPoint); ChartPoint point = chartFragment.createPendingPoint(trackPoint);
// then // then
Assert.assertEquals(100.0, point.getHeartRate(), 0.01); assertEquals(100.0, point.getHeartRate(), 0.01);
Assert.assertEquals(101.0, point.getCadence(), 0.01); assertEquals(101.0, point.getCadence(), 0.01);
Assert.assertEquals(102.0, point.getPower(), 0.01); assertEquals(102.0, point.getPower(), 0.01);
} }
/** /**
@@ -112,12 +113,12 @@ public class ChartFragmentTest {
// Resets last location and writes first location. // Resets last location and writes first location.
TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint();
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(0.0, point.getTimeOrDistance(), 0.01); assertEquals(0.0, point.getTimeOrDistance(), 0.01);
// The second is a same location, just different time. // The second is a same location, just different time.
TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint();
point = chartFragment.createPendingPoint(trackPoint2); point = chartFragment.createPendingPoint(trackPoint2);
Assert.assertEquals(0.0, point.getTimeOrDistance(), 0.01); assertEquals(0.0, point.getTimeOrDistance(), 0.01);
// The third location is a new location, and use metric. // The third location is a new location, and use metric.
TrackPoint trackPoint3 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint3 = TrackStubUtils.createDefaultTrackPoint();
@@ -129,7 +130,7 @@ public class ChartFragmentTest {
Location.distanceBetween(trackPoint2.getLatitude(), trackPoint2.getLongitude(), Location.distanceBetween(trackPoint2.getLatitude(), trackPoint2.getLongitude(),
trackPoint3.getLatitude(), trackPoint3.getLongitude(), results); trackPoint3.getLatitude(), trackPoint3.getLongitude(), results);
double distance1 = results[0] * UnitConversions.M_TO_KM; double distance1 = results[0] * UnitConversions.M_TO_KM;
Assert.assertEquals(distance1, point.getTimeOrDistance(), 0.01); assertEquals(distance1, point.getTimeOrDistance(), 0.01);
// The fourth location is a new location, and use metric. // The fourth location is a new location, and use metric.
TrackPoint trackPoint4 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint4 = TrackStubUtils.createDefaultTrackPoint();
@@ -140,7 +141,7 @@ public class ChartFragmentTest {
Location.distanceBetween(trackPoint3.getLatitude(), trackPoint3.getLongitude(), Location.distanceBetween(trackPoint3.getLatitude(), trackPoint3.getLongitude(),
trackPoint4.getLatitude(), trackPoint4.getLongitude(), results); trackPoint4.getLatitude(), trackPoint4.getLongitude(), results);
double distance2 = results[0] * UnitConversions.M_TO_KM; double distance2 = results[0] * UnitConversions.M_TO_KM;
Assert.assertEquals((distance1 + distance2), point.getTimeOrDistance(), 0.01); assertEquals((distance1 + distance2), point.getTimeOrDistance(), 0.01);
} }
/** /**
@@ -156,7 +157,7 @@ public class ChartFragmentTest {
// The first is a same location, just different time. // The first is a same location, just different time.
TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint();
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(0.0, point.getTimeOrDistance(), 0.01); assertEquals(0.0, point.getTimeOrDistance(), 0.01);
// The second location is a new location, and use imperial. // The second location is a new location, and use imperial.
TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint();
@@ -170,7 +171,7 @@ public class ChartFragmentTest {
float[] results = new float[4]; float[] results = new float[4];
Location.distanceBetween(trackPoint1.getLatitude(), trackPoint1.getLongitude(), trackPoint2.getLatitude(), trackPoint2.getLongitude(), results); Location.distanceBetween(trackPoint1.getLatitude(), trackPoint1.getLongitude(), trackPoint2.getLatitude(), trackPoint2.getLongitude(), results);
double distance1 = results[0] * UnitConversions.M_TO_KM * UnitConversions.KM_TO_MI; double distance1 = results[0] * UnitConversions.M_TO_KM * UnitConversions.KM_TO_MI;
Assert.assertEquals(distance1, point.getTimeOrDistance(), 0.01); assertEquals(distance1, point.getTimeOrDistance(), 0.01);
// The third location is a new location, and use imperial. // The third location is a new location, and use imperial.
TrackPoint trackPoint3 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint3 = TrackStubUtils.createDefaultTrackPoint();
@@ -183,7 +184,7 @@ public class ChartFragmentTest {
*/ */
Location.distanceBetween(trackPoint2.getLatitude(), trackPoint2.getLongitude(), trackPoint3.getLatitude(), trackPoint3.getLongitude(), results); Location.distanceBetween(trackPoint2.getLatitude(), trackPoint2.getLongitude(), trackPoint3.getLatitude(), trackPoint3.getLongitude(), results);
double distance2 = results[0] * UnitConversions.M_TO_KM * UnitConversions.KM_TO_MI; double distance2 = results[0] * UnitConversions.M_TO_KM * UnitConversions.KM_TO_MI;
Assert.assertEquals(distance1 + distance2, point.getTimeOrDistance(), 0.01); assertEquals(distance1 + distance2, point.getTimeOrDistance(), 0.01);
} }
/** /**
@@ -194,12 +195,12 @@ public class ChartFragmentTest {
chartFragment.setChartByDistance(false); chartFragment.setChartByDistance(false);
TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint();
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(0.0, point.getTimeOrDistance(), 0.01); assertEquals(0.0, point.getTimeOrDistance(), 0.01);
long timeSpan = 222; long timeSpan = 222;
TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint();
trackPoint2.setTime(trackPoint1.getTime() + timeSpan); trackPoint2.setTime(trackPoint1.getTime() + timeSpan);
point = chartFragment.createPendingPoint(trackPoint2); point = chartFragment.createPendingPoint(trackPoint2);
Assert.assertEquals((double) timeSpan, point.getTimeOrDistance(), 0.01); assertEquals((double) timeSpan, point.getTimeOrDistance(), 0.01);
} }
/** /**
@@ -214,7 +215,7 @@ public class ChartFragmentTest {
* Then only one value INITIAL_ALTITUDE in buffer. * Then only one value INITIAL_ALTITUDE in buffer.
*/ */
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(TrackStubUtils.INITIAL_ALTITUDE, point.getElevation(), 0.01); assertEquals(TrackStubUtils.INITIAL_ALTITUDE, point.getElevation(), 0.01);
/* /*
* Send another value to buffer, now there are two values, INITIAL_ALTITUDE and INITIAL_ALTITUDE * 2. * Send another value to buffer, now there are two values, INITIAL_ALTITUDE and INITIAL_ALTITUDE * 2.
@@ -222,7 +223,7 @@ public class ChartFragmentTest {
TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint();
trackPoint2.setAltitude(TrackStubUtils.INITIAL_ALTITUDE * 2); trackPoint2.setAltitude(TrackStubUtils.INITIAL_ALTITUDE * 2);
point = chartFragment.createPendingPoint(trackPoint2); point = chartFragment.createPendingPoint(trackPoint2);
Assert.assertEquals((TrackStubUtils.INITIAL_ALTITUDE + TrackStubUtils.INITIAL_ALTITUDE * 2) / 2.0, point.getElevation(), 0.01); assertEquals((TrackStubUtils.INITIAL_ALTITUDE + TrackStubUtils.INITIAL_ALTITUDE * 2) / 2.0, point.getElevation(), 0.01);
} }
/** /**
@@ -239,7 +240,7 @@ public class ChartFragmentTest {
TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint();
trackPoint1.setSpeed(128.5f); trackPoint1.setSpeed(128.5f);
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(0.0, point.getSpeed(), 0.01); assertEquals(0.0, point.getSpeed(), 0.01);
/* /*
* Tests the logic when both metricUnits and reportSpeed are true. * Tests the logic when both metricUnits and reportSpeed are true.
@@ -253,7 +254,7 @@ public class ChartFragmentTest {
trackPoint2.setTime(trackPoint1.getTime() + 222); trackPoint2.setTime(trackPoint1.getTime() + 222);
trackPoint2.setSpeed(130); trackPoint2.setSpeed(130);
point = chartFragment.createPendingPoint(trackPoint2); point = chartFragment.createPendingPoint(trackPoint2);
Assert.assertEquals(130.0 * UnitConversions.MPS_TO_KMH, point.getSpeed(), 0.01); assertEquals(130.0 * UnitConversions.MPS_TO_KMH, point.getSpeed(), 0.01);
} }
/** /**
@@ -267,7 +268,7 @@ public class ChartFragmentTest {
TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint();
trackPoint1.setSpeed(100.0f); trackPoint1.setSpeed(100.0f);
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(0.0, point.getSpeed(), 0.01); assertEquals(0.0, point.getSpeed(), 0.01);
TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint();
@@ -278,7 +279,7 @@ public class ChartFragmentTest {
trackPoint2.setTime(trackPoint2.getTime() + 222); trackPoint2.setTime(trackPoint2.getTime() + 222);
trackPoint2.setSpeed(102); trackPoint2.setSpeed(102);
point = chartFragment.createPendingPoint(trackPoint2); point = chartFragment.createPendingPoint(trackPoint2);
Assert.assertEquals(102.0 * UnitConversions.MPS_TO_KMH * UnitConversions.KM_TO_MI, point.getSpeed(), 0.01); assertEquals(102.0 * UnitConversions.MPS_TO_KMH * UnitConversions.KM_TO_MI, point.getSpeed(), 0.01);
} }
/** /**
@@ -292,7 +293,7 @@ public class ChartFragmentTest {
TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint1 = TrackStubUtils.createDefaultTrackPoint();
trackPoint1.setSpeed(100.0f); trackPoint1.setSpeed(100.0f);
ChartPoint point = chartFragment.createPendingPoint(trackPoint1); ChartPoint point = chartFragment.createPendingPoint(trackPoint1);
Assert.assertEquals(0.0, point.getSpeed(), 0.01); assertEquals(0.0, point.getSpeed(), 0.01);
TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint2 = TrackStubUtils.createDefaultTrackPoint();
@@ -303,7 +304,7 @@ public class ChartFragmentTest {
trackPoint2.setTime(trackPoint2.getTime() + 222); trackPoint2.setTime(trackPoint2.getTime() + 222);
trackPoint2.setSpeed(102); trackPoint2.setSpeed(102);
point = chartFragment.createPendingPoint(trackPoint2); point = chartFragment.createPendingPoint(trackPoint2);
Assert.assertEquals(HOURS_PER_UNIT / (102.0 * UnitConversions.MPS_TO_KMH), point.getPace(), 0.01); assertEquals(HOURS_PER_UNIT / (102.0 * UnitConversions.MPS_TO_KMH), point.getPace(), 0.01);
} }
/** /**
@@ -315,6 +316,6 @@ public class ChartFragmentTest {
TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint(); TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint();
trackPoint.setSpeed(0); trackPoint.setSpeed(0);
ChartPoint point = chartFragment.createPendingPoint(trackPoint); ChartPoint point = chartFragment.createPendingPoint(trackPoint);
Assert.assertEquals(0.0, point.getPace(), 0.01); assertEquals(0.0, point.getPace(), 0.01);
} }
} }
@@ -24,7 +24,6 @@ import android.net.Uri;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import org.junit.Assert;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
@@ -39,6 +38,7 @@ import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.WaypointsColumns; import de.dennisguse.opentracks.content.data.WaypointsColumns;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -122,10 +122,10 @@ public abstract class AbstractTestFileTrackImporter {
} }
protected void verifyTrack(Track track, String name, String description, long time) { protected void verifyTrack(Track track, String name, String description, long time) {
Assert.assertEquals(name, track.getName()); assertEquals(name, track.getName());
Assert.assertEquals(description, track.getDescription()); assertEquals(description, track.getDescription());
if (time != -1L) { if (time != -1L) {
Assert.assertEquals(time, track.getTrackStatistics().getStartTime_ms()); assertEquals(time, track.getTrackStatistics().getStartTime_ms());
} }
} }
} }
@@ -15,7 +15,6 @@
*/ */
package de.dennisguse.opentracks.services; package de.dennisguse.opentracks.services;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -23,6 +22,8 @@ import org.junit.runners.JUnit4;
import de.dennisguse.opentracks.services.handlers.AdaptiveLocationListenerPolicy; import de.dennisguse.opentracks.services.handlers.AdaptiveLocationListenerPolicy;
import static org.junit.Assert.assertEquals;
/** /**
* Tests the {@link AdaptiveLocationListenerPolicy}. * Tests the {@link AdaptiveLocationListenerPolicy}.
* *
@@ -57,17 +58,17 @@ public class AdaptiveLocationListenerPolicyTest {
@Test @Test
public void testGetDesiredPollingInterval() { public void testGetDesiredPollingInterval() {
adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_BIG); adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_BIG);
Assert.assertEquals(MAX, adaptiveLocationListenerPolicy.getDesiredPollingInterval()); assertEquals(MAX, adaptiveLocationListenerPolicy.getDesiredPollingInterval());
adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_NORMAL); adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_NORMAL);
// First get the half of NEW_IDLE_TIME_NORMAL, and then round it to the nearest second. // First get the half of NEW_IDLE_TIME_NORMAL, and then round it to the nearest second.
Assert.assertEquals((NEW_IDLE_TIME_NORMAL / 2 / 1000) * 1000, adaptiveLocationListenerPolicy.getDesiredPollingInterval()); assertEquals((NEW_IDLE_TIME_NORMAL / 2 / 1000) * 1000, adaptiveLocationListenerPolicy.getDesiredPollingInterval());
adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_SMALL); adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_SMALL);
Assert.assertEquals(MIN, adaptiveLocationListenerPolicy.getDesiredPollingInterval()); assertEquals(MIN, adaptiveLocationListenerPolicy.getDesiredPollingInterval());
adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_LESS_THAN_MIN); adaptiveLocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_LESS_THAN_MIN);
Assert.assertEquals(MIN, adaptiveLocationListenerPolicy.getDesiredPollingInterval()); assertEquals(MIN, adaptiveLocationListenerPolicy.getDesiredPollingInterval());
} }
/** /**
@@ -75,6 +76,6 @@ public class AdaptiveLocationListenerPolicyTest {
*/ */
@Test @Test
public void testGetMinDistance() { public void testGetMinDistance() {
Assert.assertEquals(MIN_DISTANCE, adaptiveLocationListenerPolicy.getMinDistance_m()); assertEquals(MIN_DISTANCE, adaptiveLocationListenerPolicy.getMinDistance_m());
} }
} }
@@ -32,7 +32,6 @@ import androidx.test.rule.GrantPermissionRule;
import androidx.test.rule.ServiceTestRule; import androidx.test.rule.ServiceTestRule;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
@@ -54,6 +53,13 @@ import de.dennisguse.opentracks.content.provider.CustomContentProvider;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.PreferencesUtils; import de.dennisguse.opentracks.util.PreferencesUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/** /**
* Tests for the track recording service. * Tests for the track recording service.
* *
@@ -120,14 +126,14 @@ public class TrackRecordingServiceTest {
@Test @Test
public void testStartable() throws TimeoutException { public void testStartable() throws TimeoutException {
mServiceRule.startService(createStartIntent(context)); mServiceRule.startService(createStartIntent(context));
Assert.assertNotNull(mServiceRule.bindService(createStartIntent(context))); assertNotNull(mServiceRule.bindService(createStartIntent(context)));
} }
@MediumTest @MediumTest
@Test @Test
public void testBindable() throws TimeoutException { public void testBindable() throws TimeoutException {
IBinder service = mServiceRule.bindService(createStartIntent(context)); IBinder service = mServiceRule.bindService(createStartIntent(context));
Assert.assertNotNull(service); assertNotNull(service);
} }
@MediumTest @MediumTest
@@ -135,7 +141,7 @@ public class TrackRecordingServiceTest {
public void testRecording_noTracks() throws Exception { public void testRecording_noTracks() throws Exception {
// given // given
List<Track> tracks = contentProviderUtils.getTracks(); List<Track> tracks = contentProviderUtils.getTracks();
Assert.assertTrue(tracks.isEmpty()); assertTrue(tracks.isEmpty());
// when // when
Intent startIntent = createStartIntent(context); Intent startIntent = createStartIntent(context);
@@ -144,8 +150,8 @@ public class TrackRecordingServiceTest {
// then // then
// Test if we start in no-recording mode by default. // Test if we start in no-recording mode by default.
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
Assert.assertNull(service.getRecordingTrackId()); assertNull(service.getRecordingTrackId());
} }
@MediumTest @MediumTest
@@ -158,8 +164,8 @@ public class TrackRecordingServiceTest {
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
Assert.assertNull(service.getRecordingTrackId()); assertNull(service.getRecordingTrackId());
} }
@MediumTest @MediumTest
@@ -172,7 +178,7 @@ public class TrackRecordingServiceTest {
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
// then // then
Assert.assertTrue(service.isRecording()); assertTrue(service.isRecording());
} }
@MediumTest @MediumTest
@@ -187,21 +193,21 @@ public class TrackRecordingServiceTest {
service.pauseCurrentTrack(); service.pauseCurrentTrack();
// then // then
Assert.assertEquals(2, contentProviderUtils.getTrackPoints(trackId).size()); assertEquals(2, contentProviderUtils.getTrackPoints(trackId).size());
//when //when
service.resumeTrack(trackId); service.resumeTrack(trackId);
newTrackPoint(service); newTrackPoint(service);
// then // then
Assert.assertTrue(service.isRecording()); assertTrue(service.isRecording());
Assert.assertEquals(trackId, service.getRecordingTrackId()); assertEquals(trackId, service.getRecordingTrackId());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(5, trackPoints.size()); assertEquals(5, trackPoints.size());
Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01); assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01);
Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(2).getLatitude(), 0.01); assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(2).getLatitude(), 0.01);
Assert.assertEquals(TrackPointsColumns.RESUME_LATITUDE, trackPoints.get(3).getLatitude(), 0.01); assertEquals(TrackPointsColumns.RESUME_LATITUDE, trackPoints.get(3).getLatitude(), 0.01);
} }
@MediumTest @MediumTest
@@ -213,20 +219,20 @@ public class TrackRecordingServiceTest {
newTrackPoint(service); newTrackPoint(service);
service.endCurrentTrack(); service.endCurrentTrack();
Assert.assertEquals(1, contentProviderUtils.getTrackPoints(trackId).size()); assertEquals(1, contentProviderUtils.getTrackPoints(trackId).size());
// when // when
service.resumeTrack(trackId); service.resumeTrack(trackId);
newTrackPoint(service); newTrackPoint(service);
// then // then
Assert.assertTrue(service.isRecording()); assertTrue(service.isRecording());
Assert.assertEquals(trackId, service.getRecordingTrackId()); assertEquals(trackId, service.getRecordingTrackId());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(4, trackPoints.size()); assertEquals(4, trackPoints.size());
Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01); assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01);
Assert.assertEquals(TrackPointsColumns.RESUME_LATITUDE, trackPoints.get(2).getLatitude(), 0.01); assertEquals(TrackPointsColumns.RESUME_LATITUDE, trackPoints.get(2).getLatitude(), 0.01);
} }
@FlakyTest(detail = "Sometimes fails on CI.") @FlakyTest(detail = "Sometimes fails on CI.")
@@ -242,8 +248,8 @@ public class TrackRecordingServiceTest {
PreferencesUtils.setLong(context, R.string.recording_track_id_key, 123L); PreferencesUtils.setLong(context, R.string.recording_track_id_key, 123L);
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
Assert.assertNull(service.getRecordingTrackId()); assertNull(service.getRecordingTrackId());
} }
@MediumTest @MediumTest
@@ -252,7 +258,7 @@ public class TrackRecordingServiceTest {
// given // given
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
service.startNewTrack(); service.startNewTrack();
Assert.assertTrue(service.isRecording()); assertTrue(service.isRecording());
Track.Id trackId = service.getRecordingTrackId(); Track.Id trackId = service.getRecordingTrackId();
@@ -260,10 +266,10 @@ public class TrackRecordingServiceTest {
Track.Id newTrackId = service.startNewTrack(); Track.Id newTrackId = service.startNewTrack();
// then // then
Assert.assertNull(newTrackId); assertNull(newTrackId);
Assert.assertEquals(trackId, PreferencesUtils.getRecordingTrackId(context)); assertEquals(trackId, PreferencesUtils.getRecordingTrackId(context));
Assert.assertEquals(trackId, service.getRecordingTrackId()); assertEquals(trackId, service.getRecordingTrackId());
} }
@MediumTest @MediumTest
@@ -271,15 +277,15 @@ public class TrackRecordingServiceTest {
public void testEndCurrentTrack_noRecording() throws Exception { public void testEndCurrentTrack_noRecording() throws Exception {
// given // given
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
// when // when
// Ending the current track when there is no recording should not result in any error. // Ending the current track when there is no recording should not result in any error.
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(PreferencesUtils.isRecording(context)); assertFalse(PreferencesUtils.isRecording(context));
Assert.assertNull(service.getRecordingTrackId()); assertNull(service.getRecordingTrackId());
} }
@MediumTest @MediumTest
@@ -287,13 +293,13 @@ public class TrackRecordingServiceTest {
public void testInsertWaypointMarker_noRecordingTrack() throws Exception { public void testInsertWaypointMarker_noRecordingTrack() throws Exception {
// given // given
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
// when // when
Waypoint.Id waypointId = service.insertWaypoint(null, null, null, null); Waypoint.Id waypointId = service.insertWaypoint(null, null, null, null);
// then // then
Assert.assertNull(waypointId); assertNull(waypointId);
} }
@MediumTest @MediumTest
@@ -302,7 +308,7 @@ public class TrackRecordingServiceTest {
// given // given
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
service.startNewTrack(); service.startNewTrack();
Assert.assertTrue(service.isRecording()); assertTrue(service.isRecording());
newTrackPoint(service); newTrackPoint(service);
Track.Id trackId = service.getRecordingTrackId(); Track.Id trackId = service.getRecordingTrackId();
@@ -310,21 +316,21 @@ public class TrackRecordingServiceTest {
Waypoint.Id waypointId = service.insertWaypoint(null, null, null, null); Waypoint.Id waypointId = service.insertWaypoint(null, null, null, null);
// then // then
Assert.assertNotEquals(-1L, waypointId); assertNotEquals(-1L, waypointId);
Waypoint wpt = contentProviderUtils.getWaypoint(waypointId); Waypoint wpt = contentProviderUtils.getWaypoint(waypointId);
Assert.assertEquals(context.getString(R.string.marker_waypoint_icon_url), wpt.getIcon()); assertEquals(context.getString(R.string.marker_waypoint_icon_url), wpt.getIcon());
Assert.assertEquals(context.getString(R.string.marker_name_format, 1), wpt.getName()); assertEquals(context.getString(R.string.marker_name_format, 1), wpt.getName());
Assert.assertEquals(trackId, wpt.getTrackId()); assertEquals(trackId, wpt.getTrackId());
Assert.assertEquals(0.0, wpt.getLength(), 0.01); assertEquals(0.0, wpt.getLength(), 0.01);
Assert.assertNotNull(wpt.getLocation()); assertNotNull(wpt.getLocation());
service.endCurrentTrack(); service.endCurrentTrack();
} }
private void addTrack(Track track, boolean isRecording) { private void addTrack(Track track, boolean isRecording) {
Assert.assertTrue(track.getId().isValid()); assertTrue(track.getId().isValid());
contentProviderUtils.insertTrack(track); contentProviderUtils.insertTrack(track);
Assert.assertEquals(track.getId(), contentProviderUtils.getTrack(track.getId()).getId()); assertEquals(track.getId(), contentProviderUtils.getTrack(track.getId()).getId());
PreferencesUtils.setLong(context, R.string.recording_track_id_key, isRecording ? track.getId().getId() : PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); PreferencesUtils.setLong(context, R.string.recording_track_id_key, isRecording ? track.getId().getId() : PreferencesUtils.RECORDING_TRACK_ID_DEFAULT);
PreferencesUtils.setBoolean(context, R.string.recording_track_paused_key, !isRecording); PreferencesUtils.setBoolean(context, R.string.recording_track_paused_key, !isRecording);
} }
@@ -12,7 +12,6 @@ import androidx.test.rule.GrantPermissionRule;
import androidx.test.rule.ServiceTestRule; import androidx.test.rule.ServiceTestRule;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
@@ -33,6 +32,9 @@ import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager; import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
import de.dennisguse.opentracks.util.PreferencesUtils; import de.dennisguse.opentracks.util.PreferencesUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
/** /**
* Tests insert location. * Tests insert location.
* <p> * <p>
@@ -103,11 +105,11 @@ public class TrackRecordingServiceTestLocation {
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(6, trackPoints.size()); assertEquals(6, trackPoints.size());
Assert.assertEquals(45.0005, trackPoints.get(5).getLatitude(), 0.01); assertEquals(45.0005, trackPoints.get(5).getLatitude(), 0.01);
} }
@MediumTest @MediumTest
@@ -127,11 +129,11 @@ public class TrackRecordingServiceTestLocation {
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(2, trackPoints.size()); assertEquals(2, trackPoints.size());
Assert.assertEquals(45.000005, trackPoints.get(1).getLatitude(), 0.01); assertEquals(45.000005, trackPoints.get(1).getLatitude(), 0.01);
} }
// @MediumTest // @MediumTest
@@ -169,13 +171,13 @@ public class TrackRecordingServiceTestLocation {
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(3, trackPoints.size()); assertEquals(3, trackPoints.size());
Assert.assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01); assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01);
Assert.assertEquals(2, trackPoints.get(1).getAccuracy(), 0.01); assertEquals(2, trackPoints.get(1).getAccuracy(), 0.01);
Assert.assertEquals(6, trackPoints.get(2).getAccuracy(), 0.01); assertEquals(6, trackPoints.get(2).getAccuracy(), 0.01);
} }
@MediumTest @MediumTest
@@ -195,14 +197,14 @@ public class TrackRecordingServiceTestLocation {
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(4, trackPoints.size()); assertEquals(4, trackPoints.size());
Assert.assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01); assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01);
Assert.assertEquals(2, trackPoints.get(1).getAccuracy(), 0.01); assertEquals(2, trackPoints.get(1).getAccuracy(), 0.01);
Assert.assertEquals(5, trackPoints.get(2).getAccuracy(), 0.01); //TODO Check why this trackPoint is inserted. assertEquals(5, trackPoints.get(2).getAccuracy(), 0.01); //TODO Check why this trackPoint is inserted.
Assert.assertEquals(6, trackPoints.get(3).getAccuracy(), 0.01); assertEquals(6, trackPoints.get(3).getAccuracy(), 0.01);
} }
@@ -238,16 +240,16 @@ public class TrackRecordingServiceTestLocation {
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(6, trackPoints.size()); assertEquals(6, trackPoints.size());
Assert.assertEquals(0, trackPoints.get(0).getAccuracy(), 0.01); assertEquals(0, trackPoints.get(0).getAccuracy(), 0.01);
Assert.assertEquals(1, trackPoints.get(1).getAccuracy(), 0.01); assertEquals(1, trackPoints.get(1).getAccuracy(), 0.01);
Assert.assertEquals(2, trackPoints.get(2).getAccuracy(), 0.01); assertEquals(2, trackPoints.get(2).getAccuracy(), 0.01);
Assert.assertEquals(3, trackPoints.get(3).getAccuracy(), 0.01); assertEquals(3, trackPoints.get(3).getAccuracy(), 0.01);
Assert.assertEquals(4, trackPoints.get(4).getAccuracy(), 0.01); assertEquals(4, trackPoints.get(4).getAccuracy(), 0.01);
Assert.assertEquals(5, trackPoints.get(5).getAccuracy(), 0.01); assertEquals(5, trackPoints.get(5).getAccuracy(), 0.01);
} }
@MediumTest @MediumTest
@@ -266,16 +268,16 @@ public class TrackRecordingServiceTestLocation {
service.endCurrentTrack(); service.endCurrentTrack();
// then // then
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId); List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
Assert.assertEquals(7, trackPoints.size()); assertEquals(7, trackPoints.size());
Assert.assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01); assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01);
Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01); assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01);
Assert.assertEquals(2, trackPoints.get(2).getAccuracy(), 0.01); assertEquals(2, trackPoints.get(2).getAccuracy(), 0.01);
Assert.assertEquals(3, trackPoints.get(3).getAccuracy(), 0.01); assertEquals(3, trackPoints.get(3).getAccuracy(), 0.01);
Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(4).getLatitude(), 0.01); assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(4).getLatitude(), 0.01);
Assert.assertEquals(4, trackPoints.get(5).getAccuracy(), 0.01); assertEquals(4, trackPoints.get(5).getAccuracy(), 0.01);
Assert.assertEquals(5, trackPoints.get(6).getAccuracy(), 0.01); assertEquals(5, trackPoints.get(6).getAccuracy(), 0.01);
} }
} }
@@ -13,7 +13,6 @@ import androidx.test.rule.ServiceTestRule;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
@@ -32,6 +31,12 @@ import de.dennisguse.opentracks.content.provider.CustomContentProvider;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.PreferencesUtils; import de.dennisguse.opentracks.util.PreferencesUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/** /**
* Tests for the track recording service, which require a {@link Looper}. * Tests for the track recording service, which require a {@link Looper}.
* *
@@ -188,23 +193,23 @@ public class TrackRecordingServiceTestLooper {
@Test @Test
public void testIntegration_completeRecordingSession() throws TimeoutException { public void testIntegration_completeRecordingSession() throws TimeoutException {
List<Track> tracks = contentProviderUtils.getTracks(); List<Track> tracks = contentProviderUtils.getTracks();
Assert.assertTrue(tracks.isEmpty()); assertTrue(tracks.isEmpty());
fullRecordingSession(); fullRecordingSession();
} }
private void fullRecordingSession() throws TimeoutException { private void fullRecordingSession() throws TimeoutException {
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(TrackRecordingServiceTest.createStartIntent(context))); TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(TrackRecordingServiceTest.createStartIntent(context)));
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
// Start a track. // Start a track.
Track.Id trackId = service.startNewTrack(); Track.Id trackId = service.startNewTrack();
Assert.assertTrue(trackId.isValid()); assertTrue(trackId.isValid());
Assert.assertTrue(service.isRecording()); assertTrue(service.isRecording());
Track track = contentProviderUtils.getTrack(trackId); Track track = contentProviderUtils.getTrack(trackId);
Assert.assertNotNull(track); assertNotNull(track);
Assert.assertEquals(trackId, track.getId()); assertEquals(trackId, track.getId());
Assert.assertEquals(trackId, PreferencesUtils.getRecordingTrackId(context)); assertEquals(trackId, PreferencesUtils.getRecordingTrackId(context));
Assert.assertEquals(trackId, service.getRecordingTrackId()); assertEquals(trackId, service.getRecordingTrackId());
// Insert a few points, markers and statistics. // Insert a few points, markers and statistics.
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
@@ -227,14 +232,14 @@ public class TrackRecordingServiceTestLooper {
// Stop the track. Validate if it has correct data. // Stop the track. Validate if it has correct data.
service.endCurrentTrack(); service.endCurrentTrack();
Assert.assertFalse(service.isRecording()); assertFalse(service.isRecording());
Assert.assertNull(service.getRecordingTrackId()); assertNull(service.getRecordingTrackId());
track = contentProviderUtils.getTrack(trackId); track = contentProviderUtils.getTrack(trackId);
Assert.assertNotNull(track); assertNotNull(track);
Assert.assertEquals(trackId, track.getId()); assertEquals(trackId, track.getId());
TrackStatistics trackStatistics = track.getTrackStatistics(); TrackStatistics trackStatistics = track.getTrackStatistics();
Assert.assertNotNull(trackStatistics); assertNotNull(trackStatistics);
Assert.assertTrue(trackStatistics.getStartTime_ms() > 0); assertTrue(trackStatistics.getStartTime_ms() > 0);
Assert.assertTrue(trackStatistics.getStopTime_ms() >= trackStatistics.getStartTime_ms()); assertTrue(trackStatistics.getStopTime_ms() >= trackStatistics.getStartTime_ms());
} }
} }
@@ -23,11 +23,12 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import static org.junit.Assert.assertTrue;
/** /**
* Tests for {@link AnnouncementPeriodicTaskFactory}. * Tests for {@link AnnouncementPeriodicTaskFactory}.
* *
@@ -53,6 +54,6 @@ public class AnnouncementPeriodicTaskFactoryTest {
public void testCreate() { public void testCreate() {
PeriodicTaskFactory factory = new AnnouncementPeriodicTaskFactory(); PeriodicTaskFactory factory = new AnnouncementPeriodicTaskFactory();
PeriodicTask task = factory.create(context); PeriodicTask task = factory.create(context);
Assert.assertTrue(task instanceof AnnouncementPeriodicTask); assertTrue(task instanceof AnnouncementPeriodicTask);
} }
} }
@@ -15,12 +15,13 @@
*/ */
package de.dennisguse.opentracks.stats; package de.dennisguse.opentracks.stats;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
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;
import static org.junit.Assert.assertEquals;
/** /**
* Tests for {@link TrackStatistics}. * Tests for {@link TrackStatistics}.
* This only tests non-trivial pieces of that class. * This only tests non-trivial pieces of that class.
@@ -61,28 +62,28 @@ public class TrackStatisticsTest {
statistics.merge(statistics2); statistics.merge(statistics2);
Assert.assertEquals(1000L, statistics.getStartTime_ms()); assertEquals(1000L, statistics.getStartTime_ms());
Assert.assertEquals(4000L, statistics.getStopTime_ms()); assertEquals(4000L, statistics.getStopTime_ms());
Assert.assertEquals(2500L, statistics.getTotalTime()); assertEquals(2500L, statistics.getTotalTime());
Assert.assertEquals(1300L, statistics.getMovingTime()); assertEquals(1300L, statistics.getMovingTime());
Assert.assertEquals(1100.0, statistics.getTotalDistance(), 0.001); assertEquals(1100.0, statistics.getTotalDistance(), 0.001);
Assert.assertEquals(900.0, statistics.getTotalElevationGain(), 0.001); assertEquals(900.0, statistics.getTotalElevationGain(), 0.001);
Assert.assertEquals(statistics.getTotalDistance() / (statistics.getMovingTime() / 1000.0), statistics.getMaxSpeed(), 0.001); assertEquals(statistics.getTotalDistance() / (statistics.getMovingTime() / 1000.0), statistics.getMaxSpeed(), 0.001);
Assert.assertEquals(1200.0, statistics.getMinElevation(), 0.001); assertEquals(1200.0, statistics.getMinElevation(), 0.001);
Assert.assertEquals(3575.0, statistics.getMaxElevation(), 0.001); assertEquals(3575.0, statistics.getMaxElevation(), 0.001);
} }
@Test @Test
public void testGetAverageSpeed() { public void testGetAverageSpeed() {
statistics.setTotalDistance(1000.0); statistics.setTotalDistance(1000.0);
statistics.setTotalTime(50000); // in milliseconds statistics.setTotalTime(50000); // in milliseconds
Assert.assertEquals(20.0, statistics.getAverageSpeed(), 0.001); assertEquals(20.0, statistics.getAverageSpeed(), 0.001);
} }
@Test @Test
public void testGetAverageMovingSpeed() { public void testGetAverageMovingSpeed() {
statistics.setTotalDistance(1000.0); statistics.setTotalDistance(1000.0);
statistics.setMovingTime(20000); // in milliseconds statistics.setMovingTime(20000); // in milliseconds
Assert.assertEquals(50.0, statistics.getAverageMovingSpeed(), 0.001); assertEquals(50.0, statistics.getAverageMovingSpeed(), 0.001);
} }
} }
@@ -5,11 +5,20 @@ import android.content.Context;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.List;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class AnnouncementUtilsTest { public class AnnouncementUtilsTest {
@@ -26,9 +35,50 @@ public class AnnouncementUtilsTest {
stats.setTotalElevationGain(6000); stats.setTotalElevationGain(6000);
// when // when
String announcement = AnnouncementUtils.getAnnouncement(context, stats, "airplane"); String announcement = AnnouncementUtils.getAnnouncement(context, stats, "airplane", null);
// then // then
Assert.assertEquals("OpenTracks total distance 20.00 kilometers in 5 minutes 0 seconds at 240.0 kilometers per hour", announcement); assertEquals("OpenTracks total distance 20.00 kilometers in 5 minutes 0 seconds at 240.0 kilometers per hour", announcement);
}
@Test
public void getAnnouncement_withInterval() {
TrackStatistics stats = new TrackStatistics();
stats.setTotalDistance(20000);
stats.setTotalTime(600000);
stats.setMovingTime(300000);
stats.setMaxSpeed(100);
stats.setTotalElevationGain(6000);
IntervalStatistics intervalStatistics = new IntervalStatistics();
List<TrackPoint> trackPoints = Arrays.asList(TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second);
intervalStatistics.build(trackPoints, 1000);
IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
int speedId = R.plurals.voiceSpeedKilometersPerHour;
double kmPerHour = lastInterval.getSpeed_ms() * UnitConversions.MPS_TO_KMH;
String firstPartMsg = "OpenTracks total distance 20.00 kilometers in 5 minutes 0 seconds at 240.0 kilometers per hour";
String rateMsg = " With a current kilometer speed of " + context.getResources().getQuantityString(speedId, getQuantityCount(kmPerHour), kmPerHour);
String msg = firstPartMsg + rateMsg;
// when
String announcement = AnnouncementUtils.getAnnouncement(context, stats, "airplane", lastInterval);
// then
assertEquals(msg, announcement);
}
private int getQuantityCount(double d) {
if (d == 0) {
return 0;
} else if (d == 1) {
return 1;
} else if (d == 2) {
return 2;
} else {
int count = (int) d;
return Math.max(count, 3);
}
} }
} }
@@ -2,11 +2,13 @@ package de.dennisguse.opentracks.util;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import de.dennisguse.opentracks.content.sensor.SensorDataCycling; import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class BluetoothUtilsTest { public class BluetoothUtilsTest {
@Test @Test
@@ -19,7 +21,7 @@ public class BluetoothUtilsTest {
int heartRate = BluetoothUtils.parseHeartRate(characteristic); int heartRate = BluetoothUtils.parseHeartRate(characteristic);
// then // then
Assert.assertEquals(60, heartRate); assertEquals(60, heartRate);
} }
@Test @Test
@@ -32,7 +34,7 @@ public class BluetoothUtilsTest {
int heartRate = BluetoothUtils.parseHeartRate(characteristic); int heartRate = BluetoothUtils.parseHeartRate(characteristic);
// then // then
Assert.assertEquals(257, heartRate); assertEquals(257, heartRate);
} }
@Test @Test
@@ -44,8 +46,8 @@ public class BluetoothUtilsTest {
SensorDataCycling.CadenceAndSpeed sensor = BluetoothUtils.parseCyclingCrankAndWheel("address", "sensorName", characteristic); SensorDataCycling.CadenceAndSpeed sensor = BluetoothUtils.parseCyclingCrankAndWheel("address", "sensorName", characteristic);
// then // then
Assert.assertEquals(200, sensor.getCadence().getCrankRevolutionsCount()); assertEquals(200, sensor.getCadence().getCrankRevolutionsCount());
Assert.assertNull(sensor.getSpeed()); assertNull(sensor.getSpeed());
} }
@Test @Test
@@ -57,8 +59,8 @@ public class BluetoothUtilsTest {
SensorDataCycling.CadenceAndSpeed sensor = BluetoothUtils.parseCyclingCrankAndWheel("address", "sensorName", characteristic); SensorDataCycling.CadenceAndSpeed sensor = BluetoothUtils.parseCyclingCrankAndWheel("address", "sensorName", characteristic);
// then // then
Assert.assertNull(sensor.getCadence()); assertNull(sensor.getCadence());
Assert.assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount()); assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount());
} }
@Test @Test
@@ -70,7 +72,7 @@ public class BluetoothUtilsTest {
SensorDataCycling.CadenceAndSpeed sensor = BluetoothUtils.parseCyclingCrankAndWheel("address", "sensorName", characteristic); SensorDataCycling.CadenceAndSpeed sensor = BluetoothUtils.parseCyclingCrankAndWheel("address", "sensorName", characteristic);
// then // then
Assert.assertEquals(200, sensor.getCadence().getCrankRevolutionsCount()); assertEquals(200, sensor.getCadence().getCrankRevolutionsCount());
Assert.assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount()); assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount());
} }
} }
@@ -15,7 +15,6 @@
*/ */
package de.dennisguse.opentracks.util; package de.dennisguse.opentracks.util;
import org.junit.Assert;
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;
@@ -23,6 +22,8 @@ import org.junit.runners.JUnit4;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import static org.junit.Assert.assertEquals;
/** /**
* Tests for {@link FileUtils}. * Tests for {@link FileUtils}.
* *
@@ -37,7 +38,7 @@ public class FileUtilsTest {
@Test @Test
public void testBuildUniqueFileName_new() { public void testBuildUniqueFileName_new() {
String filename = FileUtils.buildUniqueFileName(new File("/dir"), "Filename", "ext"); String filename = FileUtils.buildUniqueFileName(new File("/dir"), "Filename", "ext");
Assert.assertEquals("Filename.ext", filename); assertEquals("Filename.ext", filename);
} }
/** /**
@@ -47,7 +48,7 @@ public class FileUtilsTest {
public void testBuildUniqueFileName_exist() { public void testBuildUniqueFileName_exist() {
// Expect "/default.prop" to exist on the phone/emulator // Expect "/default.prop" to exist on the phone/emulator
String filename = FileUtils.buildUniqueFileName(new File("/"), "default", "prop"); String filename = FileUtils.buildUniqueFileName(new File("/"), "default", "prop");
Assert.assertEquals("default(1).prop", filename); assertEquals("default(1).prop", filename);
} }
/** /**
@@ -58,13 +59,13 @@ public class FileUtilsTest {
public void testSanitizeFileName() { public void testSanitizeFileName() {
String name = "Swim\10ming-^across:/the/ pacific (ocean)."; String name = "Swim\10ming-^across:/the/ pacific (ocean).";
String expected = "Swim_ming-^across_the_ pacific (ocean)."; String expected = "Swim_ming-^across_the_ pacific (ocean).";
Assert.assertEquals(expected, FileUtils.sanitizeFileName(name)); assertEquals(expected, FileUtils.sanitizeFileName(name));
} }
@Test @Test
public void testSanitizeFileNameWithSuffix() { public void testSanitizeFileNameWithSuffix() {
String name = "FileName.jpeg"; String name = "FileName.jpeg";
Assert.assertEquals(name, FileUtils.sanitizeFileName(name)); assertEquals(name, FileUtils.sanitizeFileName(name));
} }
/** /**
@@ -75,7 +76,7 @@ public class FileUtilsTest {
public void testSanitizeFileName_i18n() { public void testSanitizeFileName_i18n() {
String name = "您好-привет"; String name = "您好-привет";
String expected = "您好-привет"; String expected = "您好-привет";
Assert.assertEquals(expected, FileUtils.sanitizeFileName(name)); assertEquals(expected, FileUtils.sanitizeFileName(name));
} }
/** /**
@@ -86,7 +87,7 @@ public class FileUtilsTest {
public void testSanitizeFileName_special_characters() { public void testSanitizeFileName_special_characters() {
String name = "$%'-_@~`!(){}^#&+,;=[] "; String name = "$%'-_@~`!(){}^#&+,;=[] ";
String expected = "$%'-_@~`!(){}^#&+,;=[] "; String expected = "$%'-_@~`!(){}^#&+,;=[] ";
Assert.assertEquals(expected, FileUtils.sanitizeFileName(name)); assertEquals(expected, FileUtils.sanitizeFileName(name));
} }
/** /**
@@ -97,7 +98,7 @@ public class FileUtilsTest {
public void testSanitizeFileName_collapse() { public void testSanitizeFileName_collapse() {
String name = "hello//there"; String name = "hello//there";
String expected = "hello_there"; String expected = "hello_there";
Assert.assertEquals(expected, FileUtils.sanitizeFileName(name)); assertEquals(expected, FileUtils.sanitizeFileName(name));
} }
/** /**
@@ -114,8 +115,8 @@ public class FileUtilsTest {
String truncated = FileUtils.truncateFileName(directory, nameString, suffix); String truncated = FileUtils.truncateFileName(directory, nameString, suffix);
for (int i = 0; i < truncated.length(); i++) { for (int i = 0; i < truncated.length(); i++) {
Assert.assertEquals('a', truncated.charAt(i)); assertEquals('a', truncated.charAt(i));
} }
Assert.assertEquals(FileUtils.MAX_FAT32_PATH_LENGTH, new File(directory, truncated + suffix).getPath().length()); assertEquals(FileUtils.MAX_FAT32_PATH_LENGTH, new File(directory, truncated + suffix).getPath().length());
} }
} }
@@ -6,13 +6,14 @@ import android.content.SharedPreferences;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.TrackFileFormat;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class PreferencesUtilsTest { public class PreferencesUtilsTest {
@@ -29,7 +30,7 @@ public class PreferencesUtilsTest {
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context); TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
// then // then
Assert.assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL, trackFileFormat); assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL, trackFileFormat);
} }
@Test @Test
@@ -43,7 +44,7 @@ public class PreferencesUtilsTest {
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context); TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
// then // then
Assert.assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, trackFileFormat); assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, trackFileFormat);
} }
@Test @Test
@@ -57,6 +58,6 @@ public class PreferencesUtilsTest {
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context); TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
// then // then
Assert.assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, trackFileFormat); assertEquals(TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA, trackFileFormat);
} }
} }
@@ -21,13 +21,15 @@ import android.content.Context;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.TimeZone; import java.util.TimeZone;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/** /**
* Tests for {@link StringUtils}. * Tests for {@link StringUtils}.
* *
@@ -44,7 +46,7 @@ public class StringUtilsTest {
*/ */
@Test @Test
public void testFormatDateTimeIso8601() { public void testFormatDateTimeIso8601() {
Assert.assertEquals("1970-01-01T00:00:12.345Z", StringUtils.formatDateTimeIso8601(12345)); assertEquals("1970-01-01T00:00:12.345Z", StringUtils.formatDateTimeIso8601(12345));
} }
/** /**
@@ -53,19 +55,19 @@ public class StringUtilsTest {
@Test @Test
public void testformatElapsedTime() { public void testformatElapsedTime() {
// 1 second // 1 second
Assert.assertEquals("00:01", StringUtils.formatElapsedTime(1000)); assertEquals("00:01", StringUtils.formatElapsedTime(1000));
// 10 seconds // 10 seconds
Assert.assertEquals("00:10", StringUtils.formatElapsedTime(10000)); assertEquals("00:10", StringUtils.formatElapsedTime(10000));
// 1 minute // 1 minute
Assert.assertEquals("01:00", StringUtils.formatElapsedTime(60000)); assertEquals("01:00", StringUtils.formatElapsedTime(60000));
// 10 minutes // 10 minutes
Assert.assertEquals("10:00", StringUtils.formatElapsedTime(600000)); assertEquals("10:00", StringUtils.formatElapsedTime(600000));
// 1 hour // 1 hour
Assert.assertEquals("1:00:00", StringUtils.formatElapsedTime(3600000)); assertEquals("1:00:00", StringUtils.formatElapsedTime(3600000));
// 10 hours // 10 hours
Assert.assertEquals("10:00:00", StringUtils.formatElapsedTime(36000000)); assertEquals("10:00:00", StringUtils.formatElapsedTime(36000000));
// 100 hours // 100 hours
Assert.assertEquals("100:00:00", StringUtils.formatElapsedTime(360000000)); assertEquals("100:00:00", StringUtils.formatElapsedTime(360000000));
} }
/** /**
@@ -74,19 +76,19 @@ public class StringUtilsTest {
@Test @Test
public void testformatElapsedTimeWithHour() { public void testformatElapsedTimeWithHour() {
// 1 second // 1 second
Assert.assertEquals("0:00:01", StringUtils.formatElapsedTimeWithHour(1000)); assertEquals("0:00:01", StringUtils.formatElapsedTimeWithHour(1000));
// 10 seconds // 10 seconds
Assert.assertEquals("0:00:10", StringUtils.formatElapsedTimeWithHour(10000)); assertEquals("0:00:10", StringUtils.formatElapsedTimeWithHour(10000));
// 1 minute // 1 minute
Assert.assertEquals("0:01:00", StringUtils.formatElapsedTimeWithHour(60000)); assertEquals("0:01:00", StringUtils.formatElapsedTimeWithHour(60000));
// 10 minutes // 10 minutes
Assert.assertEquals("0:10:00", StringUtils.formatElapsedTimeWithHour(600000)); assertEquals("0:10:00", StringUtils.formatElapsedTimeWithHour(600000));
// 1 hour // 1 hour
Assert.assertEquals("1:00:00", StringUtils.formatElapsedTimeWithHour(3600000)); assertEquals("1:00:00", StringUtils.formatElapsedTimeWithHour(3600000));
// 10 hours // 10 hours
Assert.assertEquals("10:00:00", StringUtils.formatElapsedTimeWithHour(36000000)); assertEquals("10:00:00", StringUtils.formatElapsedTimeWithHour(36000000));
// 100 hours // 100 hours
Assert.assertEquals("100:00:00", StringUtils.formatElapsedTimeWithHour(360000000)); assertEquals("100:00:00", StringUtils.formatElapsedTimeWithHour(360000000));
} }
/** /**
@@ -96,13 +98,13 @@ public class StringUtilsTest {
@Test @Test
public void testFormatDistance() { public void testFormatDistance() {
// A large number in metric // A large number in metric
Assert.assertEquals("5.00 km", StringUtils.formatDistance(context, 5000, true)); assertEquals("5.00 km", StringUtils.formatDistance(context, 5000, true));
// A large number in imperial // A large number in imperial
Assert.assertEquals("3.11 mi", StringUtils.formatDistance(context, 5000, false)); assertEquals("3.11 mi", StringUtils.formatDistance(context, 5000, false));
// A small number in metric // A small number in metric
Assert.assertEquals("100.00 m", StringUtils.formatDistance(context, 100, true)); assertEquals("100.00 m", StringUtils.formatDistance(context, 100, true));
// A small number in imperial // A small number in imperial
Assert.assertEquals("328.08 ft", StringUtils.formatDistance(context, 100, false)); assertEquals("328.08 ft", StringUtils.formatDistance(context, 100, false));
} }
/** /**
@@ -110,8 +112,8 @@ public class StringUtilsTest {
*/ */
@Test @Test
public void testFormatCData() { public void testFormatCData() {
Assert.assertEquals("<![CDATA[hello]]>", StringUtils.formatCData("hello")); assertEquals("<![CDATA[hello]]>", StringUtils.formatCData("hello"));
Assert.assertEquals("<![CDATA[hello]]]]><![CDATA[>there]]>", StringUtils.formatCData("hello]]>there")); assertEquals("<![CDATA[hello]]]]><![CDATA[>there]]>", StringUtils.formatCData("hello]]>there"));
} }
/** /**
@@ -168,7 +170,7 @@ public class StringUtilsTest {
// This comparision tends to be flaky (difference of 1ms) // This comparision tends to be flaky (difference of 1ms)
// Assert.assertEquals(calendar.getTimeInMillis(), StringUtils.parseTime(xmlDateTime)); // Assert.assertEquals(calendar.getTimeInMillis(), StringUtils.parseTime(xmlDateTime));
Assert.assertTrue(calendar.getTimeInMillis() + " vs. " + StringUtils.parseTime(xmlDateTime), Math.abs(calendar.getTimeInMillis() - StringUtils.parseTime(xmlDateTime)) <= 1); assertTrue(calendar.getTimeInMillis() + " vs. " + StringUtils.parseTime(xmlDateTime), Math.abs(calendar.getTimeInMillis() - StringUtils.parseTime(xmlDateTime)) <= 1);
} }
/** /**
@@ -177,9 +179,9 @@ public class StringUtilsTest {
@Test @Test
public void testGetTimeParts_positive() { public void testGetTimeParts_positive() {
int[] parts = StringUtils.getTimeParts(61000); int[] parts = StringUtils.getTimeParts(61000);
Assert.assertEquals(1, parts[0]); assertEquals(1, parts[0]);
Assert.assertEquals(1, parts[1]); assertEquals(1, parts[1]);
Assert.assertEquals(0, parts[2]); assertEquals(0, parts[2]);
} }
/** /**
@@ -188,40 +190,40 @@ public class StringUtilsTest {
@Test @Test
public void testGetTimeParts_negative() { public void testGetTimeParts_negative() {
int[] parts = StringUtils.getTimeParts(-61000); int[] parts = StringUtils.getTimeParts(-61000);
Assert.assertEquals(-1, parts[0]); assertEquals(-1, parts[0]);
Assert.assertEquals(-1, parts[1]); assertEquals(-1, parts[1]);
Assert.assertEquals(0, parts[2]); assertEquals(0, parts[2]);
} }
@Test @Test
public void testFormatDecimal() { public void testFormatDecimal() {
Assert.assertEquals("0", StringUtils.formatDecimal(0.0, 0)); assertEquals("0", StringUtils.formatDecimal(0.0, 0));
Assert.assertEquals("0", StringUtils.formatDecimal(0.1, 0)); assertEquals("0", StringUtils.formatDecimal(0.1, 0));
Assert.assertEquals("1", StringUtils.formatDecimal(1.1, 0)); assertEquals("1", StringUtils.formatDecimal(1.1, 0));
Assert.assertEquals("10", StringUtils.formatDecimal(10, 0)); assertEquals("10", StringUtils.formatDecimal(10, 0));
Assert.assertEquals("10", StringUtils.formatDecimal(10.1, 0)); assertEquals("10", StringUtils.formatDecimal(10.1, 0));
Assert.assertEquals("0", StringUtils.formatDecimal(-0.1, 0)); assertEquals("0", StringUtils.formatDecimal(-0.1, 0));
Assert.assertEquals("0", StringUtils.formatDecimal(0.0, 2)); assertEquals("0", StringUtils.formatDecimal(0.0, 2));
Assert.assertEquals("0.1", StringUtils.formatDecimal(0.1, 2)); assertEquals("0.1", StringUtils.formatDecimal(0.1, 2));
Assert.assertEquals("1.1", StringUtils.formatDecimal(1.1, 2)); assertEquals("1.1", StringUtils.formatDecimal(1.1, 2));
Assert.assertEquals("10", StringUtils.formatDecimal(10, 2)); assertEquals("10", StringUtils.formatDecimal(10, 2));
Assert.assertEquals("10.1", StringUtils.formatDecimal(10.1, 2)); assertEquals("10.1", StringUtils.formatDecimal(10.1, 2));
Assert.assertEquals("10.11", StringUtils.formatDecimal(10.111, 2)); assertEquals("10.11", StringUtils.formatDecimal(10.111, 2));
Assert.assertEquals("-0.1", StringUtils.formatDecimal(-0.1, 2)); assertEquals("-0.1", StringUtils.formatDecimal(-0.1, 2));
Assert.assertEquals("1", StringUtils.formatDecimal(0.99, 1)); assertEquals("1", StringUtils.formatDecimal(0.99, 1));
} }
@Test @Test
public void testGetSpeedParts() { public void testGetSpeedParts() {
Assert.assertEquals("4:59", StringUtils.getSpeedParts(context, 3.34, true, false).first); assertEquals("4:59", StringUtils.getSpeedParts(context, 3.34, true, false).first);
Assert.assertEquals("5:00", StringUtils.getSpeedParts(context, 3.33, true, false).first); assertEquals("5:00", StringUtils.getSpeedParts(context, 3.33, true, false).first);
Assert.assertEquals("11.99", StringUtils.getSpeedParts(context, 3.33, true, true).first); assertEquals("11.99", StringUtils.getSpeedParts(context, 3.33, true, true).first);
Assert.assertEquals("7.45", StringUtils.getSpeedParts(context, 3.33, false, true).first); assertEquals("7.45", StringUtils.getSpeedParts(context, 3.33, false, true).first);
Assert.assertEquals("min/km", StringUtils.getSpeedParts(context, 0, true, false).second); assertEquals("min/km", StringUtils.getSpeedParts(context, 0, true, false).second);
Assert.assertEquals("min/mi", StringUtils.getSpeedParts(context, 0, false, false).second); assertEquals("min/mi", StringUtils.getSpeedParts(context, 0, false, false).second);
} }
} }
@@ -21,7 +21,6 @@ import android.content.Context;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -32,6 +31,8 @@ import java.util.Locale;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
import static org.junit.Assert.assertEquals;
/** /**
* Tests {@link TrackNameUtils}. * Tests {@link TrackNameUtils}.
* *
@@ -51,7 +52,7 @@ public class TrackNameUtilsTest {
@Test @Test
public void testTrackName_date_local() { public void testTrackName_date_local() {
PreferencesUtils.setString(CONTEXT, R.string.track_name_key, CONTEXT.getString(R.string.settings_recording_track_name_date_local_value)); PreferencesUtils.setString(CONTEXT, R.string.track_name_key, CONTEXT.getString(R.string.settings_recording_track_name_date_local_value));
Assert.assertEquals(StringUtils.formatDateTime(CONTEXT, START_TIME), TrackNameUtils.getTrackName(CONTEXT, TRACK_ID, START_TIME)); assertEquals(StringUtils.formatDateTime(CONTEXT, START_TIME), TrackNameUtils.getTrackName(CONTEXT, TRACK_ID, START_TIME));
} }
/** /**
@@ -61,7 +62,7 @@ public class TrackNameUtilsTest {
public void testTrackName_date_iso_8601() { public void testTrackName_date_iso_8601() {
PreferencesUtils.setString(CONTEXT, R.string.track_name_key, CONTEXT.getString(R.string.settings_recording_track_name_date_iso_8601_value)); PreferencesUtils.setString(CONTEXT, R.string.track_name_key, CONTEXT.getString(R.string.settings_recording_track_name_date_iso_8601_value));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(TrackNameUtils.ISO_8601_FORMAT, Locale.US); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(TrackNameUtils.ISO_8601_FORMAT, Locale.US);
Assert.assertEquals(simpleDateFormat.format(new Date(START_TIME)), TrackNameUtils.getTrackName(CONTEXT, TRACK_ID, START_TIME)); assertEquals(simpleDateFormat.format(new Date(START_TIME)), TrackNameUtils.getTrackName(CONTEXT, TRACK_ID, START_TIME));
} }
/** /**
@@ -70,6 +71,6 @@ public class TrackNameUtilsTest {
@Test @Test
public void testTrackName_number() { public void testTrackName_number() {
PreferencesUtils.setString(CONTEXT, R.string.track_name_key, CONTEXT.getString(R.string.settings_recording_track_name_number_value)); PreferencesUtils.setString(CONTEXT, R.string.track_name_key, CONTEXT.getString(R.string.settings_recording_track_name_number_value));
Assert.assertEquals("Track " + TRACK_ID.getId(), TrackNameUtils.getTrackName(CONTEXT, TRACK_ID, START_TIME)); assertEquals("Track " + TRACK_ID.getId(), TrackNameUtils.getTrackName(CONTEXT, TRACK_ID, START_TIME));
} }
} }
@@ -1,10 +1,11 @@
package de.dennisguse.opentracks.util; package de.dennisguse.opentracks.util;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
import static org.junit.Assert.assertEquals;
public class TrackPointUtilsTest { public class TrackPointUtilsTest {
@Test @Test
@@ -18,7 +19,7 @@ public class TrackPointUtilsTest {
TrackPointUtils.fixTime(trackPoint); TrackPointUtils.fixTime(trackPoint);
// then // then
Assert.assertEquals(time, trackPoint.getTime()); assertEquals(time, trackPoint.getTime());
} }
@Test @Test
@@ -32,7 +33,7 @@ public class TrackPointUtilsTest {
TrackPointUtils.fixTime(trackPoint); TrackPointUtils.fixTime(trackPoint);
// then // then
Assert.assertEquals(time, trackPoint.getTime(), 1000); assertEquals(time, trackPoint.getTime(), 1000);
} }
@Test @Test
@@ -46,7 +47,7 @@ public class TrackPointUtilsTest {
TrackPointUtils.fixTime(trackPoint); TrackPointUtils.fixTime(trackPoint);
// then // then
Assert.assertEquals(time, trackPoint.getTime()); assertEquals(time, trackPoint.getTime());
} }
} }
@@ -2,12 +2,13 @@ package de.dennisguse.opentracks.util;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.util.UUID; import java.util.UUID;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class UUIDUtilsTest { public class UUIDUtilsTest {
@@ -18,6 +19,6 @@ public class UUIDUtilsTest {
byte[] bytes = UUIDUtils.toBytes(uuid); byte[] bytes = UUIDUtils.toBytes(uuid);
UUID output = UUIDUtils.fromBytes(bytes); UUID output = UUIDUtils.fromBytes(bytes);
Assert.assertEquals(uuid, output); assertEquals(uuid, output);
} }
} }
@@ -4,7 +4,6 @@ import android.content.Context;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import org.junit.Assert;
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;
@@ -14,6 +13,9 @@ import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.TrackIconUtils; import de.dennisguse.opentracks.util.TrackIconUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class AggregatedStatisticsTest { public class AggregatedStatisticsTest {
@@ -59,13 +61,13 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(track); aggregatedStatistics.aggregate(track);
// then // then
Assert.assertEquals(1, aggregatedStatistics.getCount()); assertEquals(1, aggregatedStatistics.getCount());
Assert.assertNotNull(aggregatedStatistics.get(biking)); assertNotNull(aggregatedStatistics.get(biking));
Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks()); assertEquals(1, aggregatedStatistics.get(biking).getCountTracks());
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0); assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime, statistics2.getMovingTime()); assertEquals(totalTime, statistics2.getMovingTime());
} }
@Test @Test
@@ -82,7 +84,7 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(track); aggregatedStatistics.aggregate(track);
// then // then
Assert.assertNotNull(aggregatedStatistics.get(mountainBiking)); assertNotNull(aggregatedStatistics.get(mountainBiking));
} }
@Test @Test
@@ -99,7 +101,7 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(track); aggregatedStatistics.aggregate(track);
// then // then
Assert.assertNotNull(aggregatedStatistics.get(trailRunning)); assertNotNull(aggregatedStatistics.get(trailRunning));
} }
@Test @Test
@@ -120,13 +122,13 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(tracks[1]); // biking activity 2. aggregatedStatistics.aggregate(tracks[1]); // biking activity 2.
// then // then
Assert.assertEquals(1, aggregatedStatistics.getCount()); assertEquals(1, aggregatedStatistics.getCount());
Assert.assertNotNull(aggregatedStatistics.get(biking)); assertNotNull(aggregatedStatistics.get(biking));
Assert.assertEquals(2, aggregatedStatistics.get(biking).getCountTracks()); assertEquals(2, aggregatedStatistics.get(biking).getCountTracks());
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
Assert.assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0); assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime * 2L, statistics2.getMovingTime()); assertEquals(totalTime * 2L, statistics2.getMovingTime());
} }
@Test @Test
@@ -152,30 +154,30 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(tracks[2]); // biking activity 3. aggregatedStatistics.aggregate(tracks[2]); // biking activity 3.
// then // then
Assert.assertEquals(3, aggregatedStatistics.getCount()); assertEquals(3, aggregatedStatistics.getCount());
Assert.assertNotNull(aggregatedStatistics.get(biking)); assertNotNull(aggregatedStatistics.get(biking));
Assert.assertNotNull(aggregatedStatistics.get(running)); assertNotNull(aggregatedStatistics.get(running));
Assert.assertNotNull(aggregatedStatistics.get(walking)); assertNotNull(aggregatedStatistics.get(walking));
Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks()); assertEquals(1, aggregatedStatistics.get(biking).getCountTracks());
Assert.assertEquals(1, aggregatedStatistics.get(running).getCountTracks()); assertEquals(1, aggregatedStatistics.get(running).getCountTracks());
Assert.assertEquals(1, aggregatedStatistics.get(walking).getCountTracks()); assertEquals(1, aggregatedStatistics.get(walking).getCountTracks());
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0); assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime, statistics2.getMovingTime()); assertEquals(totalTime, statistics2.getMovingTime());
} }
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics();
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0); assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime, statistics2.getMovingTime()); assertEquals(totalTime, statistics2.getMovingTime());
} }
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics();
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0); assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime, statistics2.getMovingTime()); assertEquals(totalTime, statistics2.getMovingTime());
} }
} }
@@ -212,46 +214,46 @@ public class AggregatedStatisticsTest {
// then // then
// 4 sports. // 4 sports.
Assert.assertEquals(4, aggregatedStatistics.getCount()); assertEquals(4, aggregatedStatistics.getCount());
// There is a map for every sport. // There is a map for every sport.
Assert.assertNotNull(aggregatedStatistics.get(biking)); assertNotNull(aggregatedStatistics.get(biking));
Assert.assertNotNull(aggregatedStatistics.get(running)); assertNotNull(aggregatedStatistics.get(running));
Assert.assertNotNull(aggregatedStatistics.get(walking)); assertNotNull(aggregatedStatistics.get(walking));
Assert.assertNotNull(aggregatedStatistics.get(driving)); assertNotNull(aggregatedStatistics.get(driving));
// Number of tracks by sport. // Number of tracks by sport.
Assert.assertEquals(5, aggregatedStatistics.get(biking).getCountTracks()); // Biking. assertEquals(5, aggregatedStatistics.get(biking).getCountTracks()); // Biking.
Assert.assertEquals(2, aggregatedStatistics.get(running).getCountTracks()); // Running. assertEquals(2, aggregatedStatistics.get(running).getCountTracks()); // Running.
Assert.assertEquals(2, aggregatedStatistics.get(walking).getCountTracks()); // Walking. assertEquals(2, aggregatedStatistics.get(walking).getCountTracks()); // Walking.
Assert.assertEquals(1, aggregatedStatistics.get(driving).getCountTracks()); // Driving. assertEquals(1, aggregatedStatistics.get(driving).getCountTracks()); // Driving.
// Biking. // Biking.
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
Assert.assertEquals(totalDistance * 5, statistics2.getTotalDistance(), 0); assertEquals(totalDistance * 5, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime * 5, statistics2.getMovingTime()); assertEquals(totalTime * 5, statistics2.getMovingTime());
} }
// Running. // Running.
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics();
Assert.assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0); assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime * 2, statistics2.getMovingTime()); assertEquals(totalTime * 2, statistics2.getMovingTime());
} }
// Walking. // Walking.
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics();
Assert.assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0); assertEquals(totalDistance * 2, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime * 2, statistics2.getMovingTime()); assertEquals(totalTime * 2, statistics2.getMovingTime());
} }
// Driving. // Driving.
{ {
TrackStatistics statistics2 = aggregatedStatistics.get(driving).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(driving).getTrackStatistics();
Assert.assertEquals(totalDistance, statistics2.getTotalDistance(), 0); assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
Assert.assertEquals(totalTime, statistics2.getMovingTime()); assertEquals(totalTime, statistics2.getMovingTime());
} }
} }
} }
@@ -0,0 +1,144 @@
package de.dennisguse.opentracks.viewmodels;
import android.util.Pair;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.Arrays;
import java.util.List;
import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.UnitConversions;
import static org.junit.Assert.assertEquals;
@RunWith(JUnit4.class)
public class IntervalStatisticsTest {
private static final String TAG = IntervalStatisticsTest.class.getSimpleName();
private List<TrackPoint> buildTrackPoints(int numberOfTrackPoints) {
Pair<Track, TrackPoint[]> pair = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), numberOfTrackPoints);
return Arrays.asList(pair.second);
}
private TrackStatistics buildTrackStatistics(List<TrackPoint> trackPoints) {
TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(trackPoints.get(0).getTime());
for (TrackPoint tp : trackPoints) {
trackStatisticsUpdater.addTrackPoint(tp, 0);
}
return trackStatisticsUpdater.getTrackStatistics();
}
/**
* Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result.
*/
@Test
public void testBuild_1() {
// With 50 points and interval distance of 1000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(50);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 1000f;
IntervalStatistics intervalStatistics = new IntervalStatistics();
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval, intervalStatistics);
}
/**
* Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result.
*/
@Test
public void testBuild_2() {
// With 200 points and interval distance of 1000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(200);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 1000f;
IntervalStatistics intervalStatistics = new IntervalStatistics();
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval, intervalStatistics);
}
/**
* Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result.
*/
@Test
public void testBuild_3() {
// With 200 points and interval distance of 3000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(200);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 3000;
IntervalStatistics intervalStatistics = new IntervalStatistics();
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval, intervalStatistics);
}
/**
* Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result.
*/
@Test
public void testBuild_4() {
// With 1000 points and interval distance of 3000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(1000);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 3000;
IntervalStatistics intervalStatistics = new IntervalStatistics();
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval, intervalStatistics);
}
/**
* Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result.
*/
@Test
public void testBuild_5() {
// With 10000 points and interval distance of 1000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(10000);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 1000;
IntervalStatistics intervalStatistics = new IntervalStatistics();
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval, intervalStatistics);
}
private void whenAndThen(List<TrackPoint> trackPoints, TrackStatistics trackStatistics, float distanceInterval, IntervalStatistics intervalStatistics) {
intervalStatistics.build(trackPoints, distanceInterval);
List<IntervalStatistics.Interval> intervalList = intervalStatistics.getIntervalList();
double totalDistance = 0d;
long totalTime = 0L;
for (IntervalStatistics.Interval i : intervalList) {
totalDistance += i.getDistance_m();
totalTime += ((i.getDistance_m() / i.getSpeed_ms()) * UnitConversions.S_TO_MS);
}
// then
assertEquals(trackStatistics.getTotalDistance(), totalDistance, 0.01);
assertEquals(trackStatistics.getTotalTime() * UnitConversions.MS_TO_S, totalTime * UnitConversions.MS_TO_S, 0.1);
assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance() / distanceInterval));
for (int i = 0; i < intervalList.size() - 1; i++) {
assertEquals(intervalList.get(i).getDistance_m(), distanceInterval, 0.001);
totalDistance -= intervalList.get(i).getDistance_m();
}
assertEquals(intervalList.get(intervalList.size() - 1).getDistance_m(), totalDistance, 0.01);
}
}
@@ -11,7 +11,6 @@ import androidx.appcompat.app.AppCompatActivity;
import java.util.Set; import java.util.Set;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
import de.dennisguse.opentracks.content.provider.ShareContentProvider; import de.dennisguse.opentracks.content.provider.ShareContentProvider;
import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.util.IntentDashboardUtils; import de.dennisguse.opentracks.util.IntentDashboardUtils;
@@ -31,7 +30,7 @@ public abstract class ShowOnMapProxyActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Set<Track.Id> trackIds = IntentDashboardUtils.extractTrackIdsFromIntent(getIntent()); Set<Track.Id> trackIds = IntentDashboardUtils.extractTrackIdsFromIntent(getIntent());
showTrackTrackfileFormat(this, trackFileFormat, trackIds); showTrackfileFormat(this, trackFileFormat, trackIds);
finish(); finish();
} }
@@ -42,14 +41,14 @@ public abstract class ShowOnMapProxyActivity extends AppCompatActivity {
* @param context the context * @param context the context
* @param trackIds the track ids * @param trackIds the track ids
*/ */
private static void showTrackTrackfileFormat(Context context, TrackFileFormat trackFileFormat, Set<Track.Id> trackIds) { private static void showTrackfileFormat(Context context, TrackFileFormat trackFileFormat, Set<Track.Id> trackIds) {
if (trackIds.size() == 0) { if (trackIds.size() == 0) {
return; return;
} }
Intent intent = new Intent(android.content.Intent.ACTION_VIEW); Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(TrackPointsColumns.TRACKID, trackIds.toArray(new Track.Id[0])[0]);
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, "SharingTrack", trackFileFormat); Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, "SharingTrack", trackFileFormat);
intent.setDataAndType(uriAndMime.first, uriAndMime.second); intent.setDataAndType(uriAndMime.first, uriAndMime.second);
@@ -24,6 +24,7 @@ import android.view.MenuItem;
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.FragmentPagerAdapter; import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
@@ -36,6 +37,7 @@ import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.fragments.ChartFragment; import de.dennisguse.opentracks.fragments.ChartFragment;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment; import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment; import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
import de.dennisguse.opentracks.fragments.IntervalsRecordedFragment;
import de.dennisguse.opentracks.fragments.StatisticsRecordedFragment; import de.dennisguse.opentracks.fragments.StatisticsRecordedFragment;
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
import de.dennisguse.opentracks.settings.SettingsActivity; import de.dennisguse.opentracks.settings.SettingsActivity;
@@ -65,8 +67,7 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
private TrackDataHub trackDataHub; private TrackDataHub trackDataHub;
private ViewPager pager; private ViewPager pager;
// From intent. private Track track;
private Track.Id trackId;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -77,42 +78,8 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
trackDataHub = new TrackDataHub(this); trackDataHub = new TrackDataHub(this);
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager(), 1) {
@Override
public int getCount() {
return 3;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new StatisticsRecordedFragment();
case 1:
return ChartFragment.newInstance(false);
case 2:
return ChartFragment.newInstance(true);
default:
throw new RuntimeException("There isn't Fragment associated with the position: " + position);
}
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.track_detail_stats_tab);
case 1:
return getString(R.string.settings_chart_by_time);
case 2:
return getString(R.string.settings_chart_by_distance);
}
return "Unknown Tab";
}
};
pager = findViewById(R.id.track_detail_activity_view_pager); pager = findViewById(R.id.track_detail_activity_view_pager);
pager.setAdapter(adapter); pager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
TabLayout tabs = findViewById(R.id.track_detail_activity_tablayout); TabLayout tabs = findViewById(R.id.track_detail_activity_tablayout);
tabs.setupWithViewPager(pager); tabs.setupWithViewPager(pager);
if (savedInstanceState != null) { if (savedInstanceState != null) {
@@ -133,8 +100,8 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
// Update UI // Update UI
this.invalidateOptionsMenu(); this.invalidateOptionsMenu();
if (trackId.isValid()) { if (track != null) {
trackDataHub.loadTrack(trackId); trackDataHub.loadTrack(track.getId());
} }
} }
@@ -172,7 +139,6 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.track_detail_markers).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); menu.findItem(R.id.track_detail_markers).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.findItem(R.id.track_detail_resume_track).setVisible(!PreferencesUtils.isRecording(this)); menu.findItem(R.id.track_detail_resume_track).setVisible(!PreferencesUtils.isRecording(this));
Track track = contentProviderUtils.getTrack(trackId);
setTitle(track != null ? track.getName() : ""); setTitle(track != null ? track.getName() : "");
return super.onPrepareOptionsMenu(menu); return super.onPrepareOptionsMenu(menu);
} }
@@ -182,29 +148,29 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
Intent intent; Intent intent;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.track_detail_share: case R.id.track_detail_share:
intent = IntentUtils.newShareFileIntent(this, trackId); intent = IntentUtils.newShareFileIntent(this, track.getId());
intent = Intent.createChooser(intent, null); intent = Intent.createChooser(intent, null);
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.track_detail_menu_show_on_map: case R.id.track_detail_menu_show_on_map:
IntentDashboardUtils.startDashboard(this, false, trackId); IntentDashboardUtils.startDashboard(this, false, track.getId());
return true; return true;
case R.id.track_detail_markers: case R.id.track_detail_markers:
intent = IntentUtils.newIntent(this, MarkerListActivity.class) intent = IntentUtils.newIntent(this, MarkerListActivity.class)
.putExtra(MarkerListActivity.EXTRA_TRACK_ID, trackId); .putExtra(MarkerListActivity.EXTRA_TRACK_ID, track.getId());
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.track_detail_edit: case R.id.track_detail_edit:
intent = IntentUtils.newIntent(this, TrackEditActivity.class) intent = IntentUtils.newIntent(this, TrackEditActivity.class)
.putExtra(TrackEditActivity.EXTRA_TRACK_ID, trackId); .putExtra(TrackEditActivity.EXTRA_TRACK_ID, track.getId());
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.track_detail_delete: case R.id.track_detail_delete:
deleteTracks(trackId); deleteTracks(track.getId());
return true; return true;
case R.id.track_detail_resume_track: case R.id.track_detail_resume_track:
Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class) Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class)
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId); .putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, track.getId());
startActivity(newIntent); startActivity(newIntent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
finish(); finish();
@@ -238,7 +204,7 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
} }
private void handleIntent(Intent intent) { private void handleIntent(Intent intent) {
trackId = intent.getParcelableExtra(EXTRA_TRACK_ID); Track.Id trackId = intent.getParcelableExtra(EXTRA_TRACK_ID);
Waypoint.Id waypointId = intent.getParcelableExtra(EXTRA_MARKER_ID); Waypoint.Id waypointId = intent.getParcelableExtra(EXTRA_MARKER_ID);
if (waypointId != null) { if (waypointId != null) {
@@ -255,6 +221,8 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
Log.e(TAG, "TrackDetailActivity needs EXTRA_TRACK_ID."); Log.e(TAG, "TrackDetailActivity needs EXTRA_TRACK_ID.");
finish(); finish();
} }
track = contentProviderUtils.getTrack(trackId);
} }
public void chooseActivityType(String category) { public void chooseActivityType(String category) {
@@ -263,8 +231,52 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
@Override @Override
public void onChooseActivityTypeDone(String iconValue) { public void onChooseActivityTypeDone(String iconValue) {
Track track = contentProviderUtils.getTrack(trackId);
String category = getString(TrackIconUtils.getIconActivityType(iconValue)); String category = getString(TrackIconUtils.getIconActivityType(iconValue));
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils); TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
} }
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
public CustomFragmentPagerAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
@Override
public int getCount() {
return 4;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return StatisticsRecordedFragment.newInstance(track.getId());
case 1:
return IntervalsRecordedFragment.newInstance(track.getId());
case 2:
return ChartFragment.newInstance(false);
case 3:
return ChartFragment.newInstance(true);
default:
throw new RuntimeException("There isn't Fragment associated with the position: " + position);
}
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.track_detail_stats_tab);
case 1:
return getString(R.string.track_detail_intervals_tab);
case 2:
return getString(R.string.settings_chart_by_time);
case 3:
return getString(R.string.settings_chart_by_distance);
default:
throw new RuntimeException("There isn't Fragment associated with the position: " + position);
}
}
}
} }
@@ -25,6 +25,7 @@ import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.fragments.ChartFragment; import de.dennisguse.opentracks.fragments.ChartFragment;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment; import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
import de.dennisguse.opentracks.fragments.IntervalsRecordingFragment;
import de.dennisguse.opentracks.fragments.StatisticsRecordingFragment; import de.dennisguse.opentracks.fragments.StatisticsRecordingFragment;
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
import de.dennisguse.opentracks.services.TrackRecordingServiceInterface; import de.dennisguse.opentracks.services.TrackRecordingServiceInterface;
@@ -166,6 +167,7 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
//Activity was recreated. //Activity was recreated.
trackId = savedInstanceState.getParcelable(EXTRA_TRACK_ID); trackId = savedInstanceState.getParcelable(EXTRA_TRACK_ID);
} else { } else {
// Resume a track
trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID); trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID);
if (trackId != null && contentProviderUtils.getTrack(trackId) == null) { if (trackId != null && contentProviderUtils.getTrack(trackId) == null) {
Log.w(TAG, "TrackId does not exists; cannot continue the recording."); Log.w(TAG, "TrackId does not exists; cannot continue the recording.");
@@ -180,7 +182,7 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
trackDataHub = new TrackDataHub(this); trackDataHub = new TrackDataHub(this);
pager = findViewById(R.id.track_detail_activity_view_pager); pager = findViewById(R.id.track_detail_activity_view_pager);
pager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), 1)); pager.setAdapter(new CustomFragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT));
TabLayout tabs = findViewById(R.id.track_detail_activity_tablayout); TabLayout tabs = findViewById(R.id.track_detail_activity_tablayout);
tabs.setupWithViewPager(pager); tabs.setupWithViewPager(pager);
if (savedInstanceState != null) { if (savedInstanceState != null) {
@@ -372,7 +374,7 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
@Override @Override
public int getCount() { public int getCount() {
return 3; return 4;
} }
@NonNull @NonNull
@@ -380,10 +382,12 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
public Fragment getItem(int position) { public Fragment getItem(int position) {
switch (position) { switch (position) {
case 0: case 0:
return new StatisticsRecordingFragment(); return StatisticsRecordingFragment.newInstance();
case 1: case 1:
return ChartFragment.newInstance(false); return IntervalsRecordingFragment.newInstance(trackId);
case 2: case 2:
return ChartFragment.newInstance(false);
case 3:
return ChartFragment.newInstance(true); return ChartFragment.newInstance(true);
default: default:
throw new RuntimeException("There isn't Fragment associated with the position: " + position); throw new RuntimeException("There isn't Fragment associated with the position: " + position);
@@ -396,8 +400,10 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
case 0: case 0:
return getString(R.string.track_detail_stats_tab); return getString(R.string.track_detail_stats_tab);
case 1: case 1:
return getString(R.string.settings_chart_by_time); return getString(R.string.track_detail_intervals_tab);
case 2: case 2:
return getString(R.string.settings_chart_by_time);
case 3:
return getString(R.string.settings_chart_by_distance); return getString(R.string.settings_chart_by_distance);
default: default:
throw new RuntimeException("There isn't Fragment associated with the position: " + position); throw new RuntimeException("There isn't Fragment associated with the position: " + position);
@@ -0,0 +1,68 @@
package de.dennisguse.opentracks.adapters;
import android.content.Context;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.StringUtils;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
public class IntervalStatisticsAdapter extends ArrayAdapter<IntervalStatistics.Interval> {
private boolean metricUnits;
private float sumDistance_m = 0f;
public IntervalStatisticsAdapter(Context context, List<IntervalStatistics.Interval> intervalList) {
super(context, R.layout.interval_stats_list_item, intervalList);
metricUnits = PreferencesUtils.isMetricUnits(context);
}
@NonNull
@Override
public View getView(int position, @Nullable View intervalView, @NonNull ViewGroup parent) {
IntervalStatistics.Interval interval = getItem(position);
ViewHolder viewHolder;
if (intervalView == null) {
viewHolder = new ViewHolder();
intervalView = LayoutInflater.from(getContext()).inflate(R.layout.interval_stats_list_item, parent, false);
viewHolder.distance = intervalView.findViewById(R.id.interval_item_distance);
viewHolder.speed = intervalView.findViewById(R.id.interval_item_speed);
viewHolder.pace = intervalView.findViewById(R.id.interval_item_pace);
intervalView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) intervalView.getTag();
}
sumDistance_m += interval.getDistance_m();
viewHolder.distance.setText(StringUtils.formatDistance(getContext(), sumDistance_m, metricUnits));
Pair<String, String> speedParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, true);
viewHolder.speed.setText(speedParts.first + " " + speedParts.second);
Pair<String, String> paceParts = StringUtils.getSpeedParts(getContext(), interval.getSpeed_ms(), metricUnits, false);
viewHolder.pace.setText(paceParts.first + " " + paceParts.second);
return intervalView;
}
private static class ViewHolder {
private TextView distance;
private TextView speed;
private TextView pace;
}
}
@@ -836,7 +836,7 @@ public class ContentProviderUtils {
/** /**
* Creates the {@link ContentValues} for a {@link TrackPoint}. * Creates the {@link ContentValues} for a {@link TrackPoint}.
* *
* @param trackPoint the trackPoint * @param trackPoint the trackPointstats_pace_km#87
* @param trackId the track id * @param trackId the track id
*/ */
private ContentValues createContentValues(TrackPoint trackPoint, Track.Id trackId) { private ContentValues createContentValues(TrackPoint trackPoint, Track.Id trackId) {
@@ -209,7 +209,7 @@ public class ExportProgressDialogFragment extends DialogFragment {
TrackExporter trackExporter = trackFileFormat.newTrackExporter(context); TrackExporter trackExporter = trackFileFormat.newTrackExporter(context);
//TODO Move to helper function //TODO Move to helper function
String fileName = track.getId() + "." + trackFileFormat.getExtension(); String fileName = track.getId().getId() + "." + trackFileFormat.getExtension();
// Overwrite a file if it exists; DocumentFile.createFile() creates a new file appending a suffix if the displayname already exists. // Overwrite a file if it exists; DocumentFile.createFile() creates a new file appending a suffix if the displayname already exists.
DocumentFile file = directory.findFile(fileName); DocumentFile file = directory.findFile(fileName);
@@ -0,0 +1,93 @@
package de.dennisguse.opentracks.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProvider;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel;
import de.dennisguse.opentracks.views.IntervalListView;
/**
* A fragment to display the intervals from recorded track.
*/
public class IntervalsRecordedFragment extends Fragment implements IntervalListView.IntervalListListener {
private static final String TAG = IntervalsRecordedFragment.class.getSimpleName();
private static final String TRACK_ID_KEY = "trackId";
private IntervalStatisticsModel viewModel;
private IntervalListView intervalListView;
private Track.Id trackId;
public static Fragment newInstance(Track.Id trackId) {
Bundle bundle = new Bundle();
bundle.putParcelable(TRACK_ID_KEY, trackId);
Fragment fragment = new IntervalsRecordedFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.intervals_recording, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
trackId = getArguments().getParcelable(TRACK_ID_KEY);
intervalListView = new IntervalListView(getActivity(), this);
intervalListView.setId(View.generateViewId());
LinearLayout linearLayout = view.findViewById(R.id.root_view);
linearLayout.removeAllViews();
linearLayout.addView(intervalListView);
viewModel = new ViewModelProvider(this).get(IntervalStatisticsModel.class);
intervalChanged(null);
}
@Override
public void onDestroy() {
super.onDestroy();
intervalListView.destroy();
intervalListView = null;
viewModel = null;
}
/**
* Update intervals through {@link IntervalStatisticsModel} view model.
*
* @param interval intervals will split in this interval if not null. If it's null then view model will use the default one.
*/
@Override
public void intervalChanged(@Nullable IntervalStatisticsModel.IntervalOption interval) {
if (viewModel == null || intervalListView == null) {
return;
}
LiveData<IntervalStatistics> liveData = viewModel.getIntervalStats(trackId, interval);
liveData.observe(getActivity(), intervalStatistics -> {
if (intervalStatistics != null) {
intervalListView.display(intervalStatistics.getIntervalList());
}
});
}
}
@@ -0,0 +1,127 @@
package de.dennisguse.opentracks.fragments;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProvider;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.util.UnitConversions;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel;
import de.dennisguse.opentracks.views.IntervalListView;
/**
* A fragment to display the intervals from recording track.
*/
public class IntervalsRecordingFragment extends Fragment implements IntervalListView.IntervalListListener {
private static final String TAG = IntervalsRecordingFragment.class.getSimpleName();
private static final String TRACK_ID_KEY = "trackId";
// Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience.
private static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS;
private IntervalStatisticsModel viewModel;
private IntervalListView.IntervalReverseListView intervalListView;
private Track.Id trackId;
public static Fragment newInstance(Track.Id trackId) {
Bundle bundle = new Bundle();
bundle.putParcelable(TRACK_ID_KEY, trackId);
Fragment fragment = new IntervalsRecordingFragment();
fragment.setArguments(bundle);
return fragment;
}
private final Runnable intervalRunner = new Runnable() {
@Override
public void run() {
if (isResumed()) {
updateIntervals();
intervalHandler.postDelayed(intervalRunner, UI_UPDATE_INTERVAL);
}
}
};
private Handler intervalHandler;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.intervals_recording, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
trackId = getArguments().getParcelable(TRACK_ID_KEY);
intervalHandler = new Handler();
intervalListView = new IntervalListView.IntervalReverseListView(getActivity(), this);
intervalListView.setId(View.generateViewId());
LinearLayout linearLayout = view.findViewById(R.id.root_view);
linearLayout.removeAllViews();
linearLayout.addView(intervalListView);
viewModel = new ViewModelProvider(this).get(IntervalStatisticsModel.class);
}
@Override
public void onResume() {
super.onResume();
intervalHandler.post(intervalRunner);
}
@Override
public void onPause() {
super.onPause();
intervalHandler.removeCallbacks(intervalRunner);
}
@Override
public void onDestroy() {
super.onDestroy();
intervalListView.destroy();
intervalListView = null;
viewModel = null;
}
/**
* Update intervals through {@link IntervalStatisticsModel} view model.
*
* @param interval intervals will split in this interval if not null. If it's null then view model will use the default one.
*/
@Override
public void intervalChanged(@Nullable IntervalStatisticsModel.IntervalOption interval) {
if (viewModel == null || intervalListView == null) {
return;
}
LiveData<IntervalStatistics> liveData = viewModel.getIntervalStats(trackId, interval);
liveData.observe(getActivity(), intervalStatistics -> {
if (intervalStatistics != null) {
intervalListView.display(intervalStatistics.getIntervalList());
}
});
}
private void updateIntervals() {
intervalChanged(null);
}
}
@@ -33,11 +33,8 @@ import androidx.fragment.app.Fragment;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.TrackRecordedActivity; import de.dennisguse.opentracks.TrackRecordedActivity;
import de.dennisguse.opentracks.content.TrackDataHub;
import de.dennisguse.opentracks.content.TrackDataListener;
import de.dennisguse.opentracks.content.data.Track; 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.content.data.Waypoint;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.PreferencesUtils; import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.StringUtils; import de.dennisguse.opentracks.util.StringUtils;
@@ -49,10 +46,13 @@ import de.dennisguse.opentracks.util.TrackIconUtils;
* @author Sandor Dornbush * @author Sandor Dornbush
* @author Rodrigo Damazio * @author Rodrigo Damazio
*/ */
public class StatisticsRecordedFragment extends Fragment implements TrackDataListener { public class StatisticsRecordedFragment extends Fragment {
private TrackStatistics trackStatistics = null; private static final String TRACK_ID_KEY = "trackId";
private TrackStatistics trackStatistics;
private String category = ""; private String category = "";
private Track track;
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> { private 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)) {
@@ -71,7 +71,6 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
return inflater.inflate(R.layout.statistics_recorded, container, false); return inflater.inflate(R.layout.statistics_recorded, container, false);
} }
/* Views */
private TextView totalTimeValueView; private TextView totalTimeValueView;
private TextView distanceValue; private TextView distanceValue;
private TextView distanceUnit; private TextView distanceUnit;
@@ -88,6 +87,24 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
private TextView speedMovingValue; private TextView speedMovingValue;
private TextView speedMovingUnit; private TextView speedMovingUnit;
public static StatisticsRecordedFragment newInstance(Track.Id trackId) {
Bundle bundle = new Bundle();
bundle.putParcelable(TRACK_ID_KEY, trackId);
StatisticsRecordedFragment fragment = new StatisticsRecordedFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Track.Id trackId = getArguments().getParcelable(TRACK_ID_KEY);
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getContext());
track = contentProviderUtils.getTrack(trackId);
}
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
@@ -140,23 +157,15 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
super.onResume(); super.onResume();
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener); PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
TrackDataHub trackDataHub = ((TrackRecordedActivity) getActivity()).getTrackDataHub(); loadStatistics();
trackDataHub.registerTrackDataListener(this, true, false, true, true);
}
@Override
public void onPause() {
super.onPause();
PreferencesUtils.unregister(getContext(), sharedPreferenceChangeListener);
TrackDataHub trackDataHub = ((TrackRecordedActivity) getActivity()).getTrackDataHub();
trackDataHub.unregisterTrackDataListener(this);
} }
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
PreferencesUtils.unregister(getContext(), sharedPreferenceChangeListener);
totalTimeValueView = null; totalTimeValueView = null;
distanceValue = null; distanceValue = null;
@@ -180,8 +189,7 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
speedMovingUnit = null; speedMovingUnit = null;
} }
@Override public void loadStatistics() {
public void onTrackUpdated(final Track track) {
if (isResumed()) { if (isResumed()) {
getActivity().runOnUiThread(() -> { getActivity().runOnUiThread(() -> {
if (isResumed()) { if (isResumed()) {
@@ -193,41 +201,6 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
} }
} }
@Override
public void clearTrackPoints() {
// We don't care.
}
@Override
public void onSampledInTrackPoint(TrackPoint trackPoint) {
// We don't care.
}
@Override
public void onSampledOutTrackPoint(TrackPoint trackPoint) {
// We don't care.
}
@Override
public void onNewTrackPointsDone() {
// We don't care.
}
@Override
public void clearWaypoints() {
// We don't care.
}
@Override
public void onNewWaypoint(Waypoint wpt) {
// We don't care.
}
@Override
public void onNewWaypointsDone() {
// We don't care.
}
private void updateUI() { private void updateUI() {
String trackIconValue = TrackIconUtils.getIconValue(getContext(), category); String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
@@ -55,13 +55,17 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
private TrackRecordingServiceConnection trackRecordingServiceConnection = new TrackRecordingServiceConnection(); private TrackRecordingServiceConnection trackRecordingServiceConnection = new TrackRecordingServiceConnection();
private TrackPoint lastTrackPoint = null; private TrackPoint lastTrackPoint;
private TrackStatistics lastTrackStatistics = null; private TrackStatistics lastTrackStatistics;
private String category = ""; private String category = "";
@Deprecated //TODO This should be handled somewhere else; not in the UI. @Deprecated //TODO This should be handled somewhere else; not in the UI.
private int recordingGpsAccuracy; private int recordingGpsAccuracy;
public static Fragment newInstance() {
return new StatisticsRecordingFragment();
}
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
@@ -76,10 +76,7 @@ public class KmzTrackExporter implements TrackExporter {
@Override @Override
public boolean writeTrack(Track[] tracks, @NonNull OutputStream outputStream) { public boolean writeTrack(Track[] tracks, @NonNull OutputStream outputStream) {
ZipOutputStream zipOutputStream = null; try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
try {
zipOutputStream = new ZipOutputStream(outputStream);
// Add kml file // Add kml file
ZipEntry zipEntry = new ZipEntry(KMZ_KML_FILE); ZipEntry zipEntry = new ZipEntry(KMZ_KML_FILE);
zipOutputStream.putNextEntry(zipEntry); zipOutputStream.putNextEntry(zipEntry);
@@ -97,14 +94,6 @@ public class KmzTrackExporter implements TrackExporter {
} catch (InterruptedException | IOException e) { } catch (InterruptedException | IOException e) {
Log.e(TAG, "Unable to write track", e); Log.e(TAG, "Unable to write track", e);
return false; return false;
} finally {
if (zipOutputStream != null) {
try {
zipOutputStream.close();
} catch (IOException e) {
Log.e(TAG, "Unable to close zip input stream", e);
}
}
} }
} }
@@ -42,8 +42,8 @@ class LocationHandler implements HandlerServer.Handler, LocationListener, GpsSta
@Override @Override
public void onStop(Context context) { public void onStop(Context context) {
locationManager = null;
unregisterLocationListener(); unregisterLocationListener();
locationManager = null;
if (gpsStatus != null) { if (gpsStatus != null) {
gpsStatus.stop(); gpsStatus.stop();
gpsStatus = null; gpsStatus = null;
@@ -22,14 +22,18 @@ import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener; import android.speech.tts.UtteranceProgressListener;
import android.util.Log; import android.util.Log;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import de.dennisguse.opentracks.content.data.Track; 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.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.AnnouncementUtils; import de.dennisguse.opentracks.util.AnnouncementUtils;
import de.dennisguse.opentracks.util.PreferencesUtils; import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.UnitConversions;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
/** /**
* This class will periodically announce the user's {@link TrackStatistics}. * This class will periodically announce the user's {@link TrackStatistics}.
@@ -159,9 +163,17 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
Log.i(TAG, "Speech is not allowed at this time."); Log.i(TAG, "Speech is not allowed at this time.");
return; return;
} }
Track track = contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context)); Track track = contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context));
String category = track != null ? track.getCategory() : ""; String category = track != null ? track.getCategory() : "";
String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, category);
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(track.getId());
IntervalStatistics intervalStatistics = new IntervalStatistics();
intervalStatistics.build(trackPoints, (float) (PreferencesUtils.isMetricUnits(context) ? 1 * UnitConversions.KM_TO_M : 1 * UnitConversions.MI_TO_M));
int numIntervals = intervalStatistics.getIntervalList().size();
IntervalStatistics.Interval lastInterval = numIntervals > 0 ? intervalStatistics.getIntervalList().get(numIntervals - 1) : null;
String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, category, lastInterval);
speakAnnouncement(announcement); speakAnnouncement(announcement);
} }
@@ -8,6 +8,8 @@ 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;
@@ -16,6 +18,7 @@ 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;
@@ -189,7 +192,11 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
BluetoothLeSensorPreferenceDialog.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); BluetoothLeSensorPreferenceDialog.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss(); dialog.dismiss();
}); });
builder.setIcon(R.drawable.ic_bluetooth_searching_24dp);
Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_bluetooth_searching_animated_24dp);
((Animatable) icon).start();
builder.setIcon(icon);
builder.setPositiveButton(null, null); builder.setPositiveButton(null, null);
} }
@@ -2,18 +2,22 @@ package de.dennisguse.opentracks.util;
import android.content.Context; import android.content.Context;
import androidx.annotation.Nullable;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
public class AnnouncementUtils { public class AnnouncementUtils {
private AnnouncementUtils() {} private AnnouncementUtils() {}
public static String getAnnouncement(Context context, TrackStatistics trackStatistics, String category) { public static String getAnnouncement(Context context, TrackStatistics trackStatistics, String category, @Nullable IntervalStatistics.Interval currentInterval) {
boolean metricUnits = PreferencesUtils.isMetricUnits(context); boolean metricUnits = PreferencesUtils.isMetricUnits(context);
boolean reportSpeed = PreferencesUtils.isReportSpeed(context, category); boolean reportSpeed = PreferencesUtils.isReportSpeed(context, category);
double distance = trackStatistics.getTotalDistance() * UnitConversions.M_TO_KM; double distance = trackStatistics.getTotalDistance() * UnitConversions.M_TO_KM;
double distancePerTime = trackStatistics.getAverageMovingSpeed() * UnitConversions.MPS_TO_KMH; double distancePerTime = trackStatistics.getAverageMovingSpeed() * UnitConversions.MPS_TO_KMH;
double currentDistancePerTime = currentInterval != null ? currentInterval.getSpeed_ms() * UnitConversions.MPS_TO_KMH : 0;
if (distance == 0) { if (distance == 0) {
return context.getString(R.string.voice_total_distance_zero); return context.getString(R.string.voice_total_distance_zero);
@@ -22,23 +26,36 @@ public class AnnouncementUtils {
if (!metricUnits) { if (!metricUnits) {
distance *= UnitConversions.KM_TO_MI; distance *= UnitConversions.KM_TO_MI;
distancePerTime *= UnitConversions.KM_TO_MI; distancePerTime *= UnitConversions.KM_TO_MI;
currentDistancePerTime *= UnitConversions.KM_TO_MI;
} }
String rate; String rate;
String currentRate;
String currentRateMsg = "";
if (reportSpeed) { if (reportSpeed) {
int speedId = metricUnits ? R.plurals.voiceSpeedKilometersPerHour : R.plurals.voiceSpeedMilesPerHour; int speedId = metricUnits ? R.plurals.voiceSpeedKilometersPerHour : R.plurals.voiceSpeedMilesPerHour;
rate = context.getResources().getQuantityString(speedId, getQuantityCount(distancePerTime), distancePerTime); rate = context.getResources().getQuantityString(speedId, getQuantityCount(distancePerTime), distancePerTime);
currentRate = context.getResources().getQuantityString(speedId, getQuantityCount(currentDistancePerTime), currentDistancePerTime);
currentRateMsg = metricUnits ? context.getString(R.string.voice_speed_current_kilometer, currentRate) : context.getString(R.string.voice_speed_current_mile, currentRate);
} else { } else {
double timePerDistance = distancePerTime == 0 ? 0.0 : 1 / distancePerTime; double timePerDistance = distancePerTime == 0 ? 0.0 : 1 / distancePerTime;
int paceId = metricUnits ? R.string.voice_pace_per_kilometer : R.string.voice_pace_per_mile; int paceId = metricUnits ? R.string.voice_pace_per_kilometer : R.string.voice_pace_per_mile;
long time = Math.round(timePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS); long time = Math.round(timePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS);
rate = context.getString(paceId, getAnnounceTime(context, time)); rate = context.getString(paceId, getAnnounceTime(context, time));
double currentTimePerDistance = currentDistancePerTime == 0 ? 0.0 : 1 / currentDistancePerTime;
long currentTime = Math.round(currentTimePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS);
currentRate = context.getString(paceId, getAnnounceTime(context, currentTime));
currentRateMsg = metricUnits ? context.getString(R.string.voice_pace_current_kilometer, currentRate) : context.getString(R.string.voice_pace_current_mile, currentRate);
} }
int totalDistanceId = metricUnits ? R.plurals.voiceTotalDistanceKilometers : R.plurals.voiceTotalDistanceMiles; int totalDistanceId = metricUnits ? R.plurals.voiceTotalDistanceKilometers : R.plurals.voiceTotalDistanceMiles;
String totalDistance = context.getResources().getQuantityString(totalDistanceId, getQuantityCount(distance), distance); String totalDistance = context.getResources().getQuantityString(totalDistanceId, getQuantityCount(distance), distance);
return context.getString(R.string.voice_template, totalDistance, getAnnounceTime(context, trackStatistics.getMovingTime()), rate); currentRateMsg = currentInterval == null ? "" : " " + currentRateMsg;
return context.getString(R.string.voice_template, totalDistance, getAnnounceTime(context, trackStatistics.getMovingTime()), rate) + currentRateMsg;
} }
private static String getAnnounceTime(Context context, long time) { private static String getAnnounceTime(Context context, long time) {
@@ -65,6 +65,10 @@ public class UnitConversions {
public static final double M_TO_FT = M_TO_MI * MI_TO_FT; public static final double M_TO_FT = M_TO_MI * MI_TO_FT;
// multiplication factor to convert meters per second to kilometers per hour // 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); 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() { private UnitConversions() {
} }
@@ -0,0 +1,89 @@
package de.dennisguse.opentracks.viewmodels;
import java.util.ArrayList;
import java.util.List;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.util.LocationUtils;
import de.dennisguse.opentracks.util.UnitConversions;
public class IntervalStatistics {
List<Interval> intervalList = new ArrayList<>();
/**
* @param trackPointList the list of TrackPoint.
* @param distanceInterval_m the meters of every interval.
*/
public void build(List<TrackPoint> trackPointList, float distanceInterval_m) {
intervalList.clear();
if (trackPointList == null || trackPointList.size() == 0) {
return;
}
Interval interval = new Interval();
for (int i = 1; i < trackPointList.size(); i++) {
TrackPoint prevTrackPoint = trackPointList.get(i - 1);
TrackPoint trackPoint = trackPointList.get(i);
if (LocationUtils.isValidLocation(trackPoint.getLocation()) && LocationUtils.isValidLocation(prevTrackPoint.getLocation())) {
interval.distance_m += prevTrackPoint.distanceTo(trackPoint);
interval.time_ms += trackPoint.getTime() - prevTrackPoint.getTime();
if (interval.distance_m >= distanceInterval_m) {
float adjustFactor = distanceInterval_m / interval.distance_m;
Interval adjustedInterval = new Interval(interval);
adjustedInterval.adjust(adjustFactor);
intervalList.add(adjustedInterval);
interval = new Interval(interval.distance_m - adjustedInterval.distance_m, interval.time_ms - adjustedInterval.time_ms);
}
}
}
if (interval.distance_m > 1f) {
intervalList.add(interval);
}
}
public List<Interval> getIntervalList() {
return intervalList;
}
public static class Interval {
private float distance_m = 0f;
private float time_ms = 0f;
public Interval() {}
public Interval(float distance_m, float time_ms) {
this.distance_m = distance_m;
this.time_ms = time_ms;
}
public Interval(Interval i) {
distance_m = i.distance_m;
time_ms = i.time_ms;
}
public float getDistance_m() {
return distance_m;
}
public void adjust(float adjustFactor) {
distance_m *= adjustFactor;
time_ms *= adjustFactor;
}
/**
* @return speed of the interval in m/s.
*/
public float getSpeed_ms() {
if (distance_m == 0f) {
return 0f;
}
return distance_m / (float) (time_ms * UnitConversions.MS_TO_S);
}
}
}
@@ -0,0 +1,79 @@
package de.dennisguse.opentracks.viewmodels;
import android.app.Application;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
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.PreferencesUtils;
import de.dennisguse.opentracks.util.UnitConversions;
/**
* This view model is used to load intervals for a track.
* It uses a default interval but it can be set from outside to manage the interval length.
*/
public class IntervalStatisticsModel extends AndroidViewModel {
private MutableLiveData<IntervalStatistics> intervalStats = new MutableLiveData<>();
public IntervalStatisticsModel(@NonNull Application application) {
super(application);
}
public LiveData<IntervalStatistics> getIntervalStats(@Nullable Track.Id trackId, @Nullable IntervalOption interval) {
if (interval == null) {
interval = IntervalOption.OPTION_1;
}
if (trackId != null) {
loadIntervalStats(trackId, interval);
}
return intervalStats;
}
private void loadIntervalStats(final Track.Id trackId, IntervalOption interval) {
new Thread(() -> {
Context context = getApplication().getApplicationContext();
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
List<TrackPoint> trackPointList = contentProviderUtils.getTrackPoints(trackId);
IntervalStatistics intervalStatistics = new IntervalStatistics();
float distanceInterval = PreferencesUtils.isMetricUnits(context) ? (float) (interval.getValue() * UnitConversions.KM_TO_M) : (float) (interval.getValue() * UnitConversions.MI_TO_M);
intervalStatistics.build(trackPointList, distanceInterval);
intervalStats.postValue(intervalStatistics);
}).start();
}
/**
* Intervals length this view model support.
*/
public enum IntervalOption {
OPTION_1(1),
OPTION_2(2),
OPTION_3(3),
OPTION_4(4),
OPTION_5(5),
OPTION_10(10),
OPTION_20(20),
OPTION_50(50);
private int value;
IntervalOption(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
}
@@ -0,0 +1,120 @@
package de.dennisguse.opentracks.views;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.Arrays;
import java.util.List;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel;
/**
* LinearLayout view used to build a list of intervals.
* See {@link IntervalStatisticsAdapter}.
*/
public class IntervalListView extends LinearLayout {
protected IntervalStatisticsAdapter adapter;
protected LinearLayout linearLayoutIntervals;
protected Spinner spinnerIntervals;
protected TextView spinnerIntervalsUnit;
protected IntervalListListener listener;
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 (spinnerIntervalsUnit != null) {
spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile));
}
}
};
public IntervalListView(Context context, IntervalListListener listener) {
super(context);
this.listener = listener;
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
inflate(getContext(), R.layout.interval_list_view, this);
linearLayoutIntervals = findViewById(R.id.interval_list);
spinnerIntervals = findViewById(R.id.spinner_intervals);
int[] intValues = Arrays.stream(IntervalStatisticsModel.IntervalOption.values()).mapToInt(i -> i.getValue()).toArray();
spinnerIntervals.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, Arrays.stream(intValues).mapToObj(String::valueOf).toArray(String[]::new)));
spinnerIntervalsUnit = findViewById(R.id.spinner_intervals_unit);
spinnerIntervalsUnit.setText(PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile));
spinnerIntervals.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
IntervalStatisticsModel.IntervalOption interval = IntervalStatisticsModel.IntervalOption.values()[i];
listener.intervalChanged(interval);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void destroy() {
PreferencesUtils.unregister(getContext(), sharedPreferenceChangeListener);
adapter = null;
linearLayoutIntervals = null;
spinnerIntervals = null;
spinnerIntervalsUnit = null;
listener = null;
}
public void display(List<IntervalStatistics.Interval> intervalList) {
if (intervalList == null) {
return;
}
adapter = new IntervalStatisticsAdapter(getContext(), intervalList);
linearLayoutIntervals.removeAllViews();
for (int i = 0; i < adapter.getCount(); i++) {
View intervalView = adapter.getView(i, null, linearLayoutIntervals);
linearLayoutIntervals.addView(intervalView);
}
}
public interface IntervalListListener {
void intervalChanged(IntervalStatisticsModel.IntervalOption interval);
}
/**
* LinearLayout view used to build a list of intervals in a reverse mode, the last one will appear in the first position on the LinearLayout.
* This class is an specialization of {@link IntervalListView} that display the views contained in the LinearLayout in a reverse mode.
*/
public static class IntervalReverseListView extends IntervalListView {
public IntervalReverseListView(Context context, IntervalListListener listener) {
super(context, listener);
}
public void display(List<IntervalStatistics.Interval> intervalList) {
if (intervalList == null) {
return;
}
adapter = new IntervalStatisticsAdapter(getContext(), intervalList);
linearLayoutIntervals.removeAllViews();
for (int i = 0; i < adapter.getCount(); i++) {
View intervalView = adapter.getView(i, null, linearLayoutIntervals);
linearLayoutIntervals.addView(intervalView, 0);
}
}
}
}
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="650"
android:interpolator="@android:interpolator/linear"
android:propertyName="fillAlpha"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:startOffset="400"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:duration="650"
android:interpolator="@android:interpolator/linear"
android:propertyName="fillAlpha"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_bluetooth_searching_24dp">
<target
android:name="smallDot"
android:animation="@anim/bluetooth_searching_smalldot" />
<target
android:name="bigDot"
android:animation="@anim/bluetooth_searching_bigdot" />
</animated-vector>
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stats_split_interval"
style="@style/TextMedium" />
<Spinner
android:id="@+id/spinner_intervals"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/SpinnerCustomText"
android:gravity="center" />
<TextView
android:id="@+id/spinner_intervals_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/unit_kilometer"
style="@style/TextMedium" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/interval_distance"
android:layout_width="0dp"
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" />
<TextView
android:id="@+id/interval_speed"
android:layout_width="0dp"
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_speed" />
<TextView
android:id="@+id/interval_pace"
android:layout_width="0dp"
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_pace" />
</LinearLayout>
<LinearLayout
android:id="@+id/interval_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
@@ -0,0 +1,39 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/interval_item_distance"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/TextMedium"
tools:text="1 km" />
<TextView
android:id="@+id/interval_item_speed"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/TextMedium"
tools:text="15 km/h" />
<TextView
android:id="@+id/interval_item_pace"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/TextMedium"
tools:text="4:00" />
</LinearLayout>
</LinearLayout>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/StatsScrollView">
<LinearLayout
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="16dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
</ScrollView>
@@ -209,5 +209,24 @@
app:layout_constraintRight_toLeftOf="@+id/guideline3" app:layout_constraintRight_toLeftOf="@+id/guideline3"
tools:text="km/h" /> tools:text="km/h" />
<!-- Horizontal line -->
<View
android:id="@+id/stats_speed_horizontal_end_line"
style="@style/StatsHorizontalLine"
android:layout_marginBottom="8dp"
app:layout_constraintLeft_toRightOf="@+id/guideline"
app:layout_constraintRight_toLeftOf="@+id/guideline3"
app:layout_constraintTop_toBottomOf="@+id/stats_max_speed_value" />
<LinearLayout
android:id="@+id/linear_layout_extra"
android:orientation="vertical"
android:layout_marginBottom="16dp"
app:layout_constraintLeft_toRightOf="@+id/guideline"
app:layout_constraintRight_toLeftOf="@+id/guideline3"
app:layout_constraintTop_toBottomOf="@+id/stats_speed_horizontal_end_line"
android:layout_width="0dp"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView> </ScrollView>
+4
View File
@@ -497,6 +497,10 @@ g) haz lo que creas que ayude a OpenTracks.</string>
<string name="voice_speed_miles_per_hour_two">2 millas por hora</string> <string name="voice_speed_miles_per_hour_two">2 millas por hora</string>
<string name="voice_speed_miles_per_hour_zero">0 millas por hora</string> <string name="voice_speed_miles_per_hour_zero">0 millas por hora</string>
<string name="voice_template">OpenTracks de %1$s en %2$s a %3$s</string> <string name="voice_template">OpenTracks de %1$s en %2$s a %3$s</string>
<string name="voice_speed_current_kilometer">Con una velocidad del kilómetro actual de %1$s</string>
<string name="voice_speed_current_mile">Con una velocidad de la milla actual de %1$s</string>
<string name="voice_pace_current_kilometer">Con un ritmo del kilómetro actual de %1$s</string>
<string name="voice_pace_current_mile">Con un ritmo de la milla actual de %1$s</string>
<string name="voice_total_distance_kilometers_few">distancia total de %1$.2f kilómetros</string> <string name="voice_total_distance_kilometers_few">distancia total de %1$.2f kilómetros</string>
<string name="voice_total_distance_kilometers_many">distancia total de %1$.2f kilómetros</string> <string name="voice_total_distance_kilometers_many">distancia total de %1$.2f kilómetros</string>
<string name="voice_total_distance_kilometers_one">distancia total de 1 kilómetro</string> <string name="voice_total_distance_kilometers_one">distancia total de 1 kilómetro</string>
+7
View File
@@ -417,6 +417,8 @@ limitations under the License.
<string name="stats_speed">Speed</string> <string name="stats_speed">Speed</string>
<string name="stats_distance">Distance</string> <string name="stats_distance">Distance</string>
<string name="stats_total_time">Total time</string> <string name="stats_total_time">Total time</string>
<string name="stats_intervals">Intervals</string>
<string name="stats_split_interval">Split interval</string>
<!-- Track --> <!-- Track -->
<string name="track_name_format">Track %1$d</string> <string name="track_name_format">Track %1$d</string>
<string name="track_record_notification">Recording your track&#8230;</string> <string name="track_record_notification">Recording your track&#8230;</string>
@@ -430,6 +432,7 @@ limitations under the License.
<!-- Track Detail --> <!-- Track Detail -->
<string name="track_detail_chart_tab">Chart</string> <string name="track_detail_chart_tab">Chart</string>
<string name="track_detail_stats_tab">Stats</string> <string name="track_detail_stats_tab">Stats</string>
<string name="track_detail_intervals_tab">Intervals</string>
<string name="track_detail_record_success">Now recording a new track</string> <string name="track_detail_record_success">Now recording a new track</string>
<string name="track_detail_resume_success">Now resuming the track</string> <string name="track_detail_resume_success">Now resuming the track</string>
<!-- Track Edit --> <!-- Track Edit -->
@@ -518,6 +521,10 @@ limitations under the License.
<string name="voice_speed_miles_per_hour_two">2 miles per hour</string> <string name="voice_speed_miles_per_hour_two">2 miles per hour</string>
<string name="voice_speed_miles_per_hour_zero">0 miles per hour</string> <string name="voice_speed_miles_per_hour_zero">0 miles per hour</string>
<string name="voice_template">OpenTracks %1$s in %2$s at %3$s</string> <string name="voice_template">OpenTracks %1$s in %2$s at %3$s</string>
<string name="voice_speed_current_kilometer">With a current kilometer speed of %1$s</string>
<string name="voice_speed_current_mile">With a current mile speed of %1$s</string>
<string name="voice_pace_current_kilometer">With a current kilometer pace of %1$s</string>
<string name="voice_pace_current_mile">With a current mile pace of %1$s</string>
<string name="voice_total_distance_kilometers_few">total distance %1$.2f kilometers</string> <string name="voice_total_distance_kilometers_few">total distance %1$.2f kilometers</string>
<string name="voice_total_distance_kilometers_many">total distance %1$.2f kilometers</string> <string name="voice_total_distance_kilometers_many">total distance %1$.2f kilometers</string>
<string name="voice_total_distance_kilometers_one">total distance 1 kilometer</string> <string name="voice_total_distance_kilometers_one">total distance 1 kilometer</string>
+6
View File
@@ -16,4 +16,10 @@
<item name="android:background">@drawable/spinner_background_holo_dark</item> <item name="android:background">@drawable/spinner_background_holo_dark</item>
<item name="android:dropDownSelector">@drawable/list_selector_holo_dark</item> <item name="android:dropDownSelector">@drawable/list_selector_holo_dark</item>
</style> </style>
<style name="SpinnerCustomText" parent="android:Widget.Holo.Spinner">
<item name="android:background">@drawable/spinner_background_holo_dark</item>
<item name="android:dropDownSelector">@drawable/list_selector_holo_dark</item>
<item name="android:padding">0dp</item>
</style>
</resources> </resources>