Cleanup: static code analysis using AndroidStudio.

This commit is contained in:
Dennis Guse
2020-07-20 19:01:40 +02:00
parent 461f1c246b
commit b70c3be5af
42 changed files with 202 additions and 454 deletions
-14
View File
@@ -17,20 +17,6 @@ allprojects {
} }
} }
def getVersionCode = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', 'HEAD', '--count'
standardOutput = stdout
}
return Integer.parseInt(stdout.toString().trim())
}
catch (ignored) {
return -1
}
}
def getVersionName = { -> def getVersionName = { ->
try { try {
def stdout = new ByteArrayOutputStream() def stdout = new ByteArrayOutputStream()
@@ -206,7 +206,7 @@ public class CustomContentProviderUtilsTest {
public void testDeleteAllTracks() { public void testDeleteAllTracks() {
// Insert track, points and waypoint at first. // Insert track, points and waypoint at first.
long trackId = System.currentTimeMillis(); long trackId = System.currentTimeMillis();
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10); TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
Waypoint waypoint = new Waypoint(contentProviderUtils.getLastValidTrackPoint(trackId)); Waypoint waypoint = new Waypoint(contentProviderUtils.getLastValidTrackPoint(trackId));
contentProviderUtils.insertWaypoint(waypoint); contentProviderUtils.insertWaypoint(waypoint);
@@ -60,7 +60,7 @@ public class AggregatedStatisticsTest {
// then // then
Assert.assertEquals(1, aggregatedStatistics.getCount()); Assert.assertEquals(1, aggregatedStatistics.getCount());
Assert.assertTrue(aggregatedStatistics.get(biking) != null); Assert.assertNotNull(aggregatedStatistics.get(biking));
Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks()); Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks());
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
@@ -82,7 +82,7 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(track); aggregatedStatistics.aggregate(track);
// then // then
Assert.assertTrue(aggregatedStatistics.get(mountainBiking) != null); Assert.assertNotNull(aggregatedStatistics.get(mountainBiking));
} }
@Test @Test
@@ -99,7 +99,7 @@ public class AggregatedStatisticsTest {
aggregatedStatistics.aggregate(track); aggregatedStatistics.aggregate(track);
// then // then
Assert.assertTrue(aggregatedStatistics.get(trailRunning) != null); Assert.assertNotNull(aggregatedStatistics.get(trailRunning));
} }
@Test @Test
@@ -121,7 +121,7 @@ public class AggregatedStatisticsTest {
// then // then
Assert.assertEquals(1, aggregatedStatistics.getCount()); Assert.assertEquals(1, aggregatedStatistics.getCount());
Assert.assertTrue(aggregatedStatistics.get(biking) != null); Assert.assertNotNull(aggregatedStatistics.get(biking));
Assert.assertEquals(2, aggregatedStatistics.get(biking).getCountTracks()); Assert.assertEquals(2, aggregatedStatistics.get(biking).getCountTracks());
TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics();
@@ -153,9 +153,9 @@ public class AggregatedStatisticsTest {
// then // then
Assert.assertEquals(3, aggregatedStatistics.getCount()); Assert.assertEquals(3, aggregatedStatistics.getCount());
Assert.assertTrue(aggregatedStatistics.get(biking) != null); Assert.assertNotNull(aggregatedStatistics.get(biking));
Assert.assertTrue(aggregatedStatistics.get(running) != null); Assert.assertNotNull(aggregatedStatistics.get(running));
Assert.assertTrue(aggregatedStatistics.get(walking) != null); Assert.assertNotNull(aggregatedStatistics.get(walking));
Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks()); Assert.assertEquals(1, aggregatedStatistics.get(biking).getCountTracks());
Assert.assertEquals(1, aggregatedStatistics.get(running).getCountTracks()); Assert.assertEquals(1, aggregatedStatistics.get(running).getCountTracks());
Assert.assertEquals(1, aggregatedStatistics.get(walking).getCountTracks()); Assert.assertEquals(1, aggregatedStatistics.get(walking).getCountTracks());
@@ -215,10 +215,10 @@ public class AggregatedStatisticsTest {
Assert.assertEquals(4, aggregatedStatistics.getCount()); Assert.assertEquals(4, aggregatedStatistics.getCount());
// There is a map for every sport. // There is a map for every sport.
Assert.assertTrue(aggregatedStatistics.get(biking) != null); Assert.assertNotNull(aggregatedStatistics.get(biking));
Assert.assertTrue(aggregatedStatistics.get(running) != null); Assert.assertNotNull(aggregatedStatistics.get(running));
Assert.assertTrue(aggregatedStatistics.get(walking) != null); Assert.assertNotNull(aggregatedStatistics.get(walking));
Assert.assertTrue(aggregatedStatistics.get(driving) != null); Assert.assertNotNull(aggregatedStatistics.get(driving));
// Number of tracks by sport. // Number of tracks by sport.
Assert.assertEquals(5, aggregatedStatistics.get(biking).getCountTracks()); // Biking. Assert.assertEquals(5, aggregatedStatistics.get(biking).getCountTracks()); // Biking.
@@ -3,11 +3,9 @@ package de.dennisguse.opentracks;
import android.os.Bundle; import android.os.Bundle;
import android.widget.ListView; import android.widget.ListView;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import de.dennisguse.opentracks.adapters.AggregatedStatisticsAdapter; import de.dennisguse.opentracks.adapters.AggregatedStatisticsAdapter;
import de.dennisguse.opentracks.viewmodels.AggregatedStatistics;
import de.dennisguse.opentracks.viewmodels.AggregatedStatisticsModel; import de.dennisguse.opentracks.viewmodels.AggregatedStatisticsModel;
public class AggregatedStatisticsActivity extends AbstractActivity { public class AggregatedStatisticsActivity extends AbstractActivity {
@@ -120,7 +120,7 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
private class MarkerDetailPagerAdapter extends FragmentStatePagerAdapter { private class MarkerDetailPagerAdapter extends FragmentStatePagerAdapter {
MarkerDetailPagerAdapter(FragmentManager fragmentManager) { MarkerDetailPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager); super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
} }
@Override @Override
@@ -26,8 +26,6 @@ import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView; import android.widget.ListView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -82,7 +80,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(MarkerListActivity.this); recordingTrackPaused = PreferencesUtils.isRecordingTrackPaused(MarkerListActivity.this);
} }
if (key != null) { if (key != null) {
runOnUiThread(() -> MarkerListActivity.this.invalidateOptionsMenu()); runOnUiThread(MarkerListActivity.this::invalidateOptionsMenu);
} }
} }
}; };
@@ -129,13 +127,10 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
listView = findViewById(R.id.marker_list); listView = findViewById(R.id.marker_list);
listView.setEmptyView(findViewById(R.id.marker_list_empty)); listView.setEmptyView(findViewById(R.id.marker_list_empty));
listView.setOnItemClickListener(new OnItemClickListener() { listView.setOnItemClickListener((parent, view, position, id) -> {
@Override Intent intent = IntentUtils.newIntent(MarkerListActivity.this, MarkerDetailActivity.class)
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { .putExtra(MarkerDetailActivity.EXTRA_MARKER_ID, id);
Intent intent = IntentUtils.newIntent(MarkerListActivity.this, MarkerDetailActivity.class) startActivity(intent);
.putExtra(MarkerDetailActivity.EXTRA_MARKER_ID, id);
startActivity(intent);
}
}); });
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) { resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) {
@Override @Override
@@ -272,8 +267,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
DeleteMarkerDialogFragment.showDialog(getSupportFragmentManager(), markerIds); DeleteMarkerDialogFragment.showDialog(getSupportFragmentManager(), markerIds);
return true; return true;
case R.id.list_context_menu_select_all: case R.id.list_context_menu_select_all:
int size = listView.getCount(); for (int i = 0; i < listView.getCount(); i++) {
for (int i = 0; i < size; i++) {
listView.setItemChecked(i, true); listView.setItemChecked(i, true);
} }
return false; return false;
@@ -26,8 +26,6 @@ import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
@@ -203,20 +201,17 @@ public class SearchListActivity extends AbstractListActivity implements DeleteMa
ListView listView = findViewById(R.id.search_list); ListView listView = findViewById(R.id.search_list);
listView.setAdapter(arrayAdapter); listView.setAdapter(arrayAdapter);
listView.setEmptyView(findViewById(R.id.search_list_empty)); listView.setEmptyView(findViewById(R.id.search_list_empty));
listView.setOnItemClickListener(new OnItemClickListener() { listView.setOnItemClickListener((parent, view, position, id) -> {
@Override Map<String, Object> item = arrayAdapter.getItem(position);
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Long trackId = (Long) item.get(TRACK_ID_FIELD);
Map<String, Object> item = arrayAdapter.getItem(position); Long markerId = (Long) item.get(MARKER_ID_FIELD);
Long trackId = (Long) item.get(TRACK_ID_FIELD); Intent intent = IntentUtils.newIntent(SearchListActivity.this, TrackRecordedActivity.class);
Long markerId = (Long) item.get(MARKER_ID_FIELD); if (markerId != null) {
Intent intent = IntentUtils.newIntent(SearchListActivity.this, TrackRecordedActivity.class); intent = intent.putExtra(TrackRecordedActivity.EXTRA_MARKER_ID, markerId);
if (markerId != null) { } else {
intent = intent.putExtra(TrackRecordedActivity.EXTRA_MARKER_ID, markerId); intent = intent.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
} else {
intent = intent.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
}
startActivity(intent);
} }
startActivity(intent);
}); });
ActivityUtils.configureListViewContextualMenu(listView, contextualActionModeCallback); ActivityUtils.configureListViewContextualMenu(listView, contextualActionModeCallback);
handleIntent(getIntent()); handleIntent(getIntent());
@@ -18,7 +18,7 @@ import de.dennisguse.opentracks.util.IntentDashboardUtils;
*/ */
public abstract class ShowOnMapProxyActivity extends AppCompatActivity { public abstract class ShowOnMapProxyActivity extends AppCompatActivity {
private TrackFileFormat trackFileFormat; private final TrackFileFormat trackFileFormat;
protected ShowOnMapProxyActivity(TrackFileFormat trackFileFormat) { protected ShowOnMapProxyActivity(TrackFileFormat trackFileFormat) {
this.trackFileFormat = trackFileFormat; this.trackFileFormat = trackFileFormat;
@@ -21,7 +21,6 @@ import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button; import android.widget.Button;
@@ -89,20 +88,12 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
activityType.setAdapter(adapter); activityType.setAdapter(adapter);
activityType.setOnItemClickListener(new AdapterView.OnItemClickListener() { activityType.setOnItemClickListener((parent, view, position, id) -> setActivityTypeIcon(TrackIconUtils.getIconValue(
@Override TrackEditActivity.this, (String) activityType.getAdapter().getItem(position))));
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { activityType.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
setActivityTypeIcon(TrackIconUtils.getIconValue( setActivityTypeIcon(TrackIconUtils.getIconValue(
TrackEditActivity.this, (String) activityType.getAdapter().getItem(position))); TrackEditActivity.this, activityType.getText().toString()));
}
});
activityType.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
setActivityTypeIcon(TrackIconUtils.getIconValue(
TrackEditActivity.this, activityType.getText().toString()));
}
} }
}); });
@@ -116,37 +107,28 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
activityTypeIcon = findViewById(R.id.track_edit_activity_type_icon); activityTypeIcon = findViewById(R.id.track_edit_activity_type_icon);
activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(this, iconValue)); activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(this, iconValue));
activityTypeIcon.setOnTouchListener(new View.OnTouchListener() { activityTypeIcon.setOnTouchListener((v, event) -> {
@Override if (event.getAction() == MotionEvent.ACTION_UP) {
public boolean onTouch(View v, MotionEvent event) { ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), activityType.getText().toString());
if (event.getAction() == MotionEvent.ACTION_UP) {
ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), activityType.getText().toString());
}
return true;
} }
return true;
}); });
activityTypeIcon.setOnKeyListener(new View.OnKeyListener() { activityTypeIcon.setOnKeyListener((v, keyCode, event) -> {
@Override if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
public boolean onKey(View v, int keyCode, KeyEvent event) { ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), activityType.getText().toString());
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
ChooseActivityTypeDialogFragment.showDialog(getSupportFragmentManager(), activityType.getText().toString());
}
return true;
} }
return true;
}); });
description = findViewById(R.id.track_edit_description); description = findViewById(R.id.track_edit_description);
description.setText(track.getDescription()); description.setText(track.getDescription());
Button saveButton = findViewById(R.id.track_edit_save); Button saveButton = findViewById(R.id.track_edit_save);
saveButton.setOnClickListener(new View.OnClickListener() { saveButton.setOnClickListener(v -> {
@Override TrackUtils.updateTrack(TrackEditActivity.this, track, nameEditText.getText().toString(),
public void onClick(View v) { activityType.getText().toString(), description.getText().toString(),
TrackUtils.updateTrack(TrackEditActivity.this, track, nameEditText.getText().toString(), contentProviderUtils);
activityType.getText().toString(), description.getText().toString(), finish();
contentProviderUtils);
finish();
}
}); });
Button cancel = findViewById(R.id.track_edit_cancel); Button cancel = findViewById(R.id.track_edit_cancel);
@@ -155,12 +137,7 @@ public class TrackEditActivity extends AbstractActivity implements ChooseActivit
cancel.setVisibility(View.GONE); cancel.setVisibility(View.GONE);
} else { } else {
setTitle(R.string.menu_edit); setTitle(R.string.menu_edit);
cancel.setOnClickListener(new View.OnClickListener() { cancel.setOnClickListener(v -> finish());
@Override
public void onClick(View v) {
finish();
}
});
cancel.setVisibility(View.VISIBLE); cancel.setVisibility(View.VISIBLE);
} }
} }
@@ -33,8 +33,6 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Toast; import android.widget.Toast;
@@ -229,31 +227,23 @@ public class TrackListActivity extends AbstractListActivity implements ConfirmDe
// Show trackController when search dialog is dismissed // Show trackController when search dialog is dismissed
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE); SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
if (searchManager != null) { if (searchManager != null) {
searchManager.setOnDismissListener(new SearchManager.OnDismissListener() { searchManager.setOnDismissListener(() -> trackController.show());
@Override
public void onDismiss() {
trackController.show();
}
});
} }
listView = findViewById(R.id.track_list); listView = findViewById(R.id.track_list);
listView.setEmptyView(findViewById(R.id.track_list_empty_view)); listView.setEmptyView(findViewById(R.id.track_list_empty_view));
listView.setOnItemClickListener(new OnItemClickListener() { listView.setOnItemClickListener((parent, view, position, trackId) -> {
@Override Intent newIntent;
public void onItemClick(AdapterView<?> parent, View view, int position, long trackId) { if (trackId == recordingTrackId) {
Intent newIntent; // Is recording -> open record activity.
if (trackId == recordingTrackId) { newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class)
// Is recording -> open record activity. .putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class) } else {
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId); // Not recording -> open detail activity.
} else { newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
// Not recording -> open detail activity. .putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
.putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
}
startActivity(newIntent);
} }
startActivity(newIntent);
}); });
resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) { resourceCursorAdapter = new ResourceCursorAdapter(this, R.layout.list_item, null, 0) {
@@ -17,8 +17,8 @@ import de.dennisguse.opentracks.viewmodels.AggregatedStatistics;
public class AggregatedStatisticsAdapter extends BaseAdapter { public class AggregatedStatisticsAdapter extends BaseAdapter {
private AggregatedStatistics aggregatedStatistics; private final AggregatedStatistics aggregatedStatistics;
private Context context; private final Context context;
public AggregatedStatisticsAdapter(Context context, AggregatedStatistics aggregatedStatistics) { public AggregatedStatisticsAdapter(Context context, AggregatedStatistics aggregatedStatistics) {
this.context = context; this.context = context;
@@ -85,12 +85,9 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
protected boolean metricsUnits; protected boolean metricsUnits;
protected boolean reportSpeed; protected boolean reportSpeed;
public ViewHolder() {
metricsUnits = PreferencesUtils.isMetricUnits(context);
}
public void setValues(View view, int iconDrawable, String name, AggregatedStatistics.AggregatedStatistic aggregatedStats) { public void setValues(View view, int iconDrawable, String name, AggregatedStatistics.AggregatedStatistic aggregatedStats) {
reportSpeed = PreferencesUtils.isReportSpeed(context, name); reportSpeed = PreferencesUtils.isReportSpeed(context, name);
metricsUnits = PreferencesUtils.isMetricUnits(context);
sportIcon = view.findViewById(R.id.aggregated_stats_sport_icon); sportIcon = view.findViewById(R.id.aggregated_stats_sport_icon);
typeLabel = view.findViewById(R.id.aggregated_stats_type_label); typeLabel = view.findViewById(R.id.aggregated_stats_type_label);
@@ -108,28 +108,25 @@ public class SearchEngine {
/** /**
* Comparator for scored results. * Comparator for scored results.
*/ */
private static final Comparator<ScoredResult> SCORED_RESULT_COMPARATOR = new Comparator<ScoredResult>() { private static final Comparator<ScoredResult> SCORED_RESULT_COMPARATOR = (r1, r2) -> {
@Override // Score ordering.
public int compare(ScoredResult r1, ScoredResult r2) { int scoreDiff = Double.compare(r2.score, r1.score);
// Score ordering. if (scoreDiff != 0) {
int scoreDiff = Double.compare(r2.score, r1.score); return scoreDiff;
if (scoreDiff != 0) {
return scoreDiff;
}
// Make tracks come before waypoints.
if (r1.waypoint != null && r2.track != null) {
return 1;
} else if (r1.track != null && r2.waypoint != null) {
return -1;
}
// Finally, use arbitrary ordering, by ID.
long id1 = r1.track != null ? r1.track.getId() : r1.waypoint.getId();
long id2 = r2.track != null ? r2.track.getId() : r2.waypoint.getId();
long idDiff = id2 - id1;
return Long.signum(idDiff);
} }
// Make tracks come before waypoints.
if (r1.waypoint != null && r2.track != null) {
return 1;
} else if (r1.track != null && r2.waypoint != null) {
return -1;
}
// Finally, use arbitrary ordering, by ID.
long id1 = r1.track != null ? r1.track.getId() : r1.waypoint.getId();
long id2 = r2.track != null ? r2.track.getId() : r2.waypoint.getId();
long idDiff = id2 - id1;
return Long.signum(idDiff);
}; };
private final ContentProviderUtils providerUtils; private final ContentProviderUtils providerUtils;
@@ -6,7 +6,6 @@ import android.content.pm.ProviderInfo;
import android.database.Cursor; import android.database.Cursor;
import android.database.MatrixCursor; import android.database.MatrixCursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
import android.util.Log; import android.util.Log;
@@ -211,14 +210,11 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
final TrackExporter trackExporter = getTrackFileFormat(uri).newTrackExporter(getContext(), tracks); final TrackExporter trackExporter = getTrackFileFormat(uri).newTrackExporter(getContext(), tracks);
PipeDataWriter pipeDataWriter = new PipeDataWriter<String>() { PipeDataWriter<String> pipeDataWriter = (PipeDataWriter<String>) (output, uri1, mimeType, opts, args) -> {
@Override try (FileOutputStream fileOutputStream = new FileOutputStream(output.getFileDescriptor())) {
public void writeDataToPipe(@NonNull ParcelFileDescriptor output, @NonNull Uri uri, @NonNull String mimeType, @Nullable Bundle opts, @Nullable String args) { trackExporter.writeTrack(getContext(), fileOutputStream);
try (FileOutputStream fileOutputStream = new FileOutputStream(output.getFileDescriptor())) { } catch (IOException e) {
trackExporter.writeTrack(getContext(), fileOutputStream); Log.w(TAG, "there occurred an error while sharing a file: " + e);
} catch (IOException e) {
Log.w(TAG, "there occurred an error while sharing a file: " + e);
}
} }
}; };
@@ -100,13 +100,4 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public int getCount() {
if (cursor == null) {
return -1;
}
return cursor.getCount();
}
} }
@@ -6,10 +6,10 @@ import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
public class SensorData { public class SensorData {
private String sensorAddress; private final String sensorAddress;
private String sensorName; private final String sensorName;
private long timestamp_ms; private final long timestamp_ms;
SensorData(String sensorAddress, String sensorName) { SensorData(String sensorAddress, String sensorName) {
this(sensorAddress, sensorName, System.currentTimeMillis()); this(sensorAddress, sensorName, System.currentTimeMillis());
@@ -25,8 +25,8 @@ public final class SensorDataCycling {
public static class Cadence extends SensorData { public static class Cadence extends SensorData {
private long crankRevolutionsCount; // UINT32 private final long crankRevolutionsCount; // UINT32
private int crankRevolutionsTime; // UINT16; 1/1024s private final int crankRevolutionsTime; // UINT16; 1/1024s
private float cadence_rpm = INVALID_VALUE_FLOAT; private float cadence_rpm = INVALID_VALUE_FLOAT;
public Cadence(String sensorAddress, String sensorName, long crankRevolutionsCount, int crankRevolutionsTime) { public Cadence(String sensorAddress, String sensorName, long crankRevolutionsCount, int crankRevolutionsTime) {
@@ -93,8 +93,8 @@ public final class SensorDataCycling {
public static class Speed extends SensorData { public static class Speed extends SensorData {
private int wheelRevolutionsCount; // UINT16 private final int wheelRevolutionsCount; // UINT16
private int wheelRevolutionsTime; // UINT16; 1/1024s private final int wheelRevolutionsTime; // UINT16; 1/1024s
private float speed_mps = INVALID_VALUE_FLOAT; private float speed_mps = INVALID_VALUE_FLOAT;
public Speed(String sensorAddress, String sensorName, int wheelRevolutionsCount, int wheelRevolutionsTime) { public Speed(String sensorAddress, String sensorName, int wheelRevolutionsCount, int wheelRevolutionsTime) {
@@ -154,8 +154,8 @@ public final class SensorDataCycling {
public static class CadenceAndSpeed extends SensorData { public static class CadenceAndSpeed extends SensorData {
private Cadence cadence; private final Cadence cadence;
private Speed speed; private final Speed speed;
public CadenceAndSpeed(String sensorAddress, String sensorName, @NonNull Cadence cadence, @NonNull Speed speed) { public CadenceAndSpeed(String sensorAddress, String sensorName, @NonNull Cadence cadence, @NonNull Speed speed) {
super(sensorAddress, sensorName); super(sensorAddress, sensorName);
@@ -4,7 +4,7 @@ import androidx.annotation.NonNull;
public class SensorDataHeartRate extends SensorData { public class SensorDataHeartRate extends SensorData {
private float heartRate_bpm; private final float heartRate_bpm;
public SensorDataHeartRate(String name, String address, float heartRate_bpm) { public SensorDataHeartRate(String name, String address, float heartRate_bpm) {
super(name, address); super(name, address);
@@ -18,7 +18,6 @@ package de.dennisguse.opentracks.fragments;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -77,18 +76,13 @@ public class DeleteMarkerDialogFragment extends DialogFragment {
messageId = markerIds.length > 1 ? R.string.marker_delete_multiple_confirm_message : R.string.marker_delete_one_confirm_message; messageId = markerIds.length > 1 ? R.string.marker_delete_multiple_confirm_message : R.string.marker_delete_one_confirm_message;
} }
return DialogUtils.createConfirmationDialog( return DialogUtils.createConfirmationDialog(
fragmentActivity, titleId, getString(messageId), new DialogInterface.OnClickListener() { fragmentActivity, titleId, getString(messageId), (dialog, which) -> new Thread(() -> {
@Override ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
public void onClick(DialogInterface dialog, int which) { for (long markerId : markerIds) {
new Thread(() -> { contentProviderUtils.deleteWaypoint(getContext(), markerId);
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
for (long markerId : markerIds) {
contentProviderUtils.deleteWaypoint(getContext(), markerId);
}
caller.onDeleteMarkerDone();
}).start();
} }
}); caller.onDeleteMarkerDone();
}).start());
} }
/** /**
@@ -166,9 +166,9 @@ public class ExportProgressDialogFragment extends DialogFragment {
private class ExportThread extends Thread { private class ExportThread extends Thread {
private TrackFileFormat trackFileFormat; private final TrackFileFormat trackFileFormat;
private DocumentFile directory; private final DocumentFile directory;
ExportThread(TrackFileFormat trackFileFormat, DocumentFile directory) { ExportThread(TrackFileFormat trackFileFormat, DocumentFile directory) {
this.directory = directory; this.directory = directory;
@@ -166,7 +166,7 @@ public class ImportProgressDialogFragment extends DialogFragment {
private class ImportThread extends Thread { private class ImportThread extends Thread {
private DocumentFile file; private final DocumentFile file;
ImportThread(DocumentFile file) { ImportThread(DocumentFile file) {
this.file = file; this.file = file;
@@ -109,7 +109,7 @@ public class MarkerDetailFragment extends Fragment {
long markerId = getArguments().getLong(KEY_MARKER_ID); long markerId = getArguments().getLong(KEY_MARKER_ID);
if (markerId == -1L) { if (markerId == -1L) {
Log.d(TAG, "invalid marker id"); Log.d(TAG, "invalid marker id");
getFragmentManager().popBackStack(); getParentFragmentManager().popBackStack();
return; return;
} }
contentProviderUtils = new ContentProviderUtils(getActivity()); contentProviderUtils = new ContentProviderUtils(getActivity());
@@ -125,16 +125,13 @@ public class MarkerDetailFragment extends Fragment {
textGradient = view.findViewById(R.id.marker_detail_waypoint_text_gradient); textGradient = view.findViewById(R.id.marker_detail_waypoint_text_gradient);
waypointInfo = view.findViewById(R.id.marker_detail_waypoint_info); waypointInfo = view.findViewById(R.id.marker_detail_waypoint_info);
photoView.setOnClickListener(new View.OnClickListener() { photoView.setOnClickListener(v -> {
@Override handler.removeCallbacks(hideText);
public void onClick(View v) { int visibility = waypointInfo.getVisibility() == View.GONE ? View.VISIBLE : View.GONE;
handler.removeCallbacks(hideText); textGradient.setVisibility(visibility);
int visibility = waypointInfo.getVisibility() == View.GONE ? View.VISIBLE : View.GONE; waypointInfo.setVisibility(visibility);
textGradient.setVisibility(visibility); if (visibility == View.VISIBLE) {
waypointInfo.setVisibility(visibility); handler.postDelayed(hideText, HIDE_TEXT_DELAY);
if (visibility == View.VISIBLE) {
handler.postDelayed(hideText, HIDE_TEXT_DELAY);
}
} }
}); });
return view; return view;
@@ -222,7 +219,7 @@ public class MarkerDetailFragment extends Fragment {
waypoint = contentProviderUtils.getWaypoint(getArguments().getLong(KEY_MARKER_ID)); waypoint = contentProviderUtils.getWaypoint(getArguments().getLong(KEY_MARKER_ID));
if (waypoint == null) { if (waypoint == null) {
Log.d(TAG, "waypoint is null"); Log.d(TAG, "waypoint is null");
getFragmentManager().popBackStack(); getParentFragmentManager().popBackStack();
} }
} }
} }
@@ -54,17 +54,14 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
private TrackStatistics trackStatistics = null; private TrackStatistics trackStatistics = null;
private String category = ""; private String category = "";
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
@Override if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) {
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { if (isResumed()) {
if (PreferencesUtils.isKey(getContext(), R.string.stats_units_key, key) || PreferencesUtils.isKey(getContext(), R.string.stats_rate_key, key)) { getActivity().runOnUiThread(() -> {
if (isResumed()) { if (isResumed()) {
getActivity().runOnUiThread(() -> { updateUI();
if (isResumed()) { }
updateUI(); });
}
});
}
} }
} }
}; };
@@ -124,23 +121,17 @@ public class StatisticsRecordedFragment extends Fragment implements TrackDataLis
Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon); Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon);
activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), "")); activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), ""));
activityTypeIcon.setOnTouchListener(new View.OnTouchListener() { activityTypeIcon.setOnTouchListener((v, event) -> {
@Override if (event.getAction() == MotionEvent.ACTION_UP) {
public boolean onTouch(View v, MotionEvent event) { ((TrackRecordedActivity) getActivity()).chooseActivityType(category);
if (event.getAction() == MotionEvent.ACTION_UP) {
((TrackRecordedActivity) getActivity()).chooseActivityType(category);
}
return true;
} }
return true;
}); });
activityTypeIcon.setOnKeyListener(new View.OnKeyListener() { activityTypeIcon.setOnKeyListener((v, keyCode, event) -> {
@Override if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
public boolean onKey(View v, int keyCode, KeyEvent event) { ((TrackRecordedActivity) getActivity()).chooseActivityType(category);
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
((TrackRecordedActivity) getActivity()).chooseActivityType(category);
}
return true;
} }
return true;
}); });
} }
@@ -203,23 +203,17 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon); Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon);
activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), "")); activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), ""));
activityTypeIcon.setOnTouchListener(new View.OnTouchListener() { activityTypeIcon.setOnTouchListener((v, event) -> {
@Override if (event.getAction() == MotionEvent.ACTION_UP) {
public boolean onTouch(View v, MotionEvent event) { ((TrackRecordingActivity) getActivity()).chooseActivityType(category);
if (event.getAction() == MotionEvent.ACTION_UP) {
((TrackRecordingActivity) getActivity()).chooseActivityType(category);
}
return true;
} }
return true;
}); });
activityTypeIcon.setOnKeyListener(new View.OnKeyListener() { activityTypeIcon.setOnKeyListener((v, keyCode, event) -> {
@Override if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
public boolean onKey(View v, int keyCode, KeyEvent event) { ((TrackRecordingActivity) getActivity()).chooseActivityType(category);
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
((TrackRecordingActivity) getActivity()).chooseActivityType(category);
}
return true;
} }
return true;
}); });
} }
@@ -63,9 +63,7 @@ public class ExportActivity extends FragmentActivity implements ExportProgressDi
@Override @Override
public void onExportFinished(final String directoryDisplayName, final int successCount, final int fileCount) { public void onExportFinished(final String directoryDisplayName, final int successCount, final int fileCount) {
runOnUiThread(() -> { runOnUiThread(() -> ExportFinishedDialogFragment.showDialog(getSupportFragmentManager(), directoryDisplayName, successCount, fileCount));
ExportFinishedDialogFragment.showDialog(getSupportFragmentManager(), directoryDisplayName, successCount, fileCount);
});
} }
@Override @Override
@@ -449,7 +449,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
float speedValue; float speedValue;
if (speed != null) { if (speed != null) {
try { try {
speedValue = Float.valueOf(speed); speedValue = Float.parseFloat(speed);
trackPoint.setSpeed(speedValue); trackPoint.setSpeed(speedValue);
} catch (Exception e) { } catch (Exception e) {
throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse speed: %s", speed)), e); throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse speed: %s", speed)), e);
@@ -64,9 +64,7 @@ public class ImportActivity extends FragmentActivity implements ImportProgressDi
@Override @Override
public void onImportFinished(final String directoryDisplayName, final int successCount, final int fileCount) { public void onImportFinished(final String directoryDisplayName, final int successCount, final int fileCount) {
runOnUiThread(() -> { runOnUiThread(() -> ImportFinishedDialogFragment.showDialog(getSupportFragmentManager(), directoryDisplayName, successCount, fileCount));
ImportFinishedDialogFragment.showDialog(getSupportFragmentManager(), directoryDisplayName, successCount, fileCount);
});
} }
@Override @Override
@@ -53,7 +53,7 @@ public class KmzTrackImporter implements TrackImporter {
private final Context context; private final Context context;
private final long importTrackId; private final long importTrackId;
private Uri uriKmzFile; private final Uri uriKmzFile;
/** /**
* @param context the context * @param context the context
@@ -8,8 +8,8 @@ import de.dennisguse.opentracks.content.data.TrackPoint;
public class HandlerServer { public class HandlerServer {
private String TAG = HandlerServer.class.getSimpleName(); private String TAG = HandlerServer.class.getSimpleName();
private LocationHandler locationHandler; private final LocationHandler locationHandler;
private HandlerServerInterface service; private final HandlerServerInterface service;
public HandlerServer(HandlerServerInterface service) { public HandlerServer(HandlerServerInterface service) {
this.locationHandler = new LocationHandler(this); this.locationHandler = new LocationHandler(this);
@@ -19,10 +19,10 @@ import de.dennisguse.opentracks.util.UnitConversions;
class LocationHandler implements HandlerServer.Handler, LocationListener { class LocationHandler implements HandlerServer.Handler, LocationListener {
private String TAG = LocationHandler.class.getSimpleName(); private final String TAG = LocationHandler.class.getSimpleName();
private LocationManager locationManager; private LocationManager locationManager;
private HandlerServer handlerServer; private final HandlerServer handlerServer;
private LocationListenerPolicy locationListenerPolicy; private LocationListenerPolicy locationListenerPolicy;
private long currentRecordingInterval; private long currentRecordingInterval;
private int recordingGpsAccuracy; private int recordingGpsAccuracy;
@@ -19,7 +19,6 @@ package de.dennisguse.opentracks.services.tasks;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.UtteranceProgressListener; import android.speech.tts.UtteranceProgressListener;
import android.util.Log; import android.util.Log;
@@ -50,7 +49,7 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
private final AudioManager audioManager; private final AudioManager audioManager;
private ContentProviderUtils contentProviderUtils; private final ContentProviderUtils contentProviderUtils;
private final AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() { private final AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override @Override
@@ -116,12 +115,9 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
Log.d(TAG, "Start"); Log.d(TAG, "Start");
if (tts == null) { if (tts == null) {
tts = new TextToSpeech(context, new OnInitListener() { tts = new TextToSpeech(context, status -> {
@Override Log.i(TAG, "TextToSpeech initialized with status " + status);
public void onInit(int status) { ttsInitStatus = status;
Log.i(TAG, "TextToSpeech initialized with status " + status);
ttsInitStatus = status;
}
}); });
} }
} }
@@ -22,7 +22,6 @@ import android.util.AttributeSet;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Spinner; import android.widget.Spinner;
@@ -51,12 +50,7 @@ public class ActivityTypePreference extends DialogPreference {
setDialogIcon(null); setDialogIcon(null);
setPersistent(true); setPersistent(true);
SummaryProvider<DialogPreference> summaryProvider = new SummaryProvider<DialogPreference>() { SummaryProvider<DialogPreference> summaryProvider = preference -> PreferencesUtils.getDefaultActivity(ActivityTypePreference.this.getContext());
@Override
public CharSequence provideSummary(DialogPreference preference) {
return PreferencesUtils.getDefaultActivity(ActivityTypePreference.this.getContext());
}
};
setSummaryProvider(summaryProvider); setSummaryProvider(summaryProvider);
} }
@@ -90,43 +84,31 @@ public class ActivityTypePreference extends DialogPreference {
textView.setText(category); textView.setText(category);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, R.array.activity_types, android.R.layout.simple_dropdown_item_1line); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
textView.setAdapter(adapter); textView.setAdapter(adapter);
textView.setOnItemClickListener(new AdapterView.OnItemClickListener() { textView.setOnItemClickListener((parent, v, position, id) -> {
@Override String iconValue = TrackIconUtils.getIconValue(context, (String) textView.getAdapter().getItem(position));
public void onItemClick(AdapterView<?> parent, View v, int position, long id) { TrackIconUtils.setIconSpinner(spinner, iconValue);
String iconValue = TrackIconUtils.getIconValue(context, (String) textView.getAdapter().getItem(position));
TrackIconUtils.setIconSpinner(spinner, iconValue);
}
}); });
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() { textView.setOnFocusChangeListener((v, hasFocus) -> {
@Override if (!hasFocus) {
public void onFocusChange(View v, boolean hasFocus) { String iconValue = TrackIconUtils.getIconValue(context, textView.getText().toString());
if (!hasFocus) { TrackIconUtils.setIconSpinner(spinner, iconValue);
String iconValue = TrackIconUtils.getIconValue(context, textView.getText().toString());
TrackIconUtils.setIconSpinner(spinner, iconValue);
}
} }
}); });
String iconValue = TrackIconUtils.getIconValue(context, category); String iconValue = TrackIconUtils.getIconValue(context, category);
spinner = view.findViewById(R.id.activity_type_preference_spinner); spinner = view.findViewById(R.id.activity_type_preference_spinner);
spinner.setAdapter(TrackIconUtils.getIconSpinnerAdapter(context, iconValue)); spinner.setAdapter(TrackIconUtils.getIconSpinnerAdapter(context, iconValue));
spinner.setOnTouchListener(new View.OnTouchListener() { spinner.setOnTouchListener((v, event) -> {
@Override if (event.getAction() == MotionEvent.ACTION_UP) {
public boolean onTouch(View v, MotionEvent event) { showIconSelectDialog();
if (event.getAction() == MotionEvent.ACTION_UP) {
showIconSelectDialog();
}
return true;
} }
return true;
}); });
spinner.setOnKeyListener(new View.OnKeyListener() { spinner.setOnKeyListener((v, keyCode, event) -> {
@Override if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
public boolean onKey(View v, int keyCode, KeyEvent event) { showIconSelectDialog();
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
showIconSelectDialog();
}
return true;
} }
return true;
}); });
} }
@@ -56,15 +56,12 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
public static class PrefsFragment extends PreferenceFragmentCompat { public static class PrefsFragment extends PreferenceFragmentCompat {
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
@Override if (PreferencesUtils.isKey(getActivity(), R.string.recording_track_id_key, key)) {
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { getActivity().runOnUiThread(this::updateReset);
if (PreferencesUtils.isKey(getActivity(), R.string.recording_track_id_key, key)) { }
getActivity().runOnUiThread(() -> updateReset()); if (PreferencesUtils.isKey(getActivity(), R.string.stats_units_key, key)) {
} getActivity().runOnUiThread(this::updateUnits);
if (PreferencesUtils.isKey(getActivity(), R.string.stats_units_key, key)) {
getActivity().runOnUiThread(() -> updateUnits());
}
} }
}; };
@@ -117,7 +114,7 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
if (dialogFragment != null) { if (dialogFragment != null) {
dialogFragment.setTargetFragment(this, 0); dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(getFragmentManager(), getClass().getSimpleName()); dialogFragment.show(getParentFragmentManager(), getClass().getSimpleName());
return; return;
} }
@@ -183,14 +183,11 @@ public abstract class BluetoothLeSensorPreference extends DialogPreference {
super.onPrepareDialogBuilder(builder); super.onPrepareDialogBuilder(builder);
builder.setSingleChoiceItems(listAdapter, selectedEntryIndex, builder.setSingleChoiceItems(listAdapter, selectedEntryIndex,
new DialogInterface.OnClickListener() { (dialog, which) -> {
@Override selectedEntryIndex = which;
public void onClick(DialogInterface dialog, int which) {
selectedEntryIndex = which;
BluetoothLeSensorPreferenceDialog.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); BluetoothLeSensorPreferenceDialog.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss(); dialog.dismiss();
}
}); });
builder.setIcon(android.R.drawable.stat_sys_data_bluetooth); builder.setIcon(android.R.drawable.stat_sys_data_bluetooth);
builder.setPositiveButton(null, null); builder.setPositiveButton(null, null);
@@ -9,7 +9,6 @@ import android.util.SparseBooleanArray;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView; import android.widget.AbsListView;
import android.widget.ListView; import android.widget.ListView;
@@ -94,17 +93,13 @@ public class ActivityUtils {
} }
searchView.setQueryRefinementEnabled(true); searchView.setQueryRefinementEnabled(true);
searchView.setSubmitButtonEnabled(true); searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() { searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> {
// Hide and show trackController when searchable widget has focus/no focus
@Override if (trackController != null) {
public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) {
// Hide and show trackController when searchable widget has focus/no focus trackController.hide();
if (trackController != null) { } else {
if (hasFocus) { trackController.show();
trackController.hide();
} else {
trackController.show();
}
} }
} }
}); });
@@ -48,8 +48,6 @@ public class FileUtils {
*/ */
static final String FILEPROVIDER = BuildConfig.APPLICATION_ID + ".fileprovider"; static final String FILEPROVIDER = BuildConfig.APPLICATION_ID + ".fileprovider";
public static final String EXPORT_DIR = "OpenTracks";
private static final String JPEG_EXTENSION = "jpeg"; private static final String JPEG_EXTENSION = "jpeg";
/** /**
@@ -27,9 +27,9 @@ public class IntentDashboardUtils {
private static final String EXTRAS_SHOULD_KEEP_SCREEN_ON = "EXTRAS_SHOULD_KEEP_SCREEN_ON"; private static final String EXTRAS_SHOULD_KEEP_SCREEN_ON = "EXTRAS_SHOULD_KEEP_SCREEN_ON";
private static final String EXTRAS_SHOW_WHEN_LOCKED = "EXTRAS_SHOULD_KEEP_SCREEN_ON"; private static final String EXTRAS_SHOW_WHEN_LOCKED = "EXTRAS_SHOULD_KEEP_SCREEN_ON";
private static int TRACK_URI_INDEX = 0; private static final int TRACK_URI_INDEX = 0;
private static int TRACKPOINTS_URI_INDEX = 1; private static final int TRACKPOINTS_URI_INDEX = 1;
private static int WAYPOINTS_URI_INDEX = 2; private static final int WAYPOINTS_URI_INDEX = 2;
private IntentDashboardUtils() { private IntentDashboardUtils() {
} }
@@ -16,13 +16,6 @@
package de.dennisguse.opentracks.util; package de.dennisguse.opentracks.util;
import android.location.Location; import android.location.Location;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import de.dennisguse.opentracks.content.data.TrackPoint;
/** /**
* Utility class for decimating tracks at a given level of precision. * Utility class for decimating tracks at a given level of precision.
@@ -39,112 +32,6 @@ public class LocationUtils {
private LocationUtils() { private LocationUtils() {
} }
/**
* Computes the distance on the two sphere between the point c0 and the line segment c1 to c2.
*
* @param c0 the first coordinate
* @param c1 the beginning of the line segment
* @param c2 the end of the lone segment
* @return the distance in m (assuming spherical earth)
*/
private static double distance(final Location c0, final Location c1, final Location c2) {
if (c1.equals(c2)) {
return c2.distanceTo(c0);
}
final double s0lat = c0.getLatitude() * UnitConversions.DEG_TO_RAD;
final double s0lng = c0.getLongitude() * UnitConversions.DEG_TO_RAD;
final double s1lat = c1.getLatitude() * UnitConversions.DEG_TO_RAD;
final double s1lng = c1.getLongitude() * UnitConversions.DEG_TO_RAD;
final double s2lat = c2.getLatitude() * UnitConversions.DEG_TO_RAD;
final double s2lng = c2.getLongitude() * UnitConversions.DEG_TO_RAD;
double s2s1lat = s2lat - s1lat;
double s2s1lng = s2lng - s1lng;
final double u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng)
/ (s2s1lat * s2s1lat + s2s1lng * s2s1lng);
if (u <= 0) {
return c0.distanceTo(c1);
}
if (u >= 1) {
return c0.distanceTo(c2);
}
Location sa = new Location("");
sa.setLatitude(c0.getLatitude() - c1.getLatitude());
sa.setLongitude(c0.getLongitude() - c1.getLongitude());
Location sb = new Location("");
sb.setLatitude(u * (c2.getLatitude() - c1.getLatitude()));
sb.setLongitude(u * (c2.getLongitude() - c1.getLongitude()));
return sa.distanceTo(sb);
}
/**
* Decimates the given trackPoints for a given zoom level.
* This uses a Douglas-Peucker decimation algorithm.
*
* @param tolerance in meters
* @param trackPoints input
*/
//TODO What was it used for? Sharing data with other apps?
private static List<TrackPoint> decimate(double tolerance, List<TrackPoint> trackPoints) {
List<TrackPoint> decimated = new ArrayList<>();
final int n = trackPoints.size();
if (n < 1) {
return null;
}
int idx;
int maxIdx = 0;
Stack<int[]> stack = new Stack<>();
double[] dists = new double[n];
dists[0] = 1;
dists[n - 1] = 1;
double maxDist;
double dist;
int[] current;
if (n > 2) {
int[] stackVal = new int[]{0, (n - 1)};
stack.push(stackVal);
while (stack.size() > 0) {
current = stack.pop();
maxDist = 0;
for (idx = current[0] + 1; idx < current[1]; ++idx) {
dist = LocationUtils.distance(trackPoints.get(idx).getLocation(), trackPoints.get(current[0]).getLocation(), trackPoints.get(current[1]).getLocation());
if (dist > maxDist) {
maxDist = dist;
maxIdx = idx;
}
}
if (maxDist > tolerance) {
dists[maxIdx] = maxDist;
int[] stackValCurMax = {current[0], maxIdx};
stack.push(stackValCurMax);
int[] stackValMaxCur = {maxIdx, current[1]};
stack.push(stackValMaxCur);
}
}
}
int i = 0;
idx = 0;
decimated.clear();
for (TrackPoint l : trackPoints) {
if (dists[idx] != 0) {
decimated.add(l);
i++;
}
idx++;
}
Log.d(TAG, "Decimating " + n + " points to " + i + " w/ tolerance = " + tolerance);
return decimated;
}
/** /**
* Checks if a given location is a valid (i.e. physically possible) location on Earth. * Checks if a given location is a valid (i.e. physically possible) location on Earth.
* Note: The special separator locations (which have latitude = 100) will not qualify as valid. * Note: The special separator locations (which have latitude = 100) will not qualify as valid.
@@ -53,6 +53,7 @@ public class PreferencesUtils {
//NOTE: This was also used to recover from a service restart, but this data should not be exposed to the whole application. //NOTE: This was also used to recover from a service restart, but this data should not be exposed to the whole application.
public static final long RECORDING_TRACK_ID_DEFAULT = -1L; public static final long RECORDING_TRACK_ID_DEFAULT = -1L;
@Deprecated //Use the TrackRecordingService
public static long getRecordingTrackId(Context context) { public static long getRecordingTrackId(Context context) {
SharedPreferences sharedPreferences = getSharedPreferences(context); SharedPreferences sharedPreferences = getSharedPreferences(context);
return sharedPreferences.getLong(getKey(context, R.string.recording_track_id_key), RECORDING_TRACK_ID_DEFAULT); return sharedPreferences.getLong(getKey(context, R.string.recording_track_id_key), RECORDING_TRACK_ID_DEFAULT);
@@ -208,14 +209,17 @@ public class PreferencesUtils {
return currentStatsRate.equals(context.getString(R.string.stats_rate_speed)); return currentStatsRate.equals(context.getString(R.string.stats_rate_speed));
} }
@Deprecated //Use TrackRecordingService
public static boolean isRecordingTrackPaused(Context context) { public static boolean isRecordingTrackPaused(Context context) {
return getBoolean(context, R.string.recording_track_paused_key, isRecordingTrackPausedDefault(context)); return getBoolean(context, R.string.recording_track_paused_key, isRecordingTrackPausedDefault(context));
} }
@Deprecated //Use TrackRecordingService
public static boolean isRecordingTrackPausedDefault(Context context) { public static boolean isRecordingTrackPausedDefault(Context context) {
return context.getResources().getBoolean(R.bool.recording_track_paused_default); return context.getResources().getBoolean(R.bool.recording_track_paused_default);
} }
@Deprecated //Use TrackRecordingService
public static void defaultRecordingTrackPaused(Context context) { public static void defaultRecordingTrackPaused(Context context) {
final boolean RECORDING_TRACK_PAUSED = context.getResources().getBoolean(R.bool.recording_track_paused_default); final boolean RECORDING_TRACK_PAUSED = context.getResources().getBoolean(R.bool.recording_track_paused_default);
setBoolean(context, R.string.recording_track_paused_key, RECORDING_TRACK_PAUSED); setBoolean(context, R.string.recording_track_paused_key, RECORDING_TRACK_PAUSED);
@@ -331,6 +335,7 @@ public class PreferencesUtils {
} }
} }
@Deprecated //Use TrackRecordingService
public static boolean isRecording(Context context) { public static boolean isRecording(Context context) {
long recordingTrackId = getRecordingTrackId(context); long recordingTrackId = getRecordingTrackId(context);
return isRecording(recordingTrackId); return isRecording(recordingTrackId);
@@ -2,8 +2,8 @@ package de.dennisguse.opentracks.util;
public class UintUtils { public class UintUtils {
public static int UINT16_MAX = 0xFFFF; public static final int UINT16_MAX = 0xFFFF;
public static long UINT32_MAX = 0xFFFFFFFFL; public static final long UINT32_MAX = 0xFFFFFFFFL;
private UintUtils() { private UintUtils() {
} }
@@ -1,18 +1,16 @@
package de.dennisguse.opentracks.viewmodels; package de.dennisguse.opentracks.viewmodels;
import android.content.Context;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import de.dennisguse.opentracks.content.data.Track; 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;
public class AggregatedStatistics { public class AggregatedStatistics {
private HashMap<String, AggregatedStatistic> aggregatedStatistics = new HashMap<>(); private final Map<String, AggregatedStatistic> aggregatedStatistics = new HashMap<>();
public void aggregate(List<Track> tracks) { public void aggregate(List<Track> tracks) {
for (Track track : tracks) { for (Track track : tracks) {
@@ -50,7 +48,7 @@ public class AggregatedStatistics {
} }
public static class AggregatedStatistic { public static class AggregatedStatistic {
private TrackStatistics trackStatistics; private final TrackStatistics trackStatistics;
private int countTracks; private int countTracks;
public AggregatedStatistic(TrackStatistics trackStatistics) { public AggregatedStatistic(TrackStatistics trackStatistics) {
+2 -2
View File
@@ -69,7 +69,7 @@ Si está parado o en el interior, no se registrarán los datos del sensor (pero
<string name="help_gps_troubleshooting_title">OpenTracks no está grabando las localizaciones?</string> <string name="help_gps_troubleshooting_title">OpenTracks no está grabando las localizaciones?</string>
<string name="help_gps_troubleshooting_content"> <string name="help_gps_troubleshooting_content">
Lo que puedes hacer... Lo que puedes hacer…
a) Comprobar si el GPS está activado. a) Comprobar si el GPS está activado.
b) mejorar la recepción del GPS (por ejemplo, ir al exterior),\n b) mejorar la recepción del GPS (por ejemplo, ir al exterior),\n
c) comprueba si con <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/">GPSTest</a> app, y\n c) comprueba si con <a href="https://f-droid.org/en/packages/com.android.gpstest.osmdroid/">GPSTest</a> app, y\n
@@ -79,7 +79,7 @@ Si todo no ayuda, por favor informe de un error.</string>
<string name="help_support_title">¿Cómo puedo apoyar OpenTracks?</string> <string name="help_support_title">¿Cómo puedo apoyar OpenTracks?</string>
<string name="help_support_content"> <string name="help_support_content">
Puedes... Puedes…
a) difundir la palabra sobre OpenTracks,... a) difundir la palabra sobre OpenTracks,...
b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">proponer características</a>,\n b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">proponer características</a>,\n
c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">report bugs</a>,\n c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">report bugs</a>,\n
+2 -2
View File
@@ -25,7 +25,7 @@ limitations under the License.
<string name="help_feature_title">OpenTracks heeft de volgende kenmerken:</string> <string name="help_feature_title">OpenTracks heeft de volgende kenmerken:</string>
<string name="help_feature_content"> <string name="help_feature_content">
* creëer GPS tracks * creëer GPS tracks
* gebruik een hartslagsensor (alleen Bluetooth LE)... * gebruik een hartslagsensor (alleen Bluetooth LE)…
* spraakaankondigingen (op tijd of afstand)... * spraakaankondigingen (op tijd of afstand)...
* creëer markers (incl. fotos) * creëer markers (incl. fotos)
* werkt volledig offline * werkt volledig offline
@@ -79,7 +79,7 @@ Als alles niet helpt, meldt u dan alstublieft een bug.</string>
<string name="help_support_title">Hoe kan ik OpenTracks ondersteunen?</string> <string name="help_support_title">Hoe kan ik OpenTracks ondersteunen?</string>
<string name="help_support_content"> <string name="help_support_content">
Je kunt... Je kunt…
a) het woord verspreiden over OpenTracks, en... a) het woord verspreiden over OpenTracks, en...
b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">voorstellen van functies</a>,\n b) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">voorstellen van functies</a>,\n
c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">melding van bugs</a>,\n c) <a href="https://github.com/OpenTracksApp/OpenTracks/issues">melding van bugs</a>,\n