mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-23 02:35:18 +02:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 823dc1c12b | |||
| 26490f5a66 | |||
| d299dbdf06 | |||
| b5555e302f | |||
| 3030b4dfd9 | |||
| a5431b1cf5 | |||
| 9314221647 | |||
| 9bb9d5c283 | |||
| 1095a1442f | |||
| d373fdaaeb | |||
| 5278ba4d35 | |||
| 9b71b7f88c | |||
| bc96c2c05b | |||
| e655762c72 | |||
| 71c385a1a9 | |||
| b947a727e7 | |||
| 470f23afa8 | |||
| 0a1f9dfe41 | |||
| 6fcd19bf2e | |||
| 32d9705a4c | |||
| 2ac66c08f2 | |||
| 3b776407fa | |||
| 399f90a8f0 | |||
| b2c2047ca2 | |||
| 838671e2ce |
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: actions/checkout@v2.3.4
|
||||
|
||||
- name: run tests
|
||||
uses: reactivecircus/android-emulator-runner@v2.17.0
|
||||
uses: reactivecircus/android-emulator-runner@v2.18.0
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
+3
-3
@@ -55,8 +55,8 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "de.dennisguse.opentracks"
|
||||
versionCode 4151
|
||||
versionName "v3.18.4"
|
||||
versionCode 4176
|
||||
versionName "v3.18.5"
|
||||
|
||||
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
|
||||
|
||||
@@ -90,7 +90,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0-alpha06'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
@@ -103,5 +102,6 @@ dependencies {
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.3.0'
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
androidTestImplementation 'org.mockito:mockito-android:3.10.0'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
v3.18.5: OpenTracks
|
||||
|
||||
Changes:
|
||||
- Voice announcement speed configurable
|
||||
- API <26: Launcher icon omits background
|
||||
|
||||
Bugfixes:
|
||||
- Recording UI: show correct values
|
||||
- Recording UI: show (again) altitude in EGM2008
|
||||
|
||||
Developer:
|
||||
- Android12 permissions (BLUETOOTH_CONNECT)
|
||||
@@ -4,6 +4,8 @@ Fonctionnalités :
|
||||
|
||||
* Suivi d'activité : enregistre vos activités sportives et de plein air
|
||||
* Photos et repères : ajout de photos et de repères pendant l'enregistrement de l'activité
|
||||
* Rythme cardiaque : support des capteurs Bluetooth LE
|
||||
* Export : export des traces au format KML ou GPX
|
||||
* Dénivelé positif et négatif: via capteur de pression barométrique
|
||||
* Synthèse vocale
|
||||
* Prise en charge des capteurs Bluetooth LE : rythme cardiaque, vitesse et distance (vélo), cadence de pédalage (vélo), et capteur de puissance (vélo)
|
||||
* Export : export des traces au format KMZ (photos incluses), KML ou GPX
|
||||
* Pas d'accès internet requis : Internet n'est pas nécessaire pour le fonctionnement de l'application
|
||||
|
||||
@@ -1 +1 @@
|
||||
OpenTracks - Suivi d'activités sportives respectueux de votre vie privée.
|
||||
OpenTracks - Suivi d'activités sportives respectueux de votre vie privée.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
@@ -9,16 +10,18 @@ import androidx.test.espresso.DataInteraction;
|
||||
import androidx.test.espresso.UiController;
|
||||
import androidx.test.espresso.ViewAction;
|
||||
import androidx.test.espresso.ViewInteraction;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.rule.GrantPermissionRule;
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.rule.GrantPermissionRule;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onData;
|
||||
@@ -44,12 +47,15 @@ import static org.hamcrest.Matchers.is;
|
||||
public class EspressoCategoryUnitTest {
|
||||
|
||||
@Rule
|
||||
public ActivityTestRule<TrackListActivity> mActivityTestRule = new ActivityTestRule<>(TrackListActivity.class);
|
||||
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
|
||||
|
||||
@Rule
|
||||
public GrantPermissionRule mGrantPermissionRule =
|
||||
GrantPermissionRule.grant(
|
||||
"android.permission.ACCESS_FINE_LOCATION");
|
||||
public TestRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
|
||||
private final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
@Rule
|
||||
public TestRule mLocaleRule = new PreferenceMetricUnitRule(context, true);
|
||||
|
||||
@Test
|
||||
public void changeBetweenCategoryUpdateProperlyUnitTest() {
|
||||
|
||||
@@ -18,10 +18,10 @@ import androidx.test.espresso.ViewInteraction;
|
||||
import androidx.test.espresso.action.MotionEvents;
|
||||
import androidx.test.espresso.assertion.ViewAssertions;
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.rule.GrantPermissionRule;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
@@ -55,7 +55,7 @@ public class EspressoDeleteTrackTest {
|
||||
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
|
||||
|
||||
@Rule
|
||||
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant("android.permission.ACCESS_FINE_LOCATION");
|
||||
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
|
||||
private MyIdlingResource idlingResource;
|
||||
|
||||
@@ -241,7 +241,7 @@ public class EspressoDeleteTrackTest {
|
||||
|
||||
private class MyIdlingResource implements IdlingResource {
|
||||
|
||||
private Context context;
|
||||
private final Context context;
|
||||
private ResourceCallback resourceCallback;
|
||||
|
||||
public MyIdlingResource(Context context) {
|
||||
|
||||
@@ -35,7 +35,7 @@ public class EspressoUITest {
|
||||
public ActivityScenarioRule<TrackListActivity> mActivityTestRule = new ActivityScenarioRule<>(TrackListActivity.class);
|
||||
|
||||
@Rule
|
||||
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant("android.permission.ACCESS_FINE_LOCATION");
|
||||
public GrantPermissionRule mGrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package de.dennisguse.opentracks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
|
||||
public class PreferenceMetricUnitRule implements TestRule {
|
||||
private final Context context;
|
||||
private final boolean metricUnits;
|
||||
|
||||
public PreferenceMetricUnitRule(@NonNull Context context, boolean metricUnits) {
|
||||
this.context = context;
|
||||
this.metricUnits = metricUnits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, final Description description) {
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
|
||||
final boolean previousMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
|
||||
|
||||
try {
|
||||
PreferencesUtils.setMetricUnits(sharedPreferences, context, metricUnits);
|
||||
base.evaluate();
|
||||
} finally {
|
||||
PreferencesUtils.setMetricUnits(sharedPreferences, context, previousMetricUnits);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -193,4 +193,31 @@ public class TrackStatisticsUpdaterTest {
|
||||
@Test
|
||||
public void addTrackPoint_speed_from_GPS_moving_and_sensor_speed() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void copy_constructor() {
|
||||
// given
|
||||
TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
|
||||
|
||||
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
|
||||
TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
|
||||
TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
|
||||
TrackPoint tp4 = new TrackPoint(0.0005, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
|
||||
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
|
||||
|
||||
subject.addTrackPoint(tp1, GPS_DISTANCE);
|
||||
subject.addTrackPoint(tp2, GPS_DISTANCE);
|
||||
subject.addTrackPoint(tp3, GPS_DISTANCE);
|
||||
subject.addTrackPoint(tp4, GPS_DISTANCE);
|
||||
|
||||
// when
|
||||
TrackStatisticsUpdater copy = new TrackStatisticsUpdater(subject);
|
||||
subject.addTrackPoint(tp5, GPS_DISTANCE);
|
||||
copy.addTrackPoint(tp5, GPS_DISTANCE);
|
||||
|
||||
|
||||
// then
|
||||
assertEquals(55.287, subject.getTrackStatistics().getTotalDistance().toM(), 0.01);
|
||||
assertEquals(55.287, copy.getTrackStatistics().getTotalDistance().toM(), 0.01);
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ limitations under the License.
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
|
||||
<application
|
||||
android:name=".Startup"
|
||||
|
||||
@@ -30,8 +30,7 @@ public class Startup extends Application {
|
||||
// Set default values of preferences on first start.
|
||||
SharedPreferences sharedPreferences = PreferencesUtils.resetPreferences(this, false);
|
||||
if (PreferencesUtils.getString(sharedPreferences, this, R.string.stats_units_key, "").equals("")) {
|
||||
String statsUnits = getString(Locale.US.equals(Locale.getDefault()) ? R.string.stats_units_imperial : R.string.stats_units_metric);
|
||||
PreferencesUtils.setString(sharedPreferences, this, R.string.stats_units_key, statsUnits);
|
||||
PreferencesUtils.setMetricUnits(sharedPreferences, this, !Locale.US.equals(Locale.getDefault()));
|
||||
}
|
||||
|
||||
ActivityUtils.applyNightMode(sharedPreferences, this);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package de.dennisguse.opentracks.content.data;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
|
||||
public abstract class Altitude {
|
||||
|
||||
private final double altitude_m;
|
||||
@@ -12,12 +14,18 @@ public abstract class Altitude {
|
||||
return altitude_m;
|
||||
}
|
||||
|
||||
public abstract int getLabelId();
|
||||
|
||||
public static class WGS84 extends Altitude {
|
||||
|
||||
private WGS84(double altitude_m) {
|
||||
super(altitude_m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLabelId() {
|
||||
return R.string.wgs84;
|
||||
}
|
||||
|
||||
public static Altitude of(double altitude_m) {
|
||||
return new WGS84(altitude_m);
|
||||
@@ -30,6 +38,10 @@ public abstract class Altitude {
|
||||
super(altitude_m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLabelId() {
|
||||
return R.string.egm2008;
|
||||
}
|
||||
|
||||
public static Altitude of(double altitude_m) {
|
||||
return new EGM2008(altitude_m);
|
||||
|
||||
@@ -154,7 +154,9 @@ public class IntervalsFragment extends Fragment {
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
viewModel.onPause();
|
||||
if (viewModel != null) {
|
||||
viewModel.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,6 +182,7 @@ public class IntervalsFragment extends Fragment {
|
||||
if (viewModel == null) {
|
||||
return;
|
||||
}
|
||||
viewBinding.intervalRate.setText(isReportSpeed ? getString(R.string.stats_speed) : getString(R.string.stats_pace));
|
||||
LiveData<List<IntervalStatistics.Interval>> liveData = viewModel.getIntervalStats(trackId, metricUnits, selectedInterval);
|
||||
liveData.observe(getActivity(), intervalList -> adapter.swapData(intervalList, metricUnits, isReportSpeed));
|
||||
}
|
||||
|
||||
@@ -276,10 +276,18 @@ public class StatisticsRecordingFragment extends Fragment {
|
||||
|
||||
if (preferenceShowAltitude) {
|
||||
// Current altitude
|
||||
Float altitude = latestTrackPoint != null && latestTrackPoint.hasAltitude() ? (float) latestTrackPoint.getAltitude().toM() : null;
|
||||
Float altitude = null;
|
||||
int labelId = R.string.value_unknown;
|
||||
if (latestTrackPoint != null && latestTrackPoint.hasAltitude()) {
|
||||
altitude = (float) latestTrackPoint.getAltitude().toM();
|
||||
labelId = latestTrackPoint.getAltitude().getLabelId();
|
||||
}
|
||||
|
||||
Pair<String, String> parts = StringUtils.formatAltitude(getContext(), altitude, preferenceMetricUnits);
|
||||
viewBinding.statsAltitudeCurrentValue.setText(parts.first);
|
||||
viewBinding.statsAltitudeCurrentUnit.setText(parts.second);
|
||||
|
||||
viewBinding.statsAltitudeCurrentLabelEgm.setText(labelId);
|
||||
}
|
||||
|
||||
// Set coordinate
|
||||
@@ -313,7 +321,7 @@ public class StatisticsRecordingFragment extends Fragment {
|
||||
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, getString(R.string.stats_rate_key));
|
||||
}
|
||||
|
||||
this.latestTrackPoint = recordingData.getLatestTrackPoint();
|
||||
latestTrackPoint = recordingData.getLatestTrackPoint();
|
||||
if (latestTrackPoint != null && latestTrackPoint.hasLocation() && !latestTrackPoint.isRecent()) {
|
||||
latestTrackPoint = null;
|
||||
}
|
||||
|
||||
@@ -36,12 +36,14 @@ import androidx.core.app.TaskStackBuilder;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.TrackListActivity;
|
||||
import de.dennisguse.opentracks.TrackRecordingActivity;
|
||||
import de.dennisguse.opentracks.content.data.Altitude;
|
||||
import de.dennisguse.opentracks.content.data.Distance;
|
||||
import de.dennisguse.opentracks.content.data.Marker;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
@@ -59,6 +61,7 @@ import de.dennisguse.opentracks.services.tasks.PeriodicTaskExecutor;
|
||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||
import de.dennisguse.opentracks.util.EGM2008Utils;
|
||||
import de.dennisguse.opentracks.util.ExportUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
@@ -128,6 +131,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
private BluetoothRemoteSensorManager remoteSensorManager;
|
||||
private AltitudeSumManager altitudeSumManager;
|
||||
|
||||
private EGM2008Utils.EGM2008Correction egm2008Correction;
|
||||
|
||||
private TrackStatisticsUpdater trackStatisticsUpdater;
|
||||
private TrackPoint lastTrackPoint;
|
||||
private boolean isIdle;
|
||||
@@ -539,6 +544,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
|
||||
fillWithSensorDataSet(trackPoint);
|
||||
|
||||
correctAltitude(trackPoint);
|
||||
|
||||
notificationManager.updateTrackPoint(this, track.getTrackStatistics(), trackPoint, recordingGpsAccuracy);
|
||||
|
||||
//TODO Figure out how to avoid loading the lastValidTrackPoint from the database
|
||||
@@ -602,6 +609,25 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
lastTrackPoint = trackPoint;
|
||||
}
|
||||
|
||||
//TODO Identical to TrackDataHub
|
||||
private void correctAltitude(TrackPoint trackPoint) {
|
||||
if (!trackPoint.hasLocation() || !trackPoint.hasAltitude()) {
|
||||
Log.d(TAG, "No altitude correction necessary.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (egm2008Correction == null || !egm2008Correction.canCorrect(trackPoint.getLocation())) {
|
||||
try {
|
||||
egm2008Correction = EGM2008Utils.createCorrection(this, trackPoint.getLocation());
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not load altitude correction for " + trackPoint, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
trackPoint.setAltitude(Altitude.EGM2008.of(egm2008Correction.correctAltitude(trackPoint.getLocation())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newGpsStatus(GpsStatusValue gpsStatusValue) {
|
||||
notificationManager.updateContent(getString(gpsStatusValue.message));
|
||||
@@ -652,8 +678,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
|
||||
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
|
||||
|
||||
recordingDataObservable.postValue(new RecordingData(track, trackPoint, sensorDataSet));
|
||||
|
||||
contentProviderUtils.updateTrack(track);
|
||||
} catch (SQLiteException e) {
|
||||
/*
|
||||
@@ -761,12 +785,20 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
//TODO This somehow should happen in the HandlerServer as we create a new TrackPoint.
|
||||
TrackStatisticsUpdater tmpTrackStatisticsUpdater = new TrackStatisticsUpdater(trackStatisticsUpdater);
|
||||
TrackPoint tmpLastTrackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT);
|
||||
|
||||
if (lastTrackPoint != null && lastTrackPoint.hasLocation()) {
|
||||
//TODO Should happen in TrackPoint? via constructor
|
||||
tmpLastTrackPoint.setSpeed(lastTrackPoint.getSpeed());
|
||||
tmpLastTrackPoint.setAltitude(lastTrackPoint.getAltitude());
|
||||
tmpLastTrackPoint.setLongitude(lastTrackPoint.getLongitude());
|
||||
tmpLastTrackPoint.setLatitude(lastTrackPoint.getLatitude());
|
||||
}
|
||||
|
||||
SensorDataSet sensorDataSet = fillWithSensorDataSet(tmpLastTrackPoint);
|
||||
|
||||
tmpTrackStatisticsUpdater.addTrackPoint(tmpLastTrackPoint, recordingDistanceInterval);
|
||||
track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics());
|
||||
|
||||
|
||||
recordingDataObservable.postValue(new RecordingData(track, tmpLastTrackPoint, sensorDataSet));
|
||||
}
|
||||
|
||||
|
||||
+1
-11
@@ -25,13 +25,11 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.Distance;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
@@ -47,11 +45,6 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||
*/
|
||||
public class AnnouncementPeriodicTask implements PeriodicTask {
|
||||
|
||||
/**
|
||||
* The rate at which announcements are spoken.
|
||||
*/
|
||||
private static final float TTS_SPEECH_RATE = 0.9f;
|
||||
|
||||
private static final String TAG = AnnouncementPeriodicTask.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
@@ -213,10 +206,7 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
|
||||
*/
|
||||
}
|
||||
tts.setLanguage(locale);
|
||||
|
||||
// Slow down the speed just a bit as it is hard to hear when exercising.
|
||||
tts.setSpeechRate(TTS_SPEECH_RATE);
|
||||
|
||||
tts.setSpeechRate(PreferencesUtils.getVoiceSpeedRate(PreferencesUtils.getSharedPreferences(context), context));
|
||||
tts.setOnUtteranceProgressListener(utteranceListener);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
|
||||
// Used to forward update from ChooseActivityTypeDialogFragment; TODO Could be replaced with LiveData.
|
||||
private ActivityTypePreference.ActivityPreferenceDialog activityPreferenceDialog;
|
||||
|
||||
private Preference voiceAnnouncements;
|
||||
private Preference announcementsFrequency;
|
||||
private Preference announcementsSpeed;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@@ -140,7 +141,7 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
|
||||
ttsInitStatus = status;
|
||||
Log.i(TAG, "TextToSpeech initialized with status " + status);
|
||||
|
||||
if (voiceAnnouncements != null) {
|
||||
if (announcementsFrequency != null && announcementsSpeed != null) {
|
||||
updateVoiceAnnouncements();
|
||||
}
|
||||
});
|
||||
@@ -172,7 +173,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
|
||||
return directory != null ? directory.getName() : getString(R.string.not_set);
|
||||
});
|
||||
|
||||
voiceAnnouncements = findPreference(getString(R.string.voice_frequency_key));
|
||||
announcementsFrequency = findPreference(getString(R.string.voice_frequency_key));
|
||||
announcementsSpeed = findPreference(getString(R.string.voice_speed_rate_key));
|
||||
updateVoiceAnnouncements();
|
||||
}
|
||||
|
||||
@@ -232,7 +234,8 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
|
||||
super.onDestroy();
|
||||
trackRecordingServiceConnection.unbind(getContext());
|
||||
sharedPreferences = null;
|
||||
voiceAnnouncements = null;
|
||||
announcementsFrequency = null;
|
||||
announcementsSpeed = null;
|
||||
tts = null;
|
||||
}
|
||||
|
||||
@@ -323,7 +326,9 @@ public class SettingsActivity extends AbstractActivity implements ChooseActivity
|
||||
}
|
||||
|
||||
private void updateVoiceAnnouncements() {
|
||||
voiceAnnouncements.setEnabled(ttsInitStatus == TextToSpeech.SUCCESS);
|
||||
boolean enabled = ttsInitStatus == TextToSpeech.SUCCESS;
|
||||
announcementsFrequency.setEnabled(enabled);
|
||||
announcementsSpeed.setEnabled(enabled);
|
||||
}
|
||||
|
||||
private void onRecordingStatusChanged(TrackRecordingService.RecordingStatus status) {
|
||||
|
||||
@@ -68,7 +68,7 @@ public class TrackStatisticsUpdater {
|
||||
private final DoubleRingBuffer speedBuffer_mps;
|
||||
|
||||
// The current segment's statistics
|
||||
private final TrackStatistics currentSegment = new TrackStatistics();
|
||||
private final TrackStatistics currentSegment;
|
||||
// Current segment's last trackPoint
|
||||
private TrackPoint lastTrackPoint;
|
||||
// Current segment's last moving trackPoint
|
||||
@@ -85,6 +85,8 @@ public class TrackStatisticsUpdater {
|
||||
*/
|
||||
public TrackStatisticsUpdater(TrackStatistics trackStatistics) {
|
||||
this.trackStatistics = trackStatistics;
|
||||
this.currentSegment = new TrackStatistics();
|
||||
|
||||
trackInitialized = true;
|
||||
|
||||
altitudeBuffer_m = new DoubleRingBuffer(ALTITUDE_SMOOTHING_FACTOR);
|
||||
@@ -92,6 +94,9 @@ public class TrackStatisticsUpdater {
|
||||
}
|
||||
|
||||
public TrackStatisticsUpdater(TrackStatisticsUpdater toCopy) {
|
||||
this.currentSegment = new TrackStatistics(toCopy.currentSegment);
|
||||
this.trackStatistics = new TrackStatistics(toCopy.trackStatistics);
|
||||
|
||||
this.trackInitialized = toCopy.trackInitialized;
|
||||
this.segmentInitialized = toCopy.segmentInitialized;
|
||||
this.altitudeBuffer_m = new DoubleRingBuffer(toCopy.altitudeBuffer_m);
|
||||
@@ -99,9 +104,6 @@ public class TrackStatisticsUpdater {
|
||||
|
||||
this.lastTrackPoint = toCopy.lastTrackPoint;
|
||||
this.lastMovingTrackPoint = toCopy.lastMovingTrackPoint;
|
||||
|
||||
this.trackStatistics = toCopy.getTrackStatistics();
|
||||
this.currentSegment.merge(toCopy.currentSegment);
|
||||
}
|
||||
|
||||
public TrackStatistics getTrackStatistics() {
|
||||
|
||||
@@ -96,6 +96,22 @@ public class PreferencesUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static float getFloat(SharedPreferences sharedPreferences, Context context, int keyId, float defaultValue) {
|
||||
try {
|
||||
return sharedPreferences.getFloat(getKey(context, keyId), defaultValue);
|
||||
} catch (ClassCastException e) {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
//NOTE: We assume that the data was stored as String due to use of ListPreference.
|
||||
try {
|
||||
String stringValue = sharedPreferences.getString(getKey(context, keyId), null);
|
||||
return Float.parseFloat(stringValue);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(SharedPreferences sharedPreferences, Context context, int keyId, String defaultValue) {
|
||||
return sharedPreferences.getString(getKey(context, keyId), defaultValue);
|
||||
}
|
||||
@@ -112,6 +128,16 @@ public class PreferencesUtils {
|
||||
return STATS_UNIT.equals(getString(sharedPreferences, context, R.string.stats_units_key, STATS_UNIT));
|
||||
}
|
||||
|
||||
public static void setMetricUnits(SharedPreferences sharedPreferences, Context context, boolean metricUnits) {
|
||||
String unit;
|
||||
if (metricUnits) {
|
||||
unit = context.getString(R.string.stats_units_metric);
|
||||
} else {
|
||||
unit = context.getString(R.string.stats_units_imperial);
|
||||
}
|
||||
setString(sharedPreferences, context, R.string.stats_units_key, unit);
|
||||
}
|
||||
|
||||
public static boolean isReportSpeed(SharedPreferences sharedPreferences, Context context, String category) {
|
||||
final String STATS_RATE_DEFAULT = context.getString(R.string.stats_rate_default);
|
||||
String currentStatsRate = getString(sharedPreferences, context, R.string.stats_rate_key, STATS_RATE_DEFAULT);
|
||||
@@ -181,6 +207,11 @@ public class PreferencesUtils {
|
||||
return getInt(sharedPreferences, context, R.string.voice_frequency_key, VOICE_FREQUENCY_DEFAULT);
|
||||
}
|
||||
|
||||
public static float getVoiceSpeedRate(SharedPreferences sharedPreferences, Context context) {
|
||||
final float DEFAULT = Float.parseFloat(context.getResources().getString(R.string.voice_frequency_default));
|
||||
return getFloat(sharedPreferences, context, R.string.voice_speed_rate_key, DEFAULT);
|
||||
}
|
||||
|
||||
public static Distance getRecordingDistanceInterval(SharedPreferences sharedPreferences, Context context) {
|
||||
return Distance.of(getInt(sharedPreferences, context, R.string.recording_distance_interval_key, getRecordingDistanceIntervalDefaultInternal(context)));
|
||||
}
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="@color/ic_launcher_background" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_logo_color_24dp"
|
||||
android:inset="8dp" />
|
||||
</item>
|
||||
</layer-list>
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:drawable="@drawable/ic_logo_color_24dp" />
|
||||
@@ -269,7 +269,7 @@
|
||||
android:id="@+id/stats_altitude_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="stats_altitude_horizontal_line,stats_altitude_current_label,stats_altitude_current_value,stats_altitude_current_unit,stats_altitude_gain_label,stats_altitude_gain_value,stats_altitude_gain_unit,stats_altitude_loss_label,stats_altitude_loss_value,stats_altitude_loss_unit,stats_elevation_current_label_egm" />
|
||||
app:constraint_referenced_ids="stats_altitude_horizontal_line,stats_altitude_current_label,stats_altitude_current_value,stats_altitude_current_unit,stats_altitude_gain_label,stats_altitude_gain_value,stats_altitude_gain_unit,stats_altitude_loss_label,stats_altitude_loss_value,stats_altitude_loss_unit,@+id/stats_altitude_current_label_egm" />
|
||||
|
||||
<!-- altitude -->
|
||||
<TextView
|
||||
@@ -282,7 +282,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/stats_altitude_horizontal_line" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stats_elevation_current_label_egm"
|
||||
android:id="@+id/stats_altitude_current_label_egm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
|
||||
@@ -360,7 +360,7 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="share_track_subject">Ich möchte einen Track mit dir teilen</string>
|
||||
<!-- Stats -->
|
||||
<string name="stats_average_moving_pace">Durchschnitt\n(Bewegung)</string>
|
||||
<string name="stats_average_moving_speed">Durchschnittsgeshwindigkeit
|
||||
<string name="stats_average_moving_speed">Durchschnittsgeschwindigkeit
|
||||
\n(Bewegung)</string>
|
||||
<string name="stats_average_pace">Durchschnitt</string>
|
||||
<string name="stats_average_speed">Durchschnitt</string>
|
||||
@@ -596,4 +596,4 @@ g) das tun, was Deiner Meinung nach OpenTracks hilft.</string>
|
||||
<string name="track_distance_notification">Strecke: %1$s</string>
|
||||
<string name="track_speed_notification">Geschwindigkeit: %1$s</string>
|
||||
<string name="track_pace_notification">Tempo: %1$s</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
||||
@@ -32,11 +32,11 @@ limitations under the License.
|
||||
<string name="help_track_map_title">Comment faire apparaître une trace sur une carte ?</string>
|
||||
<string name="help_track_map_content"> Utilisez la petite icône de carte.
|
||||
\n a) (mises à jour en direct) Installez <a href="https://github.com/OpenTracksApp/OSMDashboard">OSMDashboard</a>. Il fournit des cartes en ligne ou hors ligne via <a href="https://www.openstreetmap.org ">OpenStreetMap</a>.
|
||||
\n En fait, OSMDashboard est une application séparée qui ne peut accéder (temporairement) qu aux données des piste(s) qui vont être affichées.
|
||||
\n En fait, OSMDashboard est une application séparée qui ne peut accéder (temporairement) qu aux données des trace(s) qui vont être affichées.
|
||||
\n b) Via une application cartographique normale (par exemple) , <a href="http://osmand.net/">OsmAnd</a> et <a href="https://maps.me/">MAPS.ME</a> Ces applications doivent prendre en charge le format de fichier KMZ (uniquement les lieux et les horodatages). En fait, une application doit prendre en charge <i>ACTION_VIEW</i> avec MIME <i>application/vnd.google-earth.kmz</i>. </string>
|
||||
<string name="help_storage_pictures_title">Comment OpenTracks stocke-t-il les photos qui ont été prises comme marqueurs ?</string>
|
||||
<string name="help_storage_pictures_content">Elles sont stockées dans le stockage interne de lapplication (c est-à-dire uniquement accessible dans OpenTracks).</string>
|
||||
<string name="help_track_export_title">Comment puis-je exporter/partager des pistes enregistrées ?</string>
|
||||
<string name="help_track_export_title">Comment puis-je exporter/partager des traces enregistrées \?</string>
|
||||
<string name="help_track_export_content"> Les traces peuvent être exportées à partir des paramètres en tant que KMZ, KML ou GPX. KMZ/KML toutes les données ; GPX seulement les emplacements. Les traces partagées via l\'icône <i>partager</i> sont partagées au format KMZ. </string>
|
||||
<string name="help_data_google_play_services_title">OpenTracks nécessite-t-il/utilise-t-il le service Google Play ?</string>
|
||||
<string name="help_recording_title">Comment OpenTracks enregistre-t-il les données ?</string>
|
||||
@@ -136,7 +136,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="description_average_moving_speed">Vitesse moyenne de déplacement : %1$.2f km/h (%2$.1f mi/h)</string>
|
||||
<string name="description_average_pace_in_minute">Vitesse moyenne : %1$s min/km (%2$s min/mi)</string>
|
||||
<string name="description_average_speed">Vitesse moyenne : %1$.2f km/h (%2$.1f mi/h)</string>
|
||||
<string name="description_altitude_gain">Dénivelé : %1$d m (%2$d pi)</string>
|
||||
<string name="description_altitude_gain">Dénivelé positif : %1$d m (%2$d pi)</string>
|
||||
<string name="description_altitude_imperial">Altitude (pi)</string>
|
||||
<string name="description_altitude_metric">Altitude (m)</string>
|
||||
<string name="description_fastest_pace_in_minute">Vitesse maximale : %1$s min/km (%2$s min/mi)</string>
|
||||
@@ -276,7 +276,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="menu_stop_gps">Arrêter le GPS</string>
|
||||
<string name="menu_view_photo">Afficher la photo</string>
|
||||
<string name="menu_voice_frequency">Fréquence vocale</string>
|
||||
<string name="menu_resume_track">Reprendre la piste</string>
|
||||
<string name="menu_resume_track">Reprendre la trace</string>
|
||||
<!-- OpenTracks -->
|
||||
<string name="recording_service">Service enregistrement</string>
|
||||
<!-- Permission -->
|
||||
@@ -284,7 +284,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<!-- Search -->
|
||||
<string name="search_global_description">Parcours et repères</string>
|
||||
<string name="search_list_empty_message">Aucun parcours ni repère ne correspond à votre recherche</string>
|
||||
<string name="search_list_marker_track_location">Dans la piste « %1$s ».</string>
|
||||
<string name="search_list_marker_track_location">Dans la trace « %1$s ».</string>
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_state_battery">Niveau de la batterie</string>
|
||||
<string name="sensor_state_cadence">Cadences</string>
|
||||
@@ -358,7 +358,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="stats_average_speed">Vitesse moyenne</string>
|
||||
<string name="stats_altitude">Altitude</string>
|
||||
<string name="stats_fastest_pace">Allure la plus rapide</string>
|
||||
<string name="stats_gain">Gagner</string>
|
||||
<string name="stats_gain">Dénivelé positif</string>
|
||||
<string name="stats_grade">Inclinaison</string>
|
||||
<string name="stats_latitude">Latitude</string>
|
||||
<string name="stats_longitude">Longitude</string>
|
||||
@@ -384,7 +384,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="track_detail_chart_tab">Graphique</string>
|
||||
<string name="track_detail_stats_tab">Statistiques</string>
|
||||
<string name="track_detail_record_success">Enregistrement d\'un nouveau parcours en cours</string>
|
||||
<string name="track_detail_resume_success">Reprenons maintenant la piste</string>
|
||||
<string name="track_detail_resume_success">Reprenons maintenant la trace</string>
|
||||
<!-- Track Edit -->
|
||||
<string name="track_edit_activity_type">Type d\'activité (exemple : randonnée)</string>
|
||||
<string name="track_edit_activity_type_hint">Type d\'activité</string>
|
||||
@@ -536,23 +536,23 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="track_speed_notification">Vitesse : %1$s</string>
|
||||
<string name="track_detail_intervals_tab">Intervalles</string>
|
||||
<string name="interval_list_empty_message">Il n\'y a pas encore d\'intervalle</string>
|
||||
<string name="aggregated_stats_empty_message">Enregistrez votre première piste pour voir les statistiques agrégées</string>
|
||||
<string name="aggregated_stats_empty_message">Enregistrez votre première trace pour voir les statistiques agrégées</string>
|
||||
<string name="voice_pace_lap">Temps au tour de %1$s</string>
|
||||
<string name="voice_speed_lap">Vitesse du tour de %1$s</string>
|
||||
<string name="toast_message_instant_track_was_exported">Dernière piste exportée</string>
|
||||
<string name="settings_default_export_uri_title">Répertoire d\'exportation des pistes</string>
|
||||
<string name="toast_message_instant_track_was_exported">Dernière trace exportée</string>
|
||||
<string name="settings_default_export_uri_title">Répertoire d\'exportation des traces</string>
|
||||
<string name="instant_export_enabled_title">Exportation instantanée après l\'entraînement</string>
|
||||
<string name="stats_intervals">Intervalles</string>
|
||||
<string name="stats_loss">Perte</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Empêcher la réimportation de pistes</string>
|
||||
<string name="stats_loss">Dénivelé négatif</string>
|
||||
<string name="settings_prevent_reimport_tracks_title">Empêcher la réimportation de traces</string>
|
||||
<string name="settings_night_mode_option_night">Nuit</string>
|
||||
<string name="settings_night_mode_option_day">Jour</string>
|
||||
<string name="settings_night_mode_option_system">Système</string>
|
||||
<string name="stats_split_interval">Intervalle partagé</string>
|
||||
<string name="instant_export_enabled_summary">Exportation de la piste vers le stockage après la fin de l\'enregistrement</string>
|
||||
<string name="instant_export_enabled_summary">Exportation de la trace vers le stockage après la fin de l\'enregistrement</string>
|
||||
<string name="hold_to_pause">Tenir pour faire une pause</string>
|
||||
<string name="hold_to_stop">Maintenir pour arrêter</string>
|
||||
<string name="track_distance_notification">Distanciation : %1$s</string>
|
||||
<string name="track_distance_notification">Distance : %1$s</string>
|
||||
<string name="open_track_as_KMZ">Ouvert comme KMZ</string>
|
||||
<string name="open_track_as_GPX">Ouvert en tant que GPX</string>
|
||||
<string name="open_track_as_trackfileformat">Ouvrir comme %1$s</string>
|
||||
@@ -561,7 +561,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="settings_sensor_wheel_circumference">Circonférence de roue (millimètre)</string>
|
||||
<string name="export_error_post_workout">L\'exportation du post-travail a échoué, veuillez vérifier le répertoire d\'exportation.</string>
|
||||
<string name="export_all_do_it_for_all">le faire pour tous les conflits</string>
|
||||
<string name="export_track_errors">Pistes non exportées</string>
|
||||
<string name="export_track_errors">Traces non exportées</string>
|
||||
<string name="import_unable_to_import_file">Impossible d\'importer le fichier : %1$s</string>
|
||||
<string name="import_no_kml_file_found">Pas de doc.fichier kml trouvé dans KMZ</string>
|
||||
<string name="import_error_info">%1$s : %2$s</string>
|
||||
@@ -576,8 +576,8 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="sensor_state_heart_rate_avg">Rythme cardiaque moyen</string>
|
||||
<string name="sensor_state_cadence_avg">Cadence moyenne</string>
|
||||
<string name="generic_click_twice_cancel">Cliquez sur retour pour annuler</string>
|
||||
<string name="export_progress_summary_new_msg">Nouvelles pistes exportées</string>
|
||||
<string name="export_progress_summary_skip_msg">Pistes sautées</string>
|
||||
<string name="export_progress_summary_new_msg">Nouvelles traces exportées</string>
|
||||
<string name="export_progress_summary_skip_msg">Traces ignorées</string>
|
||||
<string name="export_progress_summary_errors_msg">Erreurs</string>
|
||||
<string name="generic_overwrite">Écraser</string>
|
||||
<string name="generic_show_errors">Afficher les erreurs</string>
|
||||
@@ -590,7 +590,7 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<string name="import_unsupported_format">Format de fichier non pris en charge</string>
|
||||
<string name="import_parser_error">Erreur de l\'analyseur : %1$s</string>
|
||||
<string name="import_file_imported">Fichier %1$s importé</string>
|
||||
<string name="import_prevent_reimport">Vous avez défini empêcher la réimportation de la piste</string>
|
||||
<string name="import_prevent_reimport">Vous avez défini empêcher la réimportation de la trace</string>
|
||||
<string name="import_progress_summary_ok_msg">Les fichiers importés</string>
|
||||
<string name="import_progress_summary_exists_msg">Il existe déjà</string>
|
||||
<string name="import_progress_summary_errors_msg">Erreur</string>
|
||||
@@ -599,9 +599,9 @@ Si le dispositif GPS signale des données inexactes (par exemple, la localisatio
|
||||
<item quantity="other">Terminé avec des erreurs %1$d</item>
|
||||
</plurals>
|
||||
<string name="settings_default_trackfileformat">Format de fichier d\'exportation / partage</string>
|
||||
<string name="description_altitude_loss">Perte d\'altitude : %1$d m (%2$d ft)</string>
|
||||
<string name="export_track_already_exists_msg">La piste %1$s existe déjà dans le répertoire de destination.</string>
|
||||
<string name="export_progress_summary_overwrite_msg">Pistes écrasées</string>
|
||||
<string name="description_altitude_loss">Dénivelé négatif : %1$d m (%2$d ft)</string>
|
||||
<string name="export_track_already_exists_msg">La trace %1$s existe déjà dans le répertoire de destination.</string>
|
||||
<string name="export_progress_summary_overwrite_msg">Traces écrasées</string>
|
||||
<string name="about_third_party_data">Données de tiers</string>
|
||||
<string name="track_delete_progress">%1$d/%2$d</string>
|
||||
<string name="delete_service">Service de suppression</string>
|
||||
|
||||
@@ -34,7 +34,7 @@ limitations under the License.
|
||||
<string name="help_track_map_title">¿Como mostrar a ruta nun mapa?</string>
|
||||
<string name="help_track_map_content"> Usa a icona do mapa pequeno.
|
||||
\n a) (actualizacións en directo) Instala <a href="https://github.com/OpenTracksApp/OSMDashboard"> OSMDashboard </a>. Ofrece mapas en liña ou fóra de liña a través de <a href="https://www.openstreetmap.org"> OpenStreetMap </a>.
|
||||
\n \u0020En realidade, OSMDashboard é unha aplicación independente que só pode acceder (temporalmente) aos datos das pistas que se amosarán.
|
||||
\n En realidade, OSMDashboard é unha aplicación independente que só pode acceder (temporalmente) aos datos das pistas que se amosarán.
|
||||
\n b) A través dunha aplicación de mapa normal (por exemplo, <a href="http://osmand.net/">OsmAnd</a> e <a href="https://maps.me/">MAPS.ME</a>). Estas aplicacións precisan admitir o formato de ficheiro KMZ (só localizacións e marcas de tempo). De feito, unha aplicación ten que admitir <i> ACTION_VIEW </i> con MIME <i>application/vnd.google-earth.kmz</i>. </string>
|
||||
<string name="help_storage_pictures_title">¿De que xeito garda OpenTracks as fotos tomadas como marcadores?</string>
|
||||
<string name="help_storage_pictures_content">Gárdanse no almacenaxe interno da app (só accesible desde OpenTracks).</string>
|
||||
@@ -236,7 +236,7 @@ Se te detés ou estás en interiores, non se gardarán datos do sensor (mais ser
|
||||
<string name="image_stop">Deter</string>
|
||||
<string name="image_track">Traxecto</string>
|
||||
<!-- Import -->
|
||||
<string name="import_error">Importados: %1$d de %2$s de %3$s</string>
|
||||
<string name="import_error">Importados: %1$d de %2$s desde %3$s</string>
|
||||
<string name="import_no_directory">%1$s non existe</string>
|
||||
<string name="import_no_file">Non hai ficheiros para importar. Conecta o teu dispositivo ao ordenador e coloca os ficheiros para importar en %1$s.</string>
|
||||
<string name="import_no_file_title">Importar ficheiros</string>
|
||||
@@ -422,7 +422,7 @@ Se te detés ou estás en interiores, non se gardarán datos do sensor (mais ser
|
||||
<string name="unit_kilometer_per_hour">km/h</string>
|
||||
<string name="unit_meter">m</string>
|
||||
<string name="unit_mile">km</string>
|
||||
<string name="unit_mile_per_hour">km/h</string>
|
||||
<string name="unit_mile_per_hour">mph</string>
|
||||
<string name="unit_minute_per_kilometer">min/km</string>
|
||||
<string name="unit_minute_per_mile">min/km</string>
|
||||
<!-- Value -->
|
||||
|
||||
@@ -151,8 +151,8 @@
|
||||
<string name="image_track">Lacak</string>
|
||||
<string name="import_error">Mengimpor %1$d dari %2$s dari %3$s</string>
|
||||
<string name="import_no_directory">%1$s tidak ada.</string>
|
||||
<string name="import_no_file">Tidak ada file untuk diimpor. Hubungkan perangkat ke komputer Anda dan tempatkan file yang akan diimpor di %1$s.</string>
|
||||
<string name="import_no_file_title">Impor file</string>
|
||||
<string name="import_no_file">Tidak ada berkas untuk diimpor. Hubungkan perangkat ke komputer Anda dan tempatkan file yang akan diimpor di %1$s.</string>
|
||||
<string name="import_no_file_title">Impor berkas</string>
|
||||
<string name="import_progress_message">Mengimpor dari %1$s…</string>
|
||||
<string name="import_selection_option">Semua %1$s</string>
|
||||
<string name="import_selection_title">Impor dari penyimpanan external</string>
|
||||
@@ -160,10 +160,10 @@
|
||||
<string name="marker_add_error">Tidak dapat memasukkan penanda. Tidak ada sinyal GPS. Coba lagi.</string>
|
||||
<string name="marker_add_success">Penanda disisipkan.</string>
|
||||
<string name="marker_add_canceled">Batal, penanda tidak ditambahkan</string>
|
||||
<string name="marker_delete_all_confirm_message">Semua penanda untuk lintasan ini akan dihapus permanen dari perangkat</string>
|
||||
<string name="marker_delete_one_confirm_message">Penanda akan dihapus permanen dari perangkat</string>
|
||||
<string name="marker_delete_all_confirm_message">Semua penanda untuk lintasan ini akan dihapus secara permanen dari perangkat</string>
|
||||
<string name="marker_delete_one_confirm_message">Penanda akan dihapus secara permanen dari perangkat</string>
|
||||
<string name="marker_delete_one_confirm_title">Hapus penanda?</string>
|
||||
<string name="marker_delete_multiple_confirm_message">Penanda yang dipilih akan dihapus permanen dari perangkat</string>
|
||||
<string name="marker_delete_multiple_confirm_message">Penanda yang dipilih akan dihapus secara permanen dari perangkat</string>
|
||||
<string name="marker_label_end">%1$s (Akhir)</string>
|
||||
<string name="marker_label_start">%1$s (Awal)</string>
|
||||
<string name="marker_name_format">Penanda %1$d</string>
|
||||
@@ -229,7 +229,7 @@
|
||||
<string name="settings_recording_track_name_number_option">Angka</string>
|
||||
<string name="settings_recording_track_name_title">Nama trek default</string>
|
||||
<string name="settings_reset">Setel ulang</string>
|
||||
<string name="settings_reset_confirm_message">Semua setelan akan diubah ke nilai default.</string>
|
||||
<string name="settings_reset_confirm_message">Semua setelan akan diubah ke nilai default. Tiada lintasan yang akan dihapus dari perangkat.</string>
|
||||
<string name="settings_reset_confirm_title">Setel ulang sekarang?</string>
|
||||
<string name="settings_reset_done">Semua setelan telah dikembalikan ke nilai default</string>
|
||||
<string name="settings_sensor">Sensor</string>
|
||||
@@ -406,4 +406,18 @@
|
||||
<string name="waypoint_type_waterfall">air terjun</string>
|
||||
<string name="waypoint_type_water_fountain">air mancur</string>
|
||||
<string name="waypoint_type_waypoint">titik jalan</string>
|
||||
</resources>
|
||||
<string name="settings_night_mode_option_night">Malam</string>
|
||||
<string name="open_track_as_KMZ">Buka sebagai KMZ</string>
|
||||
<string name="import_error_list_dialog_title">Berkas tidak diimpor</string>
|
||||
<string name="import_file_imported">Berkas %1$s telah diimpor</string>
|
||||
<string name="settings_night_mode_option_day">Siang</string>
|
||||
<string name="help_support_title">Bagaimana mendukung OpenTracks\?</string>
|
||||
<string name="import_progress_summary_errors_msg">Kesalahan</string>
|
||||
<string name="open_track_as_GPX">Buka sebagai GPX</string>
|
||||
<string name="settings_error_initial_values_restored">Maaf, kesalahan terjadi. Semua setelan telah dikembalikan ke nilai default</string>
|
||||
<string name="track_speed_notification">Kecepatan: %1$s</string>
|
||||
<string name="import_unable_to_import_file">Tidak bisa mengimpor berkas: %1$s</string>
|
||||
<string name="open_track_as_trackfileformat">Buka sebagai %1$s</string>
|
||||
<string name="track_distance_notification">Jarak: %1$s</string>
|
||||
<string name="settings_recording_show_on_lockscreen_while_recording_summary">Selama perekaman,</string>
|
||||
</resources>
|
||||
@@ -335,7 +335,7 @@ limitations under the License.
|
||||
<string name="unit_kilometer_per_hour">km/t</string>
|
||||
<string name="unit_meter">m</string>
|
||||
<string name="unit_mile">mi</string>
|
||||
<string name="unit_mile_per_hour">mi/h</string>
|
||||
<string name="unit_mile_per_hour">mph</string>
|
||||
<string name="unit_minute_per_kilometer">min/km</string>
|
||||
<string name="unit_minute_per_mile">min/mi</string>
|
||||
<!-- Value -->
|
||||
@@ -393,7 +393,7 @@ limitations under the License.
|
||||
<string name="voice_speed_miles_per_hour_other">%1$.1f engelske mil i timen</string>
|
||||
<string name="voice_speed_miles_per_hour_two">2 engelske mil i timen</string>
|
||||
<string name="voice_speed_miles_per_hour_zero">0 engelske mil i timen</string>
|
||||
<string name="voice_template">Spor %1$s om %2$s ved %3$s</string>
|
||||
<string name="voice_template">OpenTracks %1$s på %2$s med %3$s</string>
|
||||
<string name="voice_total_distance_kilometers_few">total distanse %1$.2f kilometer</string>
|
||||
<string name="voice_total_distance_kilometers_many">total distanse %1$.2f kilometer</string>
|
||||
<string name="voice_total_distance_kilometers_one">total distanse 1 kilometer</string>
|
||||
|
||||
@@ -18,6 +18,7 @@ limitations under the License.
|
||||
<string name="app_name" translatable="false">OpenTracks</string>
|
||||
|
||||
<string name="egm2008" translatable="false">EGM2008</string>
|
||||
<string name="wgs84" translatable="false">WGS84</string>
|
||||
|
||||
<string name="third_party_data" translatable="false">
|
||||
<a href="https://earth-info.nga.mil/">National Geospatial-Intelligence Agency (NGA)\'s EGM2008 model</a> 5\' minute resolution.
|
||||
|
||||
@@ -238,6 +238,17 @@
|
||||
<item>-50</item>
|
||||
<item>-100</item>
|
||||
</string-array>
|
||||
<string name="voice_speed_rate_key" translatable="false">voiceSpeedRate</string>
|
||||
<string name="voice_speed_rate_default" translatable="false">0.9</string>
|
||||
<string-array name="voice_speed_rate_values">
|
||||
<item>0.7</item>
|
||||
<item>0.8</item>
|
||||
<item>@string/voice_speed_rate_default</item>
|
||||
<item>1.0</item>
|
||||
<item>1.1</item>
|
||||
<item>1.2</item>
|
||||
<item>1.3</item>
|
||||
</string-array>
|
||||
|
||||
<string name="export_trackfileformat_key" translatable="false">exportTrackFileFormat</string>
|
||||
<!-- See TrackFileFormat -->
|
||||
|
||||
@@ -349,6 +349,7 @@ limitations under the License.
|
||||
<string name="menu_stop_gps">Stop GPS</string>
|
||||
<string name="menu_view_photo">View photo</string>
|
||||
<string name="menu_voice_frequency">Voice frequency</string>
|
||||
<string name="menu_voice_rate">Voice speed</string>
|
||||
<string name="menu_resume_track">Resume track</string>
|
||||
<!-- OpenTracks -->
|
||||
<string name="recording_service">Recording service</string>
|
||||
|
||||
@@ -85,6 +85,13 @@ limitations under the License.
|
||||
android:key="@string/voice_frequency_key"
|
||||
android:title="@string/menu_voice_frequency"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
<ListPreference
|
||||
android:defaultValue="@string/voice_speed_rate_default"
|
||||
android:entryValues="@array/voice_speed_rate_values"
|
||||
android:entries="@array/voice_speed_rate_values"
|
||||
android:key="@string/voice_speed_rate_key"
|
||||
android:title="@string/menu_voice_rate"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
<de.dennisguse.opentracks.settings.ActivityTypePreference
|
||||
android:defaultValue="@string/default_activity_default"
|
||||
android:key="@string/default_activity_key"
|
||||
|
||||
Reference in New Issue
Block a user