Cleanup: use ActivityType instead of passing it's id around as String.

Part of #1608.
This commit is contained in:
Dennis Guse
2023-06-24 19:30:00 +02:00
parent 779681088c
commit 425ea0f216
34 changed files with 162 additions and 171 deletions
@@ -46,6 +46,7 @@ import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.TimezoneRule; import de.dennisguse.opentracks.TimezoneRule;
import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.HeartRate;
@@ -95,8 +96,8 @@ public class ExportImportTest {
private final ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context); private final ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
private static final String TRACK_ICON = "the track icon"; private static final ActivityType TRACK_ACTIVITY_TYPE = ActivityType.MOUNTAIN_BIKE;
private static final String TRACK_ACTIVITY_TYPE = "the activity type"; private static final String TRACK_ACTIVITY_TYPE_LOCALIZED = "the activity type";
private static final String TRACK_DESCRIPTION = "the description"; private static final String TRACK_DESCRIPTION = "the description";
private File tmpFile; private File tmpFile;
@@ -180,8 +181,8 @@ public class ExportImportTest {
service.endCurrentTrack(); service.endCurrentTrack();
Track track = contentProviderUtils.getTrack(trackId); Track track = contentProviderUtils.getTrack(trackId);
track.setActivityTypeId(TRACK_ICON);
track.setActivityType(TRACK_ACTIVITY_TYPE); track.setActivityType(TRACK_ACTIVITY_TYPE);
track.setActivityTypeLocalized(TRACK_ACTIVITY_TYPE_LOCALIZED);
track.setDescription(TRACK_DESCRIPTION); track.setDescription(TRACK_DESCRIPTION);
contentProviderUtils.updateTrack(track); contentProviderUtils.updateTrack(track);
@@ -192,7 +193,7 @@ public class ExportImportTest {
assertEquals(2, markers.size()); assertEquals(2, markers.size());
} }
//TODO Does not test images //TODO Does not test marker images
@LargeTest @LargeTest
@Test @Test
public void kmz_with_trackdetail_and_sensordata() throws TimeoutException, IOException { public void kmz_with_trackdetail_and_sensordata() throws TimeoutException, IOException {
@@ -216,10 +217,10 @@ public class ExportImportTest {
// 1. track // 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals(track.getActivityType(), importedTrack.getActivityType()); assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
assertEquals(track.getDescription(), importedTrack.getDescription()); assertEquals(track.getDescription(), importedTrack.getDescription());
assertEquals(track.getName(), importedTrack.getName()); assertEquals(track.getName(), importedTrack.getName());
assertEquals(track.getActivityTypeId(), importedTrack.getActivityTypeId()); assertEquals(track.getActivityType(), importedTrack.getActivityType());
// 2. trackpoints // 2. trackpoints
TrackPointAssert a = new TrackPointAssert(); TrackPointAssert a = new TrackPointAssert();
@@ -323,7 +324,7 @@ public class ExportImportTest {
// 1. track // 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals(track.getActivityType(), importedTrack.getActivityType()); assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
assertEquals(track.getDescription(), importedTrack.getDescription()); assertEquals(track.getDescription(), importedTrack.getDescription());
assertEquals(track.getName(), importedTrack.getName()); assertEquals(track.getName(), importedTrack.getName());
@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.Track;
@@ -79,10 +80,10 @@ public class GPXTrackImporterTest {
// 2. track // 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals("the category", importedTrack.getActivityType()); assertEquals("the category", importedTrack.getActivityTypeLocalized());
assertEquals("the description", importedTrack.getDescription()); assertEquals("the description", importedTrack.getDescription());
assertEquals("2021-01-07 22:51", importedTrack.getName()); assertEquals("2021-01-07 22:51", importedTrack.getName());
assertEquals("UNKNOWN", importedTrack.getActivityTypeId()); assertEquals("UNKNOWN", importedTrack.getActivityType());
//TODO Check trackstatistics //TODO Check trackstatistics
@@ -133,10 +134,10 @@ public class GPXTrackImporterTest {
// 2. track // 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals("", importedTrack.getActivityType()); assertEquals("", importedTrack.getActivityTypeLocalized());
assertEquals("", importedTrack.getDescription()); assertEquals("", importedTrack.getDescription());
assertEquals("20210907_213924.gpx", importedTrack.getName()); assertEquals("20210907_213924.gpx", importedTrack.getName());
assertEquals("", importedTrack.getActivityTypeId()); assertEquals("", importedTrack.getActivityType());
// 3. trackstatistics // 3. trackstatistics
TrackStatistics trackStatistics = importedTrack.getTrackStatistics(); TrackStatistics trackStatistics = importedTrack.getTrackStatistics();
@@ -181,10 +182,10 @@ public class GPXTrackImporterTest {
// 2. track // 2. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals("", importedTrack.getActivityType()); assertEquals("", importedTrack.getActivityTypeLocalized());
assertEquals("", importedTrack.getDescription()); assertEquals("", importedTrack.getDescription());
assertEquals("20210907_213924.gpx", importedTrack.getName()); assertEquals("20210907_213924.gpx", importedTrack.getName());
assertEquals("", importedTrack.getActivityTypeId()); assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
// 3. trackstatistics // 3. trackstatistics
TrackStatistics trackStatistics = importedTrack.getTrackStatistics(); TrackStatistics trackStatistics = importedTrack.getTrackStatistics();
@@ -22,6 +22,7 @@ import java.util.List;
import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.Track;
@@ -70,10 +71,10 @@ public class KMLTrackImporterTest {
// 1. track // 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals("", importedTrack.getActivityType()); assertEquals("", importedTrack.getActivityTypeLocalized());
assertEquals("", importedTrack.getDescription()); assertEquals("", importedTrack.getDescription());
assertEquals("", importedTrack.getName()); assertEquals("", importedTrack.getName());
assertEquals("", importedTrack.getActivityTypeId()); assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
// 2. markers // 2. markers
assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size()); assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size());
@@ -119,10 +120,10 @@ public class KMLTrackImporterTest {
// 1. track // 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals("", importedTrack.getActivityType()); assertEquals("", importedTrack.getActivityTypeLocalized());
assertEquals("", importedTrack.getDescription()); assertEquals("", importedTrack.getDescription());
assertEquals("", importedTrack.getName()); assertEquals("", importedTrack.getName());
assertEquals("", importedTrack.getActivityTypeId()); assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
// 2. markers // 2. markers
assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size()); assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size());
@@ -159,10 +160,10 @@ public class KMLTrackImporterTest {
// 1. track // 1. track
Track importedTrack = contentProviderUtils.getTrack(importTrackId); Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack); assertNotNull(importedTrack);
assertEquals("unknown", importedTrack.getActivityType()); assertEquals("unknown", importedTrack.getActivityTypeLocalized());
assertEquals("Test Track", importedTrack.getDescription()); assertEquals("Test Track", importedTrack.getDescription());
assertEquals("2020-11-28 18:06", importedTrack.getName()); assertEquals("2020-11-28 18:06", importedTrack.getName());
assertEquals("UNKNOWN", importedTrack.getActivityTypeId()); assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
// 2. markers // 2. markers
assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size()); assertEquals(0, contentProviderUtils.getMarkers(importTrackId).size());
@@ -80,7 +80,7 @@ public class DescriptionGeneratorTest {
stats.setTotalAltitudeLoss(6000f); stats.setTotalAltitudeLoss(6000f);
stats.setStartTime(START_TIME); stats.setStartTime(START_TIME);
track.setTrackStatistics(stats); track.setTrackStatistics(stats);
track.setActivityType("hiking"); track.setActivityTypeLocalized("hiking");
String expected = //"Created by" String expected = //"Created by"
"<a href='https://github.com/OpenTracksApp/OpenTracks'>OpenTracks (Debug)</a><p>" "<a href='https://github.com/OpenTracksApp/OpenTracks'>OpenTracks (Debug)</a><p>"
+ "Name: -<br>" + "Name: -<br>"
@@ -118,7 +118,7 @@ public class DescriptionGeneratorTest {
stats.setTotalAltitudeLoss(6000f); stats.setTotalAltitudeLoss(6000f);
stats.setStartTime(START_TIME); stats.setStartTime(START_TIME);
track.setTrackStatistics(stats); track.setTrackStatistics(stats);
track.setActivityType("hiking"); track.setActivityTypeLocalized("hiking");
String expected = //"Created by" String expected = //"Created by"
"<a href='https://github.com/OpenTracksApp/OpenTracks'>OpenTracks (Debug)</a><p>" "<a href='https://github.com/OpenTracksApp/OpenTracks'>OpenTracks (Debug)</a><p>"
+ "Name: -<br>" + "Name: -<br>"
@@ -27,7 +27,7 @@ public class AggregatedStatisticsTest {
private final Context context = ApplicationProvider.getApplicationContext(); private final Context context = ApplicationProvider.getApplicationContext();
private static Track createTrack(Context context, Distance totalDistance, Duration totalTime, String category) { private static Track createTrack(Context context, Distance totalDistance, Duration totalTime, String activityTypeLocalized) {
TrackStatistics statistics = new TrackStatistics(); TrackStatistics statistics = new TrackStatistics();
statistics.setStartTime(Instant.ofEpochMilli(1000L)); // Resulting start time statistics.setStartTime(Instant.ofEpochMilli(1000L)); // Resulting start time
statistics.setStopTime(statistics.getStartTime().plus(totalTime)); statistics.setStopTime(statistics.getStartTime().plus(totalTime));
@@ -40,9 +40,8 @@ public class AggregatedStatisticsTest {
statistics.setMinAltitude(1200.0); // Resulting min altitude statistics.setMinAltitude(1200.0); // Resulting min altitude
Track track = new Track(); Track track = new Track();
track.setActivityTypeId(ActivityType.findByLocalizedString(context, category) track.setActivityType(ActivityType.findByLocalizedString(context, activityTypeLocalized));
.getId()); track.setActivityTypeLocalized(activityTypeLocalized);
track.setActivityType(category);
track.setTrackStatistics(statistics); track.setTrackStatistics(statistics);
return track; return track;
} }
@@ -51,7 +51,7 @@ public class EspressoAggregatedFilterTest {
@Before @Before
public void setUp() { public void setUp() {
Pair<Track, List<TrackPoint>> pair = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 20); Pair<Track, List<TrackPoint>> pair = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 20);
pair.first.setActivityType(CATEGORY); pair.first.setActivityTypeLocalized(CATEGORY);
TestDataUtil.insertTrackWithLocations(new ContentProviderUtils(ApplicationProvider.getApplicationContext()), pair.first, pair.second); TestDataUtil.insertTrackWithLocations(new ContentProviderUtils(ApplicationProvider.getApplicationContext()), pair.first, pair.second);
} }
@@ -47,7 +47,7 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
private TrackRecordingServiceConnection trackRecordingServiceConnection; private TrackRecordingServiceConnection trackRecordingServiceConnection;
private ContentProviderUtils contentProviderUtils; private ContentProviderUtils contentProviderUtils;
private Track track; private Track track;
private String iconValue; private ActivityType activityType;
private TrackEditBinding viewBinding; private TrackEditBinding viewBinding;
@@ -73,32 +73,30 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
viewBinding.fields.trackEditName.setText(track.getName()); viewBinding.fields.trackEditName.setText(track.getName());
viewBinding.fields.trackEditActivityType.setText(track.getActivityType()); viewBinding.fields.trackEditActivityType.setText(track.getActivityTypeLocalized());
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this)); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this));
viewBinding.fields.trackEditActivityType.setAdapter(adapter); viewBinding.fields.trackEditActivityType.setAdapter(adapter);
viewBinding.fields.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> { viewBinding.fields.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> {
String localizedActivityType = (String) viewBinding.fields.trackEditActivityType.getAdapter().getItem(position); String localizedActivityType = (String) viewBinding.fields.trackEditActivityType.getAdapter().getItem(position);
setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType) setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType));
.getId());
}); });
viewBinding.fields.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> { viewBinding.fields.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) { if (!hasFocus) {
String localizedActivityType = viewBinding.fields.trackEditActivityType.getText().toString(); String localizedActivityType = viewBinding.fields.trackEditActivityType.getText().toString();
setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType) setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType));
.getId());
} }
}); });
iconValue = null; activityType = null;
if (bundle != null) { if (bundle != null) {
iconValue = bundle.getString(ICON_VALUE_KEY); activityType = (ActivityType) bundle.getSerializable(ICON_VALUE_KEY);
} }
if (iconValue == null) { if (activityType == null) {
iconValue = track.getActivityTypeId(); activityType = track.getActivityType();
} }
setActivityTypeIcon(iconValue); setActivityTypeIcon(activityType);
viewBinding.fields.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.fields.trackEditActivityType.getText().toString())); viewBinding.fields.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.fields.trackEditActivityType.getText().toString()));
viewBinding.fields.trackEditDescription.setText(track.getDescription()); viewBinding.fields.trackEditDescription.setText(track.getDescription());
@@ -131,7 +129,7 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
@Override @Override
public void onSaveInstanceState(@NonNull Bundle outState) { public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putString(ICON_VALUE_KEY, iconValue); outState.putSerializable(ICON_VALUE_KEY, activityType);
} }
@Override @Override
@@ -140,16 +138,14 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
return viewBinding.getRoot(); return viewBinding.getRoot();
} }
private void setActivityTypeIcon(String iconValue) { private void setActivityTypeIcon(ActivityType activityType) {
this.iconValue = iconValue; this.activityType = activityType;
viewBinding.fields.trackEditActivityTypeIcon.setImageResource(ActivityType.findByActivityTypeId(iconValue) viewBinding.fields.trackEditActivityTypeIcon.setImageResource(activityType.getIconDrawableId());
.getIconDrawableId());
} }
@Override @Override
public void onChooseActivityTypeDone(String value) { public void onChooseActivityTypeDone(ActivityType activityType) {
setActivityTypeIcon(value); setActivityTypeIcon(activityType);
viewBinding.fields.trackEditActivityType.setText(getString(ActivityType.findByActivityTypeId(value) viewBinding.fields.trackEditActivityType.setText(getString(activityType.getFirstLocalizedStringId()));
.getFirstLocalizedStringId()));
} }
} }
@@ -212,14 +212,14 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
int totalDistanceIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE); int totalDistanceIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME); int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
int startTimeOffsetIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME_OFFSET); int startTimeOffsetIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME_OFFSET);
int activityTypeIndex = cursor.getColumnIndexOrThrow(TracksColumns.ACTIVITY_TYPE); int activityTypeIndex = cursor.getColumnIndexOrThrow(TracksColumns.ACTIVITY_TYPE_LOCALIZED);
int descriptionIndex = cursor.getColumnIndexOrThrow(TracksColumns.DESCRIPTION); int descriptionIndex = cursor.getColumnIndexOrThrow(TracksColumns.DESCRIPTION);
int markerCountIndex = cursor.getColumnIndexOrThrow(TracksColumns.MARKER_COUNT); int markerCountIndex = cursor.getColumnIndexOrThrow(TracksColumns.MARKER_COUNT);
Track.Id trackId = new Track.Id(cursor.getLong(idIndex)); Track.Id trackId = new Track.Id(cursor.getLong(idIndex));
boolean isRecording = trackId.equals(recordingStatus.getTrackId()); boolean isRecording = trackId.equals(recordingStatus.getTrackId());
String icon = cursor.getString(iconIndex); String icon = cursor.getString(iconIndex);
int iconId = ActivityType.findByActivityTypeId(icon) int iconId = ActivityType.findBy(icon)
.getIconDrawableId(); .getIconDrawableId();
String name = cursor.getString(nameIndex); String name = cursor.getString(nameIndex);
String totalTime = StringUtils.formatElapsedTime(Duration.ofMillis(cursor.getLong(totalTimeIndex))); String totalTime = StringUtils.formatElapsedTime(Duration.ofMillis(cursor.getLong(totalTimeIndex)));
@@ -517,7 +517,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
@Override @Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
final String[] PROJECTION = new String[]{TracksColumns._ID, TracksColumns.NAME, final String[] PROJECTION = new String[]{TracksColumns._ID, TracksColumns.NAME,
TracksColumns.DESCRIPTION, TracksColumns.ACTIVITY_TYPE, TracksColumns.STARTTIME, TracksColumns.STARTTIME_OFFSET, TracksColumns.DESCRIPTION, TracksColumns.ACTIVITY_TYPE_LOCALIZED, TracksColumns.STARTTIME, TracksColumns.STARTTIME_OFFSET,
TracksColumns.TOTALDISTANCE, TracksColumns.TOTALTIME, TracksColumns.ICON, TracksColumns.MARKER_COUNT}; TracksColumns.TOTALDISTANCE, TracksColumns.TOTALTIME, TracksColumns.ICON, TracksColumns.MARKER_COUNT};
final String sortOrder = TracksColumns.STARTTIME + " DESC"; final String sortOrder = TracksColumns.STARTTIME + " DESC";
@@ -527,7 +527,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
} else { } else {
final String SEARCH_QUERY = TracksColumns.NAME + " LIKE ? OR " + final String SEARCH_QUERY = TracksColumns.NAME + " LIKE ? OR " +
TracksColumns.DESCRIPTION + " LIKE ? OR " + TracksColumns.DESCRIPTION + " LIKE ? OR " +
TracksColumns.ACTIVITY_TYPE + " LIKE ?"; TracksColumns.ACTIVITY_TYPE_LOCALIZED + " LIKE ?";
final String[] selectionArgs = new String[]{"%" + searchQuery + "%", "%" + searchQuery + "%", "%" + searchQuery + "%"}; final String[] selectionArgs = new String[]{"%" + searchQuery + "%", "%" + searchQuery + "%", "%" + searchQuery + "%"};
return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, SEARCH_QUERY, selectionArgs, sortOrder); return new CursorLoader(TrackListActivity.this, TracksColumns.CONTENT_URI, PROJECTION, SEARCH_QUERY, selectionArgs, sortOrder);
} }
@@ -317,11 +317,10 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
} }
@Override @Override
public void onChooseActivityTypeDone(String iconValue) { public void onChooseActivityTypeDone(ActivityType activityType) {
Track track = contentProviderUtils.getTrack(trackId); Track track = contentProviderUtils.getTrack(trackId);
String activityType = getString(ActivityType.findByActivityTypeId(iconValue) String activityTypeLocalized = getString(activityType.getFirstLocalizedStringId());
.getFirstLocalizedStringId()); TrackUtils.updateTrack(this, track, null, activityTypeLocalized, null, contentProviderUtils);
TrackUtils.updateTrack(this, track, null, activityType, null, contentProviderUtils);
} }
private class CustomFragmentPagerAdapter extends FragmentStateAdapter { private class CustomFragmentPagerAdapter extends FragmentStateAdapter {
@@ -49,26 +49,22 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
viewBinding.trackEditName.setText(track.getName()); viewBinding.trackEditName.setText(track.getName());
viewBinding.trackEditActivityType.setText(track.getActivityType()); viewBinding.trackEditActivityType.setText(track.getActivityTypeLocalized());
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this)); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, ActivityType.getLocalizedStrings(this));
viewBinding.trackEditActivityType.setAdapter(adapter); viewBinding.trackEditActivityType.setAdapter(adapter);
viewBinding.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> { viewBinding.trackEditActivityType.setOnItemClickListener((parent, view, position, id) -> {
String localizedActivityType = (String) viewBinding.trackEditActivityType.getAdapter().getItem(position); String localizedActivityType = (String) viewBinding.trackEditActivityType.getAdapter().getItem(position);
setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType) setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType));
.getId());
}); });
viewBinding.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> { viewBinding.trackEditActivityType.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) { if (!hasFocus) {
String localizedActivityType = viewBinding.trackEditActivityType.getText().toString(); String localizedActivityType = viewBinding.trackEditActivityType.getText().toString();
setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType) setActivityTypeIcon(ActivityType.findByLocalizedString(this, localizedActivityType));
.getId());
} }
}); });
String iconValue = track.getActivityTypeId(); setActivityTypeIcon(track.getActivityType());
setActivityTypeIcon(iconValue);
viewBinding.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.trackEditActivityType.getText().toString())); viewBinding.trackEditActivityTypeIcon.setOnClickListener(v -> ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), viewBinding.trackEditActivityType.getText().toString()));
viewBinding.trackEditDescription.setText(track.getDescription()); viewBinding.trackEditDescription.setText(track.getDescription());
@@ -78,7 +74,7 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
{ {
Pair<String, String> parts = SpeedFormatter.Builder() Pair<String, String> parts = SpeedFormatter.Builder()
.setUnit(PreferencesUtils.getUnitSystem()) .setUnit(PreferencesUtils.getUnitSystem())
.setReportSpeedOrPace(PreferencesUtils.isReportSpeed(track.getActivityType())) .setReportSpeedOrPace(PreferencesUtils.isReportSpeed(track.getActivityTypeLocalized()))
.build(this) .build(this)
.getSpeedParts(track.getTrackStatistics().getAverageMovingSpeed()); .getSpeedParts(track.getTrackStatistics().getAverageMovingSpeed());
viewBinding.speed.setText(parts.first); viewBinding.speed.setText(parts.first);
@@ -129,16 +125,14 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements
return viewBinding.getRoot(); return viewBinding.getRoot();
} }
private void setActivityTypeIcon(String iconValue) { private void setActivityTypeIcon(ActivityType activityType) {
viewBinding.trackEditActivityTypeIcon.setImageResource(ActivityType.findByActivityTypeId(iconValue) viewBinding.trackEditActivityTypeIcon.setImageResource(activityType.getIconDrawableId());
.getIconDrawableId());
} }
@Override @Override
public void onChooseActivityTypeDone(String iconValue) { public void onChooseActivityTypeDone(ActivityType activityType) {
setActivityTypeIcon(iconValue); setActivityTypeIcon(activityType);
viewBinding.trackEditActivityType.setText(getString(ActivityType.findByActivityTypeId(iconValue) viewBinding.trackEditActivityType.setText(getString(activityType.getFirstLocalizedStringId()));
.getFirstLocalizedStringId()));
} }
private void resumeTrackAndFinish() { private void resumeTrackAndFinish() {
@@ -164,7 +164,7 @@ public class ChartFragment extends Fragment implements TrackDataHub.Listener {
return; return;
} }
category = track.getActivityType(); category = track.getActivityTypeLocalized();
boolean reportSpeed = PreferencesUtils.isReportSpeed(category); boolean reportSpeed = PreferencesUtils.isReportSpeed(category);
if (reportSpeed != viewBinding.chartView.getReportSpeed()) { if (reportSpeed != viewBinding.chartView.getReportSpeed()) {
viewBinding.chartView.setReportSpeed(reportSpeed); viewBinding.chartView.setReportSpeed(reportSpeed);
@@ -40,6 +40,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import de.dennisguse.opentracks.BuildConfig; import de.dennisguse.opentracks.BuildConfig;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Altitude; import de.dennisguse.opentracks.data.models.Altitude;
import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Distance;
@@ -100,7 +101,7 @@ public class ContentProviderUtils {
int uuidIndex = cursor.getColumnIndexOrThrow(TracksColumns.UUID); int uuidIndex = cursor.getColumnIndexOrThrow(TracksColumns.UUID);
int nameIndex = cursor.getColumnIndexOrThrow(TracksColumns.NAME); int nameIndex = cursor.getColumnIndexOrThrow(TracksColumns.NAME);
int descriptionIndex = cursor.getColumnIndexOrThrow(TracksColumns.DESCRIPTION); int descriptionIndex = cursor.getColumnIndexOrThrow(TracksColumns.DESCRIPTION);
int activityTypeIndex = cursor.getColumnIndexOrThrow(TracksColumns.ACTIVITY_TYPE); int activityTypeLocalizedIndex = cursor.getColumnIndexOrThrow(TracksColumns.ACTIVITY_TYPE_LOCALIZED);
int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME); int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
int startTimeOffsetIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME_OFFSET); int startTimeOffsetIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME_OFFSET);
int stopTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STOPTIME); int stopTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STOPTIME);
@@ -128,8 +129,8 @@ public class ContentProviderUtils {
if (!cursor.isNull(descriptionIndex)) { if (!cursor.isNull(descriptionIndex)) {
track.setDescription(cursor.getString(descriptionIndex)); track.setDescription(cursor.getString(descriptionIndex));
} }
if (!cursor.isNull(activityTypeIndex)) { if (!cursor.isNull(activityTypeLocalizedIndex)) {
track.setActivityType(cursor.getString(activityTypeIndex)); track.setActivityTypeLocalized(cursor.getString(activityTypeLocalizedIndex));
} }
if (!cursor.isNull(startTimeIndex)) { if (!cursor.isNull(startTimeIndex)) {
@@ -163,7 +164,7 @@ public class ContentProviderUtils {
trackStatistics.setTotalAltitudeLoss(cursor.getFloat(altitudeLossIndex)); trackStatistics.setTotalAltitudeLoss(cursor.getFloat(altitudeLossIndex));
} }
if (!cursor.isNull(iconIndex)) { if (!cursor.isNull(iconIndex)) {
track.setActivityTypeId(cursor.getString(iconIndex)); track.setActivityType(ActivityType.findBy(cursor.getString(iconIndex)));
} }
return track; return track;
} }
@@ -290,7 +291,7 @@ public class ContentProviderUtils {
values.put(TracksColumns.UUID, UUIDUtils.toBytes(track.getUuid())); values.put(TracksColumns.UUID, UUIDUtils.toBytes(track.getUuid()));
values.put(TracksColumns.NAME, track.getName()); values.put(TracksColumns.NAME, track.getName());
values.put(TracksColumns.DESCRIPTION, track.getDescription()); values.put(TracksColumns.DESCRIPTION, track.getDescription());
values.put(TracksColumns.ACTIVITY_TYPE, track.getActivityType()); values.put(TracksColumns.ACTIVITY_TYPE_LOCALIZED, track.getActivityTypeLocalized());
values.put(TracksColumns.STARTTIME_OFFSET, track.getZoneOffset().getTotalSeconds()); values.put(TracksColumns.STARTTIME_OFFSET, track.getZoneOffset().getTotalSeconds());
if (trackStatistics.getStartTime() != null) { if (trackStatistics.getStartTime() != null) {
values.put(TracksColumns.STARTTIME, trackStatistics.getStartTime().toEpochMilli()); values.put(TracksColumns.STARTTIME, trackStatistics.getStartTime().toEpochMilli());
@@ -308,7 +309,7 @@ public class ContentProviderUtils {
values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude()); values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude());
values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.getTotalAltitudeGain()); values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.getTotalAltitudeGain());
values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.getTotalAltitudeLoss()); values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.getTotalAltitudeLoss());
values.put(TracksColumns.ICON, track.getActivityTypeId()); values.put(TracksColumns.ICON, track.getActivityType() != null ? track.getActivityType().getIconId() : "");
return values; return values;
} }
@@ -53,7 +53,7 @@ public class TrackSelection implements ContentProviderUtils.ContentProviderSelec
} }
if (!categories.isEmpty()) { if (!categories.isEmpty()) {
selection += selection.isEmpty() ? "" : " AND "; selection += selection.isEmpty() ? "" : " AND ";
selection += String.format(TracksColumns.ACTIVITY_TYPE + " IN (%s)", TextUtils.join(",", Collections.nCopies(categories.size(), "?"))); selection += String.format(TracksColumns.ACTIVITY_TYPE_LOCALIZED + " IN (%s)", TextUtils.join(",", Collections.nCopies(categories.size(), "?")));
} }
if (from != null && to != null) { if (from != null && to != null) {
selection += selection.isEmpty() ? "" : " AND "; selection += selection.isEmpty() ? "" : " AND ";
@@ -34,22 +34,22 @@ public enum ActivityType {
SWIMMING_OPEN("SWIMMING_OPEN", R.drawable.ic_activity_swimming_open_24dp, false, R.string.activity_type_swimming_open), SWIMMING_OPEN("SWIMMING_OPEN", R.drawable.ic_activity_swimming_open_24dp, false, R.string.activity_type_swimming_open),
WORKOUT("WORKOUT", R.drawable.ic_activity_workout_24dp, false, R.string.activity_type_workout); WORKOUT("WORKOUT", R.drawable.ic_activity_workout_24dp, false, R.string.activity_type_workout);
final String id; final String iconId;
final int iconDrawableId; final int iconDrawableId;
final boolean showSpeedPreferred; final boolean showSpeedPreferred;
final int[] localizedStringIds; final int[] localizedStringIds;
//isSpeed? //isSpeed?
ActivityType(String id, int iconDrawableId, boolean showSpeedPreferred, int... localizedStringIds) { ActivityType(String iconId, int iconDrawableId, boolean showSpeedPreferred, int... localizedStringIds) {
this.id = id; this.iconId = iconId;
this.iconDrawableId = iconDrawableId; this.iconDrawableId = iconDrawableId;
this.showSpeedPreferred = showSpeedPreferred; this.showSpeedPreferred = showSpeedPreferred;
this.localizedStringIds = localizedStringIds; this.localizedStringIds = localizedStringIds;
} }
public String getId() { public String getIconId() {
return id; return iconId;
} }
public int getIconDrawableId() { public int getIconDrawableId() {
@@ -81,9 +81,9 @@ public enum ActivityType {
} }
@NonNull @NonNull
public static ActivityType findByActivityTypeId(String activityTypeId) { public static ActivityType findBy(String iconId) {
return Arrays.stream(ActivityType.values()).filter( return Arrays.stream(ActivityType.values()).filter(
it -> it.getId().equals(activityTypeId) it -> it.getIconId().equals(iconId)
).findFirst() ).findFirst()
.orElse(ActivityType.UNKNOWN); .orElse(ActivityType.UNKNOWN);
} }
@@ -44,9 +44,9 @@ public class Track {
private String name = ""; private String name = "";
private String description = ""; private String description = "";
private String activityType = ""; private String activityTypeLocalized = "";
private String activityTypeId = ""; private ActivityType activityType;
private final ZoneOffset zoneOffset; private final ZoneOffset zoneOffset;
@@ -54,7 +54,7 @@ public class Track {
@VisibleForTesting @VisibleForTesting
public Track() { public Track() {
this.zoneOffset = ZoneOffset.UTC; this(ZoneOffset.UTC);
} }
public Track(@NonNull ZoneOffset zoneOffset) { public Track(@NonNull ZoneOffset zoneOffset) {
@@ -97,22 +97,22 @@ public class Track {
this.description = description; this.description = description;
} }
public String getActivityType() { public String getActivityTypeLocalized() {
return activityTypeLocalized;
}
public void setActivityTypeLocalized(String activityType) {
this.activityTypeLocalized = activityType;
}
public ActivityType getActivityType() {
return activityType; return activityType;
} }
public void setActivityType(String activityType) { public void setActivityType(ActivityType activityType) {
this.activityType = activityType; this.activityType = activityType;
} }
public String getActivityTypeId() {
return activityTypeId;
}
public void setActivityTypeId(String activityTypeId) {
this.activityTypeId = activityTypeId;
}
public ZoneOffset getZoneOffset() { public ZoneOffset getZoneOffset() {
return zoneOffset; return zoneOffset;
} }
@@ -39,7 +39,7 @@ public interface TracksColumns extends BaseColumns {
String UUID = "uuid"; // identifier to make tracks globally unique (prevent re-import) String UUID = "uuid"; // identifier to make tracks globally unique (prevent re-import)
String NAME = "name"; // track name String NAME = "name"; // track name
String DESCRIPTION = "description"; // track description String DESCRIPTION = "description"; // track description
String ACTIVITY_TYPE = "category"; // track activity type String ACTIVITY_TYPE_LOCALIZED = "category"; // track activity type
String STARTTIME = "starttime"; // track start time String STARTTIME = "starttime"; // track start time
String STARTTIME_OFFSET = "starttime_offset"; // in plus/minus in seconds String STARTTIME_OFFSET = "starttime_offset"; // in plus/minus in seconds
String STOPTIME = "stoptime"; // track stop time String STOPTIME = "stoptime"; // track stop time
@@ -57,13 +57,13 @@ public interface TracksColumns extends BaseColumns {
String MAX_ALTITUDE = "maxelevation"; // maximum altitude //TODO RENAME column String MAX_ALTITUDE = "maxelevation"; // maximum altitude //TODO RENAME column
String ALTITUDE_GAIN = "elevationgain"; // altitude gain //TODO RENAME column String ALTITUDE_GAIN = "elevationgain"; // altitude gain //TODO RENAME column
String ALTITUDE_LOSS = "elevationloss"; // altitude loss //TODO RENAME column String ALTITUDE_LOSS = "elevationloss"; // altitude loss //TODO RENAME column
String ICON = "icon"; // track activity type icon String ICON = "icon"; // track activity type icon //TODO DEPRECATED
String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ NAME + " TEXT, " + NAME + " TEXT, "
+ DESCRIPTION + " TEXT, " + DESCRIPTION + " TEXT, "
+ ACTIVITY_TYPE + " TEXT, " + ACTIVITY_TYPE_LOCALIZED + " TEXT, "
+ STARTTIME + " INTEGER, " + STARTTIME + " INTEGER, "
+ STOPTIME + " INTEGER, " + STOPTIME + " INTEGER, "
+ NUMPOINTS + " INTEGER, " + NUMPOINTS + " INTEGER, "
@@ -37,7 +37,7 @@ public class ChooseActivityTypeDialogFragment extends DialogFragment implements
return -1; return -1;
} }
String iconValue = ActivityType.findByLocalizedString(context, category) String iconValue = ActivityType.findByLocalizedString(context, category)
.getId(); .getIconId();
return getAllActivityTypeIds().indexOf(iconValue); return getAllActivityTypeIds().indexOf(iconValue);
} }
@@ -66,7 +66,7 @@ public class ChooseActivityTypeDialogFragment extends DialogFragment implements
List<Integer> iconDrawableIds = new ArrayList<>(); List<Integer> iconDrawableIds = new ArrayList<>();
for (String iconValue : getAllActivityTypeIds()) { for (String iconValue : getAllActivityTypeIds()) {
iconDrawableIds.add(ActivityType.findByActivityTypeId(iconValue) iconDrawableIds.add(ActivityType.findBy(iconValue)
.getIconDrawableId()); .getIconDrawableId());
} }
@@ -98,13 +98,14 @@ public class ChooseActivityTypeDialogFragment extends DialogFragment implements
@Override @Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
chooseActivityTypeCaller.onChooseActivityTypeDone(getAllActivityTypeIds().get(position)); chooseActivityTypeCaller.onChooseActivityTypeDone(ActivityType.findBy(getAllActivityTypeIds().get(position)));
dismiss(); dismiss();
} }
// TODO Return List<ActivityType>
public static List<String> getAllActivityTypeIds() { public static List<String> getAllActivityTypeIds() {
return Arrays.stream(ActivityType.values()) return Arrays.stream(ActivityType.values())
.map(ActivityType::getId) .map(ActivityType::getIconId)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@@ -113,6 +114,6 @@ public class ChooseActivityTypeDialogFragment extends DialogFragment implements
*/ */
public interface ChooseActivityTypeCaller { public interface ChooseActivityTypeCaller {
void onChooseActivityTypeDone(String iconValue); void onChooseActivityTypeDone(ActivityType activityType);
} }
} }
@@ -90,7 +90,7 @@ public class StatisticsRecordedFragment extends Fragment {
if (PreferencesUtils.isKey(R.string.stats_rate_key, key) && track != null) { if (PreferencesUtils.isKey(R.string.stats_rate_key, key) && track != null) {
updateUInecessary = true; updateUInecessary = true;
preferenceReportSpeed = PreferencesUtils.isReportSpeed(track.getActivityType()); preferenceReportSpeed = PreferencesUtils.isReportSpeed(track.getActivityTypeLocalized());
} }
if (key != null && updateUInecessary && isResumed()) { if (key != null && updateUInecessary && isResumed()) {
@@ -156,7 +156,7 @@ public class StatisticsRecordedFragment extends Fragment {
sensorStatistics = contentProviderUtils.getSensorStats(trackId); sensorStatistics = contentProviderUtils.getSensorStats(trackId);
boolean prefsChanged = this.track == null || (!this.track.getActivityType().equals(track.getActivityType())); boolean prefsChanged = this.track == null || (!this.track.getActivityTypeLocalized().equals(track.getActivityTypeLocalized()));
this.track = track; this.track = track;
if (prefsChanged) { if (prefsChanged) {
sharedPreferenceChangeListener.onSharedPreferenceChanged(null, getString(R.string.stats_rate_key)); sharedPreferenceChangeListener.onSharedPreferenceChanged(null, getString(R.string.stats_rate_key));
@@ -193,10 +193,10 @@ public class StatisticsRecordedFragment extends Fragment {
// Set activity type // Set activity type
{ {
Context context = getContext(); Context context = getContext();
String localizedActivityType = track.getActivityType(); String localizedActivityType = track.getActivityTypeLocalized();
String trackIconValue = ActivityType.findByLocalizedString(context, localizedActivityType) String trackIconValue = ActivityType.findByLocalizedString(context, localizedActivityType)
.getId(); .getIconId();
viewBinding.statsActivityTypeIcon.setImageDrawable(ContextCompat.getDrawable(getContext(), ActivityType.findByActivityTypeId(trackIconValue) viewBinding.statsActivityTypeIcon.setImageDrawable(ContextCompat.getDrawable(getContext(), ActivityType.findBy(trackIconValue)
.getIconDrawableId())); .getIconDrawableId()));
} }
@@ -44,7 +44,7 @@ public class TrackFilenameGenerator {
values.put(UUID_KEY, track.getUuid().toString().substring(0, 8)); values.put(UUID_KEY, track.getUuid().toString().substring(0, 8));
values.put(TRACKNAME_KEY, track.getName()); values.put(TRACKNAME_KEY, track.getName());
values.put(ACTIVITY_TYPE_KEY, track.getActivityType()); values.put(ACTIVITY_TYPE_KEY, track.getActivityTypeLocalized());
values.put(STARTTIME_TIME_KEY, track.getStartTime().toLocalTime().toString()); values.put(STARTTIME_TIME_KEY, track.getStartTime().toLocalTime().toString());
values.put(STARTTIME_DATE_KEY, track.getStartTime().toLocalDate().toString()); values.put(STARTTIME_DATE_KEY, track.getStartTime().toLocalDate().toString());
@@ -268,7 +268,7 @@ public class GPXTrackExporter implements TrackExporter {
printWriter.println("<trk>"); printWriter.println("<trk>");
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>"); printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println("<desc>" + StringUtils.formatCData(track.getDescription()) + "</desc>"); printWriter.println("<desc>" + StringUtils.formatCData(track.getDescription()) + "</desc>");
printWriter.println("<type>" + StringUtils.formatCData(track.getActivityType()) + "</type>"); printWriter.println("<type>" + StringUtils.formatCData(track.getActivityTypeLocalized()) + "</type>");
printWriter.println("<extensions>"); printWriter.println("<extensions>");
printWriter.println("<topografix:color>c0c0c0</topografix:color>"); printWriter.println("<topografix:color>c0c0c0</topografix:color>");
@@ -307,11 +307,11 @@ public class KMLTrackExporter implements TrackExporter {
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>"); printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println("<description>" + StringUtils.formatCData(track.getDescription()) + "</description>"); printWriter.println("<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
printWriter.println("<icon>" + StringUtils.formatCData(track.getActivityTypeId()) + "</icon>"); printWriter.println("<icon>" + StringUtils.formatCData(track.getActivityType().getIconId()) + "</icon>");
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>"); printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>"); printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>");
writeActivityType(track.getActivityType()); writeActivityType(track.getActivityTypeLocalized());
printWriter.println("<MultiTrack>"); printWriter.println("<MultiTrack>");
printWriter.println("<altitudeMode>absolute</altitudeMode>"); printWriter.println("<altitudeMode>absolute</altitudeMode>");
printWriter.println("<interpolate>1</interpolate>"); printWriter.println("<interpolate>1</interpolate>");
@@ -514,12 +514,12 @@ public class KMLTrackExporter implements TrackExporter {
return result; return result;
} }
private void writeActivityType(String actiivtyType) { private void writeActivityType(String activityTypeLocalized) {
if (actiivtyType == null || actiivtyType.equals("")) { if (activityTypeLocalized == null || activityTypeLocalized.equals("")) {
return; return;
} }
printWriter.println("<ExtendedData>"); printWriter.println("<ExtendedData>");
printWriter.println("<Data name=\"" + EXTENDED_DATA_TYPE_ACTIVITYTYPE + "\"><value>" + StringUtils.formatCData(actiivtyType) + "</value></Data>"); printWriter.println("<Data name=\"" + EXTENDED_DATA_TYPE_ACTIVITYTYPE + "\"><value>" + StringUtils.formatCData(activityTypeLocalized) + "</value></Data>");
printWriter.println("</ExtendedData>"); printWriter.println("</ExtendedData>");
} }
@@ -90,7 +90,7 @@ public class TrackImporter {
this.markers.addAll(markers); this.markers.addAll(markers);
} }
void setTrack(Context context, String name, String uuid, String description, String activityType, String icon, @Nullable ZoneOffset zoneOffset) { void setTrack(Context context, String name, String uuid, String description, String activityTypeLocalized, String activityTypeId, @Nullable ZoneOffset zoneOffset) {
track = new Track(zoneOffset != null ? zoneOffset : ZoneOffset.UTC); track = new Track(zoneOffset != null ? zoneOffset : ZoneOffset.UTC);
track.setName(name != null ? name : ""); track.setName(name != null ? name : "");
@@ -103,16 +103,17 @@ public class TrackImporter {
track.setDescription(description != null ? description : ""); track.setDescription(description != null ? description : "");
if (activityType != null) { if (activityTypeLocalized != null) {
track.setActivityType(activityType); track.setActivityTypeLocalized(activityTypeLocalized);
if (icon == null) {
icon = ActivityType.findByLocalizedString(context, activityType)
.getId();
}
} }
track.setActivityTypeId(icon != null ? icon : ""); ActivityType activityType;
if (activityTypeId == null) {
activityType = ActivityType.findByLocalizedString(context, activityTypeId);
} else {
activityType = ActivityType.findBy(activityTypeId);
}
track.setActivityType(activityType);
} }
void finish() { void finish() {
@@ -5,6 +5,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.PreferencesUtils;
@@ -14,8 +15,8 @@ import de.dennisguse.opentracks.util.TrackUtils;
public class StartRecording extends AbstractAPIActivity { public class StartRecording extends AbstractAPIActivity {
public static final String EXTRA_TRACK_NAME = "TRACK_NAME"; public static final String EXTRA_TRACK_NAME = "TRACK_NAME";
public static final String EXTRA_TRACK_CATEGORY = "TRACK_CATEGORY"; public static final String EXTRA_TRACK_ACTIVITY_TYPE_LOCALIZED = "TRACK_CATEGORY"; //TODO Update constant
public static final String EXTRA_TRACK_ICON = "TRACK_ICON"; public static final String EXTRA_TRACK_ACTIVITY_TYPE_ID = "TRACK_ICON"; //TODO Update constant
public static final String EXTRA_TRACK_DESCRIPTION = "TRACK_DESCRIPTION"; public static final String EXTRA_TRACK_DESCRIPTION = "TRACK_DESCRIPTION";
public static final String EXTRA_STATS_TARGET_PACKAGE = "STATS_TARGET_PACKAGE"; public static final String EXTRA_STATS_TARGET_PACKAGE = "STATS_TARGET_PACKAGE";
@@ -43,8 +44,8 @@ public class StartRecording extends AbstractAPIActivity {
TrackUtils.updateTrack(this, track, TrackUtils.updateTrack(this, track,
bundle.getString(EXTRA_TRACK_NAME, null), bundle.getString(EXTRA_TRACK_NAME, null),
bundle.getString(EXTRA_TRACK_CATEGORY, null), bundle.getString(EXTRA_TRACK_ACTIVITY_TYPE_LOCALIZED, null),
bundle.getString(EXTRA_TRACK_ICON, null), ActivityType.findBy(bundle.getString(EXTRA_TRACK_ACTIVITY_TYPE_ID, null)),
bundle.getString(EXTRA_TRACK_DESCRIPTION, null), bundle.getString(EXTRA_TRACK_DESCRIPTION, null),
contentProviderUtils); contentProviderUtils);
} }
@@ -16,7 +16,7 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData
if (track == null) { if (track == null) {
return ""; return "";
} }
return track.getActivityType(); return track.getActivityTypeLocalized();
} }
@NonNull @NonNull
@@ -73,9 +73,8 @@ class TrackRecordingManager implements SharedPreferences.OnSharedPreferenceChang
onNewTrackPoint(segmentStartTrackPoint); onNewTrackPoint(segmentStartTrackPoint);
String category = PreferencesUtils.getDefaultActivityTypeLocalized(); String category = PreferencesUtils.getDefaultActivityTypeLocalized();
track.setActivityType(category); track.setActivityTypeLocalized(category);
track.setActivityTypeId(ActivityType.findByLocalizedString(context, category) track.setActivityType(ActivityType.findByLocalizedString(context, category));
.getId());
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics()); track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
//TODO Pass TrackPoint //TODO Pass TrackPoint
track.setName(TrackNameUtils.getTrackName(context, trackId, track.getStartTime())); track.setName(TrackNameUtils.getTrackName(context, trackId, track.getStartTime()));
@@ -182,7 +182,7 @@ public class VoiceAnnouncement {
sensorStatistics = contentProviderUtils.getSensorStats(track.getId()); sensorStatistics = contentProviderUtils.getSensorStats(track.getId());
} }
Spannable announcement = VoiceAnnouncementUtils.getAnnouncement(context, track.getTrackStatistics(), PreferencesUtils.getUnitSystem(), PreferencesUtils.isReportSpeed(track.getActivityType()), lastInterval, sensorStatistics); Spannable announcement = VoiceAnnouncementUtils.getAnnouncement(context, track.getTrackStatistics(), PreferencesUtils.getUnitSystem(), PreferencesUtils.isReportSpeed(track.getActivityTypeLocalized()), lastInterval, sensorStatistics);
if (announcement.length() > 0) { if (announcement.length() > 0) {
// We don't care about the utterance id. It is supplied here to force onUtteranceCompleted to be called. // We don't care about the utterance id. It is supplied here to force onUtteranceCompleted to be called.
@@ -83,24 +83,21 @@ public class ActivityTypePreference extends DialogPreference {
textView.setAdapter(adapter); textView.setAdapter(adapter);
textView.setOnItemClickListener((parent, v, position, id) -> { textView.setOnItemClickListener((parent, v, position, id) -> {
String localizedActivityType = (String) textView.getAdapter().getItem(position); String localizedActivityType = (String) textView.getAdapter().getItem(position);
String iconValue = ActivityType.findByLocalizedString(context, localizedActivityType) ActivityType activityType = ActivityType.findByLocalizedString(context, localizedActivityType);
.getId(); updateIcon(activityType);
updateIcon(iconValue);
}); });
textView.setOnFocusChangeListener((v, hasFocus) -> { textView.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) { if (!hasFocus) {
String localizedActivityType = textView.getText().toString(); String localizedActivityType = textView.getText().toString();
String iconValue = ActivityType.findByLocalizedString(context, localizedActivityType) ActivityType activityType = ActivityType.findByLocalizedString(context, localizedActivityType);
.getId(); updateIcon(activityType);
updateIcon(iconValue);
} }
}); });
iconView = view.findViewById(R.id.activity_type_preference_spinner); iconView = view.findViewById(R.id.activity_type_preference_spinner);
iconView.setOnClickListener((it) -> showIconSelectDialog()); iconView.setOnClickListener((it) -> showIconSelectDialog());
updateIcon(ActivityType.findByLocalizedString(context, category) updateIcon(ActivityType.findByLocalizedString(context, category));
.getId());
} }
private void showIconSelectDialog() { private void showIconSelectDialog() {
@@ -119,16 +116,14 @@ public class ActivityTypePreference extends DialogPreference {
} }
} }
public void updateUI(String iconValue) { public void updateUI(ActivityType activityType) {
updateIcon(iconValue); updateIcon(activityType);
textView.setText(getActivity().getString(ActivityType.findByActivityTypeId(iconValue) textView.setText(getActivity().getString(activityType.getFirstLocalizedStringId()));
.getFirstLocalizedStringId()));
textView.clearFocus(); textView.clearFocus();
} }
private void updateIcon(String iconValue) { private void updateIcon(ActivityType activityType) {
iconView.setImageResource(ActivityType.findByActivityTypeId(iconValue) iconView.setImageResource(activityType.getIconDrawableId());
.getIconDrawableId());
} }
} }
} }
@@ -9,6 +9,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment; import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
public class DefaultsSettingsFragment extends PreferenceFragmentCompat implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller { public class DefaultsSettingsFragment extends PreferenceFragmentCompat implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller {
@@ -81,9 +82,9 @@ public class DefaultsSettingsFragment extends PreferenceFragmentCompat implement
} }
@Override @Override
public void onChooseActivityTypeDone(String iconValue) { public void onChooseActivityTypeDone(ActivityType activityType) {
if (activityPreferenceDialog != null) { if (activityPreferenceDialog != null) {
activityPreferenceDialog.updateUI(iconValue); activityPreferenceDialog.updateUI(activityType);
} }
} }
} }
@@ -10,6 +10,7 @@ import androidx.preference.PreferenceFragmentCompat;
import de.dennisguse.opentracks.AbstractActivity; import de.dennisguse.opentracks.AbstractActivity;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.ActivityType;
import de.dennisguse.opentracks.databinding.SettingsBinding; import de.dennisguse.opentracks.databinding.SettingsBinding;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment; import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
@@ -104,9 +105,9 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
} }
@Override @Override
public void onChooseActivityTypeDone(String iconValue) { public void onChooseActivityTypeDone(ActivityType activityType) {
try { try {
((ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller) this.fragment).onChooseActivityTypeDone(iconValue); ((ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller) this.fragment).onChooseActivityTypeDone(activityType);
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new ClassCastException(this.fragment.getClass().getSimpleName() + " must implement " + ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller.class.getSimpleName()); throw new ClassCastException(this.fragment.getClass().getSimpleName() + " must implement " + ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller.class.getSimpleName());
} }
@@ -72,7 +72,7 @@ public class DescriptionGenerator {
builder.append(paragraphSeparator); builder.append(paragraphSeparator);
writeString(track.getName(), builder, R.string.generic_name_line, lineBreak); writeString(track.getName(), builder, R.string.generic_name_line, lineBreak);
writeString(track.getActivityType(), builder, R.string.description_activity_type, lineBreak); writeString(track.getActivityTypeLocalized(), builder, R.string.description_activity_type, lineBreak);
writeString(track.getDescription(), builder, R.string.generic_description_line, lineBreak); writeString(track.getDescription(), builder, R.string.generic_description_line, lineBreak);
builder.append(generateTrackStatisticsDescription(track.getTrackStatistics(), html)); builder.append(generateTrackStatisticsDescription(track.getTrackStatistics(), html));
@@ -33,7 +33,7 @@ public class AggregatedStatistics {
@VisibleForTesting @VisibleForTesting
public void aggregate(@NonNull Track track) { public void aggregate(@NonNull Track track) {
String activityType = track.getActivityType(); String activityType = track.getActivityTypeLocalized();
if (dataMap.containsKey(activityType)) { if (dataMap.containsKey(activityType)) {
dataMap.get(activityType).add(track.getTrackStatistics()); dataMap.get(activityType).add(track.getTrackStatistics());
} else { } else {
@@ -184,8 +184,8 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
private int getIcon(AggregatedStatistics.AggregatedStatistic aggregatedStatistic) { private int getIcon(AggregatedStatistics.AggregatedStatistic aggregatedStatistic) {
String localizedActivityType = aggregatedStatistic.getActivityType(); String localizedActivityType = aggregatedStatistic.getActivityType();
String iconValue = ActivityType.findByLocalizedString(context, localizedActivityType) String iconValue = ActivityType.findByLocalizedString(context, localizedActivityType)
.getId(); .getIconId();
return ActivityType.findByActivityTypeId(iconValue) return ActivityType.findBy(iconValue)
.getIconDrawableId(); .getIconDrawableId();
} }
} }
@@ -151,7 +151,7 @@ public class IntervalsFragment extends Fragment {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getContext()); ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getContext());
Track track = contentProviderUtils.getTrack(trackId); Track track = contentProviderUtils.getTrack(trackId);
if (track != null) { if (track != null) {
isReportSpeed = PreferencesUtils.isReportSpeed(track.getActivityType()); isReportSpeed = PreferencesUtils.isReportSpeed(track.getActivityTypeLocalized());
} }
viewModel = new ViewModelProvider(getActivity()).get(IntervalStatisticsModel.class); viewModel = new ViewModelProvider(getActivity()).get(IntervalStatisticsModel.class);
@@ -27,32 +27,32 @@ import de.dennisguse.opentracks.data.models.Track;
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
//TOOD Refactor ActivityType handling in here!
@Deprecated //TODO Refactor: all this should happen somewhere else (ContentProviderUtils?) @Deprecated //TODO Refactor: all this should happen somewhere else (ContentProviderUtils?)
public class TrackUtils { public class TrackUtils {
private TrackUtils() { private TrackUtils() {
} }
public static void updateTrack(Context context, Track track, String name, String activityType, String description, ContentProviderUtils contentProviderUtils) { public static void updateTrack(Context context, Track track, String name, String activityTypeLocalized, String description, ContentProviderUtils contentProviderUtils) {
updateTrack(context, track, name, activityType, ActivityType.findByLocalizedString(context, activityType) updateTrack(context, track, name, activityTypeLocalized, ActivityType.findByLocalizedString(context, activityTypeLocalized), description, contentProviderUtils);
.getId(), description, contentProviderUtils);
} }
public static void updateTrack(Context context, Track track, String name, String activityType, String iconValue, String description, ContentProviderUtils contentProviderUtils) { public static void updateTrack(Context context, Track track, String name, String activityTypeLocalized, ActivityType activityType, String description, ContentProviderUtils contentProviderUtils) {
boolean update = false; boolean update = false;
if (name != null) { if (name != null) {
track.setName(name); track.setName(name);
update = true; update = true;
} }
if (activityType != null) { if (activityTypeLocalized != null) {
track.setActivityType(activityType); track.setActivityTypeLocalized(activityTypeLocalized);
update = true; update = true;
} }
if (iconValue != null) { if (activityType != null) {
track.setActivityTypeId(iconValue); track.setActivityType(activityType);
} else if (activityType != null) { } else if (activityTypeLocalized != null) {
track.setActivityTypeId(ActivityType.findByLocalizedString(context, activityType) track.setActivityType(ActivityType.findByLocalizedString(context, activityTypeLocalized)
.getId()); );
} }
if (description != null) { if (description != null) {
track.setDescription(description); track.setDescription(description);